[PATCH 5/6] PI IO extension: advertise possible userspace flags

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Expose possible userland flags to the new PI IO extension so that
userspace can discover what flags exist.

Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
---
 Documentation/ABI/testing/sysfs-block  |   14 ++++++++++++++
 Documentation/block/data-integrity.txt |   22 +++++++++++++++++++++
 block/blk-integrity.c                  |   33 ++++++++++++++++++++++++++++++++
 drivers/scsi/sd_dif.c                  |   11 +++++++++++
 include/linux/blkdev.h                 |    7 +++++++
 5 files changed, 87 insertions(+)


diff --git a/Documentation/ABI/testing/sysfs-block b/Documentation/ABI/testing/sysfs-block
index 279da08..989cb80 100644
--- a/Documentation/ABI/testing/sysfs-block
+++ b/Documentation/ABI/testing/sysfs-block
@@ -53,6 +53,20 @@ Description:
 		512 bytes of data.
 
 
+What:		/sys/block/<disk>/integrity/tuple_size
+Date:		March 2014
+Contact:	Darrick J. Wong <darrick.wong@xxxxxxxxxx>
+Description:
+		Size in bytes of the integrity data buffer for each logical
+		block.
+
+What:		/sys/block/<disk>/integrity/write_user_flags
+Date:		March 2014
+Contact:	Darrick J. Wong <darrick.wong@xxxxxxxxxx>
+Description:
+		Provides a list of flags that userspace can pass to the kernel
+		when supplying integrity data for a write IO.
+
 What:		/sys/block/<disk>/integrity/write_generate
 Date:		June 2008
 Contact:	Martin K. Petersen <martin.petersen@xxxxxxxxxx>
diff --git a/Documentation/block/data-integrity.txt b/Documentation/block/data-integrity.txt
index b72a54f..e33d4a7 100644
--- a/Documentation/block/data-integrity.txt
+++ b/Documentation/block/data-integrity.txt
@@ -341,7 +341,29 @@ will require extra work due to the application tag.
       specific to the blk_integrity provider) arrange for pre-processing
       of the user buffer prior to issuing the IO.
 
+      'user_write_flags' points to an array of struct blk_integrity_flag,
+      which maps mod_user_buf_fn flags to a description of what they do.
+
       See 6.2 for a description of get_tag_fn and set_tag_fn.
 
+5.5 PASSING INTEGRITY DATA FROM USERSPACE
+
+    The "IO extension" interface has been expanded to provide
+    userspace programs with the ability to provide PI data with a WRITE,
+    or to receive PI data with a READ.  The fields ie_pi_buf,
+    ie_pi_buflen, and ie_pi_flags should contain a pointer to the PI
+    buffer, the length of the PI buffer, and any flags that should be
+    passed to the PI provider.
+
+    This buffer must contain PI tuples.  Tuples must NOT split a page
+    boundary.  Valid flag values can be found in
+    /sys/block/*/integrity/user_write_flags.  The tuple size can be found
+    in /sys/block/*/integrity/tuple_size.
+
+    In general, the flags allow the user program to ask the in-kernel
+    integrity provider to fill in some parts of the tuples.  For example,
+    the T10 DIF provider can fill in the reference tag (sector number) so
+    that userspace can choose not to care about the reference tag.
+
 ----------------------------------------------------------------------
 2007-12-24 Martin K. Petersen <martin.petersen@xxxxxxxxxx>
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index 1cb1eb2..557d28e 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -307,6 +307,26 @@ static ssize_t integrity_write_show(struct blk_integrity *bi, char *page)
 	return sprintf(page, "%d\n", (bi->flags & INTEGRITY_FLAG_WRITE) != 0);
 }
 
+static ssize_t integrity_write_flags_show(struct blk_integrity *bi, char *page)
+{
+	struct blk_integrity_flag *flag = bi->user_write_flags;
+	char *p = page;
+	ssize_t ret = 0;
+
+	while (flag->value) {
+		ret += snprintf(p, PAGE_SIZE - ret, "0x%x: %s\n",
+				flag->value, flag->descr);
+		p = page + ret;
+		flag++;
+	}
+	return ret;
+}
+
+static ssize_t integrity_tuple_size_show(struct blk_integrity *bi, char *page)
+{
+	return sprintf(page, "%d\n", bi->tuple_size);
+}
+
 static struct integrity_sysfs_entry integrity_format_entry = {
 	.attr = { .name = "format", .mode = S_IRUGO },
 	.show = integrity_format_show,
@@ -329,11 +349,23 @@ static struct integrity_sysfs_entry integrity_write_entry = {
 	.store = integrity_write_store,
 };
 
+static struct integrity_sysfs_entry integrity_write_flags_entry = {
+	.attr = { .name = "write_user_flags", .mode = S_IRUGO },
+	.show = integrity_write_flags_show,
+};
+
+static struct integrity_sysfs_entry integrity_tuple_size_entry = {
+	.attr = { .name = "tuple_size", .mode = S_IRUGO },
+	.show = integrity_tuple_size_show,
+};
+
 static struct attribute *integrity_attrs[] = {
 	&integrity_format_entry.attr,
 	&integrity_tag_size_entry.attr,
 	&integrity_read_entry.attr,
 	&integrity_write_entry.attr,
+	&integrity_write_flags_entry.attr,
+	&integrity_tuple_size_entry.attr,
 	NULL,
 };
 
@@ -422,6 +454,7 @@ int blk_integrity_register(struct gendisk *disk, struct blk_integrity *template)
 		bi->get_tag_fn = template->get_tag_fn;
 		bi->tag_size = template->tag_size;
 		bi->mod_user_buf_fn = template->mod_user_buf_fn;
+		bi->user_write_flags = template->user_write_flags;
 	} else
 		bi->name = bi_unsupported_name;
 
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c
index 74182c9..bea648b 100644
--- a/drivers/scsi/sd_dif.c
+++ b/drivers/scsi/sd_dif.c
@@ -182,6 +182,13 @@ static void sd_dif_type1_get_tag(void *prot, void *tag_buf, unsigned int sectors
 	}
 }
 
+static struct blk_integrity_flag dif_flags[] = {
+	{GENERATE_GUARD,	"generate guard tag"},
+	{GENERATE_REF,		"generate ref tag"},
+	{GENERATE_APP,		"generate app tag"},
+	{0, NULL},
+};
+
 static struct blk_integrity dif_type1_integrity_crc = {
 	.name			= "T10-DIF-TYPE1-CRC",
 	.generate_fn		= sd_dif_type1_generate_crc,
@@ -191,6 +198,7 @@ static struct blk_integrity dif_type1_integrity_crc = {
 	.tuple_size		= sizeof(struct sd_dif_tuple),
 	.tag_size		= 0,
 	.mod_user_buf_fn	= sd_dif_type1_mod_crc,
+	.user_write_flags	= dif_flags,
 };
 
 static struct blk_integrity dif_type1_integrity_ip = {
@@ -202,6 +210,7 @@ static struct blk_integrity dif_type1_integrity_ip = {
 	.tuple_size		= sizeof(struct sd_dif_tuple),
 	.tag_size		= 0,
 	.mod_user_buf_fn	= sd_dif_type1_mod_ip,
+	.user_write_flags	= dif_flags,
 };
 
 
@@ -334,6 +343,7 @@ static struct blk_integrity dif_type3_integrity_crc = {
 	.tuple_size		= sizeof(struct sd_dif_tuple),
 	.tag_size		= 0,
 	.mod_user_buf_fn	= sd_dif_type3_mod_crc,
+	.user_write_flags	= dif_flags,
 };
 
 static struct blk_integrity dif_type3_integrity_ip = {
@@ -345,6 +355,7 @@ static struct blk_integrity dif_type3_integrity_ip = {
 	.tuple_size		= sizeof(struct sd_dif_tuple),
 	.tag_size		= 0,
 	.mod_user_buf_fn	= sd_dif_type3_mod_ip,
+	.user_write_flags	= dif_flags,
 };
 
 /*
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index cf1ec22..e8e6401 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1428,6 +1428,11 @@ typedef void (integrity_set_tag_fn) (void *, void *, unsigned int);
 typedef void (integrity_get_tag_fn) (void *, void *, unsigned int);
 typedef int (integrity_mod_user_buf_fn) (struct blk_integrity_exchg *, int);
 
+struct blk_integrity_flag {
+	unsigned int value;
+	const char *descr;
+};
+
 struct blk_integrity {
 	integrity_gen_fn	*generate_fn;
 	integrity_vrfy_fn	*verify_fn;
@@ -1443,6 +1448,8 @@ struct blk_integrity {
 	const char		*name;
 
 	struct kobject		kobj;
+
+	struct blk_integrity_flag	*user_write_flags;
 };
 
 extern bool blk_integrity_is_initialized(struct gendisk *);

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux