Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <okozina@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Christian Brauner <brauner@kernel.org>
Tested-by: Milan Broz <gmazyland@gmail.com>
Link: https://lore.kernel.org/r/20230411090931.9193-2-okozina@redhat.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Ondrej Kozina and committed by
Jens Axboe
9e05a259 63f8793e

+42 -1
+28 -1
block/sed-opal.c
··· 83 83 u16 comid; 84 84 u32 hsn; 85 85 u32 tsn; 86 - u64 align; 86 + u64 align; /* alignment granularity */ 87 87 u64 lowest_lba; 88 + u32 logical_block_size; 89 + u8 align_required; /* ALIGN: 0 or 1 */ 88 90 89 91 size_t pos; 90 92 u8 *cmd; ··· 411 409 412 410 dev->align = be64_to_cpu(geo->alignment_granularity); 413 411 dev->lowest_lba = be64_to_cpu(geo->lowest_aligned_lba); 412 + dev->logical_block_size = be32_to_cpu(geo->logical_block_size); 413 + dev->align_required = geo->reserved01 & 1; 414 414 } 415 415 416 416 static int execute_step(struct opal_dev *dev, ··· 2960 2956 return 0; 2961 2957 } 2962 2958 2959 + static int opal_get_geometry(struct opal_dev *dev, void __user *data) 2960 + { 2961 + struct opal_geometry geo = {0}; 2962 + 2963 + if (check_opal_support(dev)) 2964 + return -EINVAL; 2965 + 2966 + geo.align = dev->align_required; 2967 + geo.logical_block_size = dev->logical_block_size; 2968 + geo.alignment_granularity = dev->align; 2969 + geo.lowest_aligned_lba = dev->lowest_lba; 2970 + 2971 + if (copy_to_user(data, &geo, sizeof(geo))) { 2972 + pr_debug("Error copying geometry data to userspace\n"); 2973 + return -EFAULT; 2974 + } 2975 + 2976 + return 0; 2977 + } 2978 + 2963 2979 int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg) 2964 2980 { 2965 2981 void *p; ··· 3052 3028 break; 3053 3029 case IOC_OPAL_GET_LR_STATUS: 3054 3030 ret = opal_locking_range_status(dev, p, arg); 3031 + break; 3032 + case IOC_OPAL_GET_GEOMETRY: 3033 + ret = opal_get_geometry(dev, arg); 3055 3034 break; 3056 3035 default: 3057 3036 break;
+1
include/linux/sed-opal.h
··· 46 46 case IOC_OPAL_GENERIC_TABLE_RW: 47 47 case IOC_OPAL_GET_STATUS: 48 48 case IOC_OPAL_GET_LR_STATUS: 49 + case IOC_OPAL_GET_GEOMETRY: 49 50 return true; 50 51 } 51 52 return false;
+13
include/uapi/linux/sed-opal.h
··· 161 161 __u32 reserved; 162 162 }; 163 163 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 + 164 176 #define IOC_OPAL_SAVE _IOW('p', 220, struct opal_lock_unlock) 165 177 #define IOC_OPAL_LOCK_UNLOCK _IOW('p', 221, struct opal_lock_unlock) 166 178 #define IOC_OPAL_TAKE_OWNERSHIP _IOW('p', 222, struct opal_key) ··· 191 179 #define IOC_OPAL_GENERIC_TABLE_RW _IOW('p', 235, struct opal_read_write_table) 192 180 #define IOC_OPAL_GET_STATUS _IOR('p', 236, struct opal_status) 193 181 #define IOC_OPAL_GET_LR_STATUS _IOW('p', 237, struct opal_lr_status) 182 + #define IOC_OPAL_GET_GEOMETRY _IOR('p', 238, struct opal_geometry) 194 183 195 184 #endif /* _UAPI_SED_OPAL_H */