Skip to content

Commit 9e05a25

Browse files
onikoaxboe
authored andcommitted
sed-opal: geometry feature reporting command
Locking range start and locking range length attributes may be require to satisfy restrictions exposed by OPAL2 geometry feature reporting. Geometry reporting feature is described in TCG OPAL SSC, section 3.1.1.4 (ALIGN, LogicalBlockSize, AlignmentGranularity and LowestAlignedLBA). 4.3.5.2.1.1 RangeStart Behavior: [ StartAlignment = (RangeStart modulo AlignmentGranularity) - LowestAlignedLBA ] When processing a Set method or CreateRow method on the Locking table for a non-Global Range row, if: a) the AlignmentRequired (ALIGN above) column in the LockingInfo table is TRUE; b) RangeStart is non-zero; and c) StartAlignment is non-zero, then the method SHALL fail and return an error status code INVALID_PARAMETER. 4.3.5.2.1.2 RangeLength Behavior: If RangeStart is zero, then [ LengthAlignment = (RangeLength modulo AlignmentGranularity) - LowestAlignedLBA ] If RangeStart is non-zero, then [ LengthAlignment = (RangeLength modulo AlignmentGranularity) ] When processing a Set method or CreateRow method on the Locking table for a non-Global Range row, if: a) the AlignmentRequired (ALIGN above) column in the LockingInfo table is TRUE; b) RangeLength is non-zero; and c) LengthAlignment is non-zero, then the method SHALL fail and return an error status code INVALID_PARAMETER In userspace we stuck to logical block size reported by general block device (via sysfs or ioctl), but we can not read 'AlignmentGranularity' or 'LowestAlignedLBA' anywhere else and we need to get those values from sed-opal interface otherwise we will not be able to report or avoid locking range setup INVALID_PARAMETER errors above. Signed-off-by: Ondrej Kozina <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Christian Brauner <[email protected]> Tested-by: Milan Broz <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 63f8793 commit 9e05a25

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

block/sed-opal.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,10 @@ struct opal_dev {
8383
u16 comid;
8484
u32 hsn;
8585
u32 tsn;
86-
u64 align;
86+
u64 align; /* alignment granularity */
8787
u64 lowest_lba;
88+
u32 logical_block_size;
89+
u8 align_required; /* ALIGN: 0 or 1 */
8890

8991
size_t pos;
9092
u8 *cmd;
@@ -409,6 +411,8 @@ static void check_geometry(struct opal_dev *dev, const void *data)
409411

410412
dev->align = be64_to_cpu(geo->alignment_granularity);
411413
dev->lowest_lba = be64_to_cpu(geo->lowest_aligned_lba);
414+
dev->logical_block_size = be32_to_cpu(geo->logical_block_size);
415+
dev->align_required = geo->reserved01 & 1;
412416
}
413417

414418
static int execute_step(struct opal_dev *dev,
@@ -2956,6 +2960,26 @@ static int opal_get_status(struct opal_dev *dev, void __user *data)
29562960
return 0;
29572961
}
29582962

2963+
static int opal_get_geometry(struct opal_dev *dev, void __user *data)
2964+
{
2965+
struct opal_geometry geo = {0};
2966+
2967+
if (check_opal_support(dev))
2968+
return -EINVAL;
2969+
2970+
geo.align = dev->align_required;
2971+
geo.logical_block_size = dev->logical_block_size;
2972+
geo.alignment_granularity = dev->align;
2973+
geo.lowest_aligned_lba = dev->lowest_lba;
2974+
2975+
if (copy_to_user(data, &geo, sizeof(geo))) {
2976+
pr_debug("Error copying geometry data to userspace\n");
2977+
return -EFAULT;
2978+
}
2979+
2980+
return 0;
2981+
}
2982+
29592983
int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
29602984
{
29612985
void *p;
@@ -3029,6 +3053,9 @@ int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
30293053
case IOC_OPAL_GET_LR_STATUS:
30303054
ret = opal_locking_range_status(dev, p, arg);
30313055
break;
3056+
case IOC_OPAL_GET_GEOMETRY:
3057+
ret = opal_get_geometry(dev, arg);
3058+
break;
30323059
default:
30333060
break;
30343061
}

include/linux/sed-opal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ static inline bool is_sed_ioctl(unsigned int cmd)
4646
case IOC_OPAL_GENERIC_TABLE_RW:
4747
case IOC_OPAL_GET_STATUS:
4848
case IOC_OPAL_GET_LR_STATUS:
49+
case IOC_OPAL_GET_GEOMETRY:
4950
return true;
5051
}
5152
return false;

include/uapi/linux/sed-opal.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,18 @@ struct opal_status {
161161
__u32 reserved;
162162
};
163163

164+
/*
165+
* Geometry Reporting per TCG Storage OPAL SSC
166+
* section 3.1.1.4
167+
*/
168+
struct opal_geometry {
169+
__u8 align;
170+
__u32 logical_block_size;
171+
__u64 alignment_granularity;
172+
__u64 lowest_aligned_lba;
173+
__u8 __align[3];
174+
};
175+
164176
#define IOC_OPAL_SAVE _IOW('p', 220, struct opal_lock_unlock)
165177
#define IOC_OPAL_LOCK_UNLOCK _IOW('p', 221, struct opal_lock_unlock)
166178
#define IOC_OPAL_TAKE_OWNERSHIP _IOW('p', 222, struct opal_key)
@@ -179,5 +191,6 @@ struct opal_status {
179191
#define IOC_OPAL_GENERIC_TABLE_RW _IOW('p', 235, struct opal_read_write_table)
180192
#define IOC_OPAL_GET_STATUS _IOR('p', 236, struct opal_status)
181193
#define IOC_OPAL_GET_LR_STATUS _IOW('p', 237, struct opal_lr_status)
194+
#define IOC_OPAL_GET_GEOMETRY _IOR('p', 238, struct opal_geometry)
182195

183196
#endif /* _UAPI_SED_OPAL_H */

0 commit comments

Comments
 (0)