aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2017-04-18 12:43:20 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-05-14 08:00:22 -0400
commit6a7620744e89c99b5f9aeaf083766d48b0500d87 (patch)
tree10be05fc6d02718296860a35e25cf138c6153f9f
parent48d9fa1ece5ee453d4c08a7feec74c966939a25c (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.c19
-rw-r--r--block/partition-generic.c1
-rw-r--r--fs/block_dev.c1
-rw-r--r--include/linux/genhd.h2
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}
422EXPORT_SYMBOL(blk_integrity_register); 422EXPORT_SYMBOL(blk_integrity_register);
423 423
@@ -430,26 +430,11 @@ EXPORT_SYMBOL(blk_integrity_register);
430 */ 430 */
431void blk_integrity_unregister(struct gendisk *disk) 431void 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}
436EXPORT_SYMBOL(blk_integrity_unregister); 436EXPORT_SYMBOL(blk_integrity_unregister);
437 437
438void 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
453void blk_integrity_add(struct gendisk *disk) 438void 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)
732extern void blk_integrity_add(struct gendisk *); 732extern void blk_integrity_add(struct gendisk *);
733extern void blk_integrity_del(struct gendisk *); 733extern void blk_integrity_del(struct gendisk *);
734extern void blk_integrity_revalidate(struct gendisk *);
735#else /* CONFIG_BLK_DEV_INTEGRITY */ 734#else /* CONFIG_BLK_DEV_INTEGRITY */
736static inline void blk_integrity_add(struct gendisk *disk) { } 735static inline void blk_integrity_add(struct gendisk *disk) { }
737static inline void blk_integrity_del(struct gendisk *disk) { } 736static inline void blk_integrity_del(struct gendisk *disk) { }
738static 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 */