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-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html