aboutsummaryrefslogtreecommitdiffstats
path: root/block/blk-integrity.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/blk-integrity.c')
-rw-r--r--block/blk-integrity.c193
1 files changed, 77 insertions, 116 deletions
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index ff1070edbb40..d4e9b4556d14 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -6,7 +6,7 @@
* Written by: Martin K. Petersen <martin.petersen@oracle.com>
*/
-#include <linux/blkdev.h>
+#include <linux/blk-integrity.h>
#include <linux/backing-dev.h>
#include <linux/mempool.h>
#include <linux/bio.h>
@@ -183,7 +183,6 @@ bool blk_integrity_merge_rq(struct request_queue *q, struct request *req,
return true;
}
-EXPORT_SYMBOL(blk_integrity_merge_rq);
bool blk_integrity_merge_bio(struct request_queue *q, struct request *req,
struct bio *bio)
@@ -212,63 +211,45 @@ bool blk_integrity_merge_bio(struct request_queue *q, struct request *req,
return true;
}
-EXPORT_SYMBOL(blk_integrity_merge_bio);
-struct integrity_sysfs_entry {
- struct attribute attr;
- ssize_t (*show)(struct blk_integrity *, char *);
- ssize_t (*store)(struct blk_integrity *, const char *, size_t);
-};
-
-static ssize_t integrity_attr_show(struct kobject *kobj, struct attribute *attr,
- char *page)
+static inline struct blk_integrity *dev_to_bi(struct device *dev)
{
- struct gendisk *disk = container_of(kobj, struct gendisk, integrity_kobj);
- struct blk_integrity *bi = &disk->queue->integrity;
- struct integrity_sysfs_entry *entry =
- container_of(attr, struct integrity_sysfs_entry, attr);
-
- return entry->show(bi, page);
+ return &dev_to_disk(dev)->queue->integrity;
}
-static ssize_t integrity_attr_store(struct kobject *kobj,
- struct attribute *attr, const char *page,
- size_t count)
+static ssize_t format_show(struct device *dev, struct device_attribute *attr,
+ char *page)
{
- struct gendisk *disk = container_of(kobj, struct gendisk, integrity_kobj);
- struct blk_integrity *bi = &disk->queue->integrity;
- struct integrity_sysfs_entry *entry =
- container_of(attr, struct integrity_sysfs_entry, attr);
- ssize_t ret = 0;
+ struct blk_integrity *bi = dev_to_bi(dev);
- if (entry->store)
- ret = entry->store(bi, page, count);
-
- return ret;
-}
-
-static ssize_t integrity_format_show(struct blk_integrity *bi, char *page)
-{
if (bi->profile && bi->profile->name)
- return sprintf(page, "%s\n", bi->profile->name);
- else
- return sprintf(page, "none\n");
+ return sysfs_emit(page, "%s\n", bi->profile->name);
+ return sysfs_emit(page, "none\n");
}
-static ssize_t integrity_tag_size_show(struct blk_integrity *bi, char *page)
+static ssize_t tag_size_show(struct device *dev, struct device_attribute *attr,
+ char *page)
{
- return sprintf(page, "%u\n", bi->tag_size);
+ struct blk_integrity *bi = dev_to_bi(dev);
+
+ return sysfs_emit(page, "%u\n", bi->tag_size);
}
-static ssize_t integrity_interval_show(struct blk_integrity *bi, char *page)
+static ssize_t protection_interval_bytes_show(struct device *dev,
+ struct device_attribute *attr,
+ char *page)
{
- return sprintf(page, "%u\n",
- bi->interval_exp ? 1 << bi->interval_exp : 0);
+ struct blk_integrity *bi = dev_to_bi(dev);
+
+ return sysfs_emit(page, "%u\n",
+ bi->interval_exp ? 1 << bi->interval_exp : 0);
}
-static ssize_t integrity_verify_store(struct blk_integrity *bi,
- const char *page, size_t count)
+static ssize_t read_verify_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *page, size_t count)
{
+ struct blk_integrity *bi = dev_to_bi(dev);
char *p = (char *) page;
unsigned long val = simple_strtoul(p, &p, 10);
@@ -280,14 +261,20 @@ static ssize_t integrity_verify_store(struct blk_integrity *bi,
return count;
}
-static ssize_t integrity_verify_show(struct blk_integrity *bi, char *page)
+static ssize_t read_verify_show(struct device *dev,
+ struct device_attribute *attr, char *page)
{
- return sprintf(page, "%d\n", (bi->flags & BLK_INTEGRITY_VERIFY) != 0);
+ struct blk_integrity *bi = dev_to_bi(dev);
+
+ return sysfs_emit(page, "%d\n", !!(bi->flags & BLK_INTEGRITY_VERIFY));
}
-static ssize_t integrity_generate_store(struct blk_integrity *bi,
- const char *page, size_t count)
+static ssize_t write_generate_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *page, size_t count)
{
+ struct blk_integrity *bi = dev_to_bi(dev);
+
char *p = (char *) page;
unsigned long val = simple_strtoul(p, &p, 10);
@@ -299,68 +286,44 @@ static ssize_t integrity_generate_store(struct blk_integrity *bi,
return count;
}
-static ssize_t integrity_generate_show(struct blk_integrity *bi, char *page)
+static ssize_t write_generate_show(struct device *dev,
+ struct device_attribute *attr, char *page)
{
- return sprintf(page, "%d\n", (bi->flags & BLK_INTEGRITY_GENERATE) != 0);
-}
+ struct blk_integrity *bi = dev_to_bi(dev);
-static ssize_t integrity_device_show(struct blk_integrity *bi, char *page)
-{
- return sprintf(page, "%u\n",
- (bi->flags & BLK_INTEGRITY_DEVICE_CAPABLE) != 0);
+ return sysfs_emit(page, "%d\n", !!(bi->flags & BLK_INTEGRITY_GENERATE));
}
-static struct integrity_sysfs_entry integrity_format_entry = {
- .attr = { .name = "format", .mode = 0444 },
- .show = integrity_format_show,
-};
-
-static struct integrity_sysfs_entry integrity_tag_size_entry = {
- .attr = { .name = "tag_size", .mode = 0444 },
- .show = integrity_tag_size_show,
-};
-
-static struct integrity_sysfs_entry integrity_interval_entry = {
- .attr = { .name = "protection_interval_bytes", .mode = 0444 },
- .show = integrity_interval_show,
-};
-
-static struct integrity_sysfs_entry integrity_verify_entry = {
- .attr = { .name = "read_verify", .mode = 0644 },
- .show = integrity_verify_show,
- .store = integrity_verify_store,
-};
+static ssize_t device_is_integrity_capable_show(struct device *dev,
+ struct device_attribute *attr,
+ char *page)
+{
+ struct blk_integrity *bi = dev_to_bi(dev);
-static struct integrity_sysfs_entry integrity_generate_entry = {
- .attr = { .name = "write_generate", .mode = 0644 },
- .show = integrity_generate_show,
- .store = integrity_generate_store,
-};
+ return sysfs_emit(page, "%u\n",
+ !!(bi->flags & BLK_INTEGRITY_DEVICE_CAPABLE));
+}
-static struct integrity_sysfs_entry integrity_device_entry = {
- .attr = { .name = "device_is_integrity_capable", .mode = 0444 },
- .show = integrity_device_show,
-};
+static DEVICE_ATTR_RO(format);
+static DEVICE_ATTR_RO(tag_size);
+static DEVICE_ATTR_RO(protection_interval_bytes);
+static DEVICE_ATTR_RW(read_verify);
+static DEVICE_ATTR_RW(write_generate);
+static DEVICE_ATTR_RO(device_is_integrity_capable);
static struct attribute *integrity_attrs[] = {
- &integrity_format_entry.attr,
- &integrity_tag_size_entry.attr,
- &integrity_interval_entry.attr,
- &integrity_verify_entry.attr,
- &integrity_generate_entry.attr,
- &integrity_device_entry.attr,
- NULL,
+ &dev_attr_format.attr,
+ &dev_attr_tag_size.attr,
+ &dev_attr_protection_interval_bytes.attr,
+ &dev_attr_read_verify.attr,
+ &dev_attr_write_generate.attr,
+ &dev_attr_device_is_integrity_capable.attr,
+ NULL
};
-ATTRIBUTE_GROUPS(integrity);
-static const struct sysfs_ops integrity_ops = {
- .show = &integrity_attr_show,
- .store = &integrity_attr_store,
-};
-
-static struct kobj_type integrity_ktype = {
- .default_groups = integrity_groups,
- .sysfs_ops = &integrity_ops,
+const struct attribute_group blk_integrity_attr_group = {
+ .name = "integrity",
+ .attrs = integrity_attrs,
};
static blk_status_t blk_integrity_nop_fn(struct blk_integrity_iter *iter)
@@ -408,7 +371,14 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template
bi->tuple_size = template->tuple_size;
bi->tag_size = template->tag_size;
- disk->queue->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES;
+ blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES, disk->queue);
+
+#ifdef CONFIG_BLK_INLINE_ENCRYPTION
+ if (disk->queue->crypto_profile) {
+ pr_warn("blk-integrity: Integrity and hardware inline encryption are not supported together. Disabling hardware inline encryption.\n");
+ disk->queue->crypto_profile = NULL;
+ }
+#endif
}
EXPORT_SYMBOL(blk_integrity_register);
@@ -421,23 +391,14 @@ EXPORT_SYMBOL(blk_integrity_register);
*/
void blk_integrity_unregister(struct gendisk *disk)
{
- disk->queue->backing_dev_info->capabilities &= ~BDI_CAP_STABLE_WRITES;
- memset(&disk->queue->integrity, 0, sizeof(struct blk_integrity));
-}
-EXPORT_SYMBOL(blk_integrity_unregister);
+ struct blk_integrity *bi = &disk->queue->integrity;
-void blk_integrity_add(struct gendisk *disk)
-{
- if (kobject_init_and_add(&disk->integrity_kobj, &integrity_ktype,
- &disk_to_dev(disk)->kobj, "%s", "integrity"))
+ if (!bi->profile)
return;
- kobject_uevent(&disk->integrity_kobj, KOBJ_ADD);
-}
-
-void blk_integrity_del(struct gendisk *disk)
-{
- kobject_uevent(&disk->integrity_kobj, KOBJ_REMOVE);
- kobject_del(&disk->integrity_kobj);
- kobject_put(&disk->integrity_kobj);
+ /* ensure all bios are off the integrity workqueue */
+ blk_flush_integrity();
+ blk_queue_flag_clear(QUEUE_FLAG_STABLE_WRITES, disk->queue);
+ memset(bi, 0, sizeof(*bi));
}
+EXPORT_SYMBOL(blk_integrity_unregister);