summaryrefslogtreecommitdiff
path: root/block/blk-integrity.c
diff options
context:
space:
mode:
authorChristian Brauner <brauner@kernel.org>2025-07-01 14:00:21 +0200
committerChristian Brauner <brauner@kernel.org>2025-07-01 14:00:21 +0200
commit4a3def74d9810f4d4148a3aa17b76d2f0c0f6109 (patch)
tree643256afb25f0f9f8bf6972b7aee919a1a7eed56 /block/blk-integrity.c
parent19272b37aa4f83ca52bdf9c16d5d81bdd1354494 (diff)
parent9eb22f7fedfc9eb1b7f431a5359abd4d15b0b0cd (diff)
downloadlwn-4a3def74d9810f4d4148a3aa17b76d2f0c0f6109.tar.gz
lwn-4a3def74d9810f4d4148a3aa17b76d2f0c0f6109.zip
Merge patch series "add ioctl to query metadata and protection info capabilities"
Anuj Gupta <anuj20.g@samsung.com> says: This patch series adds a new ioctl to query metadata and integrity capability. * patches from https://lore.kernel.org/20250630090548.3317-1-anuj20.g@samsung.com: fs: add ioctl to query metadata and protection info capabilities nvme: set pi_offset only when checksum type is not BLK_INTEGRITY_CSUM_NONE block: introduce pi_tuple_size field in blk_integrity block: rename tuple_size field in blk_integrity to metadata_size Link: https://lore.kernel.org/20250630090548.3317-1-anuj20.g@samsung.com Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'block/blk-integrity.c')
-rw-r--r--block/blk-integrity.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index e4e2567061f9..9d9dc9c32083 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -13,6 +13,7 @@
#include <linux/scatterlist.h>
#include <linux/export.h>
#include <linux/slab.h>
+#include <linux/t10-pi.h>
#include "blk.h"
@@ -54,6 +55,57 @@ new_segment:
return segments;
}
+int blk_get_meta_cap(struct block_device *bdev, unsigned int cmd,
+ struct logical_block_metadata_cap __user *argp)
+{
+ struct blk_integrity *bi = blk_get_integrity(bdev->bd_disk);
+ struct logical_block_metadata_cap meta_cap = {};
+ size_t usize = _IOC_SIZE(cmd);
+
+ if (!argp)
+ return -EINVAL;
+ if (usize < LBMD_SIZE_VER0)
+ return -EINVAL;
+ if (!bi)
+ goto out;
+
+ if (bi->flags & BLK_INTEGRITY_DEVICE_CAPABLE)
+ meta_cap.lbmd_flags |= LBMD_PI_CAP_INTEGRITY;
+ if (bi->flags & BLK_INTEGRITY_REF_TAG)
+ meta_cap.lbmd_flags |= LBMD_PI_CAP_REFTAG;
+ meta_cap.lbmd_interval = 1 << bi->interval_exp;
+ meta_cap.lbmd_size = bi->metadata_size;
+ meta_cap.lbmd_pi_size = bi->pi_tuple_size;
+ meta_cap.lbmd_pi_offset = bi->pi_offset;
+ meta_cap.lbmd_opaque_size = bi->metadata_size - bi->pi_tuple_size;
+ if (meta_cap.lbmd_opaque_size && !bi->pi_offset)
+ meta_cap.lbmd_opaque_offset = bi->pi_tuple_size;
+
+ meta_cap.lbmd_guard_tag_type = bi->csum_type;
+ if (bi->csum_type != BLK_INTEGRITY_CSUM_NONE)
+ meta_cap.lbmd_app_tag_size = 2;
+
+ if (bi->flags & BLK_INTEGRITY_REF_TAG) {
+ switch (bi->csum_type) {
+ case BLK_INTEGRITY_CSUM_CRC64:
+ meta_cap.lbmd_ref_tag_size =
+ sizeof_field(struct crc64_pi_tuple, ref_tag);
+ break;
+ case BLK_INTEGRITY_CSUM_CRC:
+ case BLK_INTEGRITY_CSUM_IP:
+ meta_cap.lbmd_ref_tag_size =
+ sizeof_field(struct t10_pi_tuple, ref_tag);
+ break;
+ default:
+ break;
+ }
+ }
+
+out:
+ return copy_struct_to_user(argp, usize, &meta_cap, sizeof(meta_cap),
+ NULL);
+}
+
/**
* blk_rq_map_integrity_sg - Map integrity metadata into a scatterlist
* @rq: request to map
@@ -239,7 +291,7 @@ static ssize_t format_show(struct device *dev, struct device_attribute *attr,
{
struct blk_integrity *bi = dev_to_bi(dev);
- if (!bi->tuple_size)
+ if (!bi->metadata_size)
return sysfs_emit(page, "none\n");
return sysfs_emit(page, "%s\n", blk_integrity_profile_name(bi));
}