diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2017-04-18 12:43:20 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-05-14 08:00:22 -0400 |
commit | 6a7620744e89c99b5f9aeaf083766d48b0500d87 (patch) | |
tree | 10be05fc6d02718296860a35e25cf138c6153f9f | |
parent | 48d9fa1ece5ee453d4c08a7feec74c966939a25c (diff) |
block: get rid of blk_integrity_revalidate()
commit 19b7ccf8651df09d274671b53039c672a52ad84d upstream.
Commit 25520d55cdb6 ("block: Inline blk_integrity in struct gendisk")
introduced blk_integrity_revalidate(), which seems to assume ownership
of the stable pages flag and unilaterally clears it if no blk_integrity
profile is registered:
if (bi->profile)
disk->queue->backing_dev_info->capabilities |=
BDI_CAP_STABLE_WRITES;
else
disk->queue->backing_dev_info->capabilities &=
~BDI_CAP_STABLE_WRITES;
It's called from revalidate_disk() and rescan_partitions(), making it
impossible to enable stable pages for drivers that support partitions
and don't use blk_integrity: while the call in revalidate_disk() can be
trivially worked around (see zram, which doesn't support partitions and
hence gets away with zram_revalidate_disk()), rescan_partitions() can
be triggered from userspace at any time. This breaks rbd, where the
ceph messenger is responsible for generating/verifying CRCs.
Since blk_integrity_{un,}register() "must" be used for (un)registering
the integrity profile with the block layer, move BDI_CAP_STABLE_WRITES
setting there. This way drivers that call blk_integrity_register() and
use integrity infrastructure won't interfere with drivers that don't
but still want stable pages.
Fixes: 25520d55cdb6 ("block: Inline blk_integrity in struct gendisk")
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Mike Snitzer <snitzer@redhat.com>
Tested-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
[idryomov@gmail.com: backport to < 4.11: bdi is embedded in queue]
Signed-off-by: Jens Axboe <axboe@fb.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | block/blk-integrity.c | 19 | ||||
-rw-r--r-- | block/partition-generic.c | 1 | ||||
-rw-r--r-- | fs/block_dev.c | 1 | ||||
-rw-r--r-- | include/linux/genhd.h | 2 |
4 files changed, 2 insertions, 21 deletions
diff --git a/block/blk-integrity.c b/block/blk-integrity.c index d69c5c79f98e..319f2e4f4a8b 100644 --- a/block/blk-integrity.c +++ b/block/blk-integrity.c | |||
@@ -417,7 +417,7 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template | |||
417 | bi->tuple_size = template->tuple_size; | 417 | bi->tuple_size = template->tuple_size; |
418 | bi->tag_size = template->tag_size; | 418 | bi->tag_size = template->tag_size; |
419 | 419 | ||
420 | blk_integrity_revalidate(disk); | 420 | disk->queue->backing_dev_info.capabilities |= BDI_CAP_STABLE_WRITES; |
421 | } | 421 | } |
422 | EXPORT_SYMBOL(blk_integrity_register); | 422 | EXPORT_SYMBOL(blk_integrity_register); |
423 | 423 | ||
@@ -430,26 +430,11 @@ EXPORT_SYMBOL(blk_integrity_register); | |||
430 | */ | 430 | */ |
431 | void blk_integrity_unregister(struct gendisk *disk) | 431 | void blk_integrity_unregister(struct gendisk *disk) |
432 | { | 432 | { |
433 | blk_integrity_revalidate(disk); | 433 | disk->queue->backing_dev_info.capabilities &= ~BDI_CAP_STABLE_WRITES; |
434 | memset(&disk->queue->integrity, 0, sizeof(struct blk_integrity)); | 434 | memset(&disk->queue->integrity, 0, sizeof(struct blk_integrity)); |
435 | } | 435 | } |
436 | EXPORT_SYMBOL(blk_integrity_unregister); | 436 | EXPORT_SYMBOL(blk_integrity_unregister); |
437 | 437 | ||
438 | void blk_integrity_revalidate(struct gendisk *disk) | ||
439 | { | ||
440 | struct blk_integrity *bi = &disk->queue->integrity; | ||
441 | |||
442 | if (!(disk->flags & GENHD_FL_UP)) | ||
443 | return; | ||
444 | |||
445 | if (bi->profile) | ||
446 | disk->queue->backing_dev_info.capabilities |= | ||
447 | BDI_CAP_STABLE_WRITES; | ||
448 | else | ||
449 | disk->queue->backing_dev_info.capabilities &= | ||
450 | ~BDI_CAP_STABLE_WRITES; | ||
451 | } | ||
452 | |||
453 | void blk_integrity_add(struct gendisk *disk) | 438 | void blk_integrity_add(struct gendisk *disk) |
454 | { | 439 | { |
455 | if (kobject_init_and_add(&disk->integrity_kobj, &integrity_ktype, | 440 | if (kobject_init_and_add(&disk->integrity_kobj, &integrity_ktype, |
diff --git a/block/partition-generic.c b/block/partition-generic.c index 71d9ed9df8da..a2437c006640 100644 --- a/block/partition-generic.c +++ b/block/partition-generic.c | |||
@@ -447,7 +447,6 @@ rescan: | |||
447 | 447 | ||
448 | if (disk->fops->revalidate_disk) | 448 | if (disk->fops->revalidate_disk) |
449 | disk->fops->revalidate_disk(disk); | 449 | disk->fops->revalidate_disk(disk); |
450 | blk_integrity_revalidate(disk); | ||
451 | check_disk_size_change(disk, bdev); | 450 | check_disk_size_change(disk, bdev); |
452 | bdev->bd_invalidated = 0; | 451 | bdev->bd_invalidated = 0; |
453 | if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) | 452 | if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 092a2eed1628..9ad527ff9974 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -1165,7 +1165,6 @@ int revalidate_disk(struct gendisk *disk) | |||
1165 | 1165 | ||
1166 | if (disk->fops->revalidate_disk) | 1166 | if (disk->fops->revalidate_disk) |
1167 | ret = disk->fops->revalidate_disk(disk); | 1167 | ret = disk->fops->revalidate_disk(disk); |
1168 | blk_integrity_revalidate(disk); | ||
1169 | bdev = bdget_disk(disk, 0); | 1168 | bdev = bdget_disk(disk, 0); |
1170 | if (!bdev) | 1169 | if (!bdev) |
1171 | return ret; | 1170 | return ret; |
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index e0341af6950e..3c99fb6727ca 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
@@ -731,11 +731,9 @@ static inline void part_nr_sects_write(struct hd_struct *part, sector_t size) | |||
731 | #if defined(CONFIG_BLK_DEV_INTEGRITY) | 731 | #if defined(CONFIG_BLK_DEV_INTEGRITY) |
732 | extern void blk_integrity_add(struct gendisk *); | 732 | extern void blk_integrity_add(struct gendisk *); |
733 | extern void blk_integrity_del(struct gendisk *); | 733 | extern void blk_integrity_del(struct gendisk *); |
734 | extern void blk_integrity_revalidate(struct gendisk *); | ||
735 | #else /* CONFIG_BLK_DEV_INTEGRITY */ | 734 | #else /* CONFIG_BLK_DEV_INTEGRITY */ |
736 | static inline void blk_integrity_add(struct gendisk *disk) { } | 735 | static inline void blk_integrity_add(struct gendisk *disk) { } |
737 | static inline void blk_integrity_del(struct gendisk *disk) { } | 736 | static inline void blk_integrity_del(struct gendisk *disk) { } |
738 | static inline void blk_integrity_revalidate(struct gendisk *disk) { } | ||
739 | #endif /* CONFIG_BLK_DEV_INTEGRITY */ | 737 | #endif /* CONFIG_BLK_DEV_INTEGRITY */ |
740 | 738 | ||
741 | #else /* CONFIG_BLOCK */ | 739 | #else /* CONFIG_BLOCK */ |