| From 559040a100a7e9268103ff8ed739d74dc44e768a Mon Sep 17 00:00:00 2001 |
| From: Ilya Dryomov <idryomov@gmail.com> |
| Date: Tue, 18 Apr 2017 18:43:20 +0200 |
| Subject: [PATCH] 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> |
| Cc: stable@vger.kernel.org # 4.4+, needs backporting |
| Tested-by: Dan Williams <dan.j.williams@intel.com> |
| Signed-off-by: Ilya Dryomov <idryomov@gmail.com> |
| Signed-off-by: Jens Axboe <axboe@fb.com> |
| |
| 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 |
| bi->tuple_size = template->tuple_size; |
| bi->tag_size = template->tag_size; |
| |
| - blk_integrity_revalidate(disk); |
| + disk->queue->backing_dev_info.capabilities |= BDI_CAP_STABLE_WRITES; |
| } |
| EXPORT_SYMBOL(blk_integrity_register); |
| |
| @@ -430,26 +430,11 @@ EXPORT_SYMBOL(blk_integrity_register); |
| */ |
| void blk_integrity_unregister(struct gendisk *disk) |
| { |
| - blk_integrity_revalidate(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); |
| |
| -void blk_integrity_revalidate(struct gendisk *disk) |
| -{ |
| - struct blk_integrity *bi = &disk->queue->integrity; |
| - |
| - if (!(disk->flags & GENHD_FL_UP)) |
| - return; |
| - |
| - if (bi->profile) |
| - disk->queue->backing_dev_info.capabilities |= |
| - BDI_CAP_STABLE_WRITES; |
| - else |
| - disk->queue->backing_dev_info.capabilities &= |
| - ~BDI_CAP_STABLE_WRITES; |
| -} |
| - |
| void blk_integrity_add(struct gendisk *disk) |
| { |
| 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: |
| |
| if (disk->fops->revalidate_disk) |
| disk->fops->revalidate_disk(disk); |
| - blk_integrity_revalidate(disk); |
| check_disk_size_change(disk, bdev); |
| bdev->bd_invalidated = 0; |
| if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) |
| diff --git a/fs/block_dev.c b/fs/block_dev.c |
| index 496d99b80fb0..585ff2c70d16 100644 |
| --- a/fs/block_dev.c |
| +++ b/fs/block_dev.c |
| @@ -1170,7 +1170,6 @@ int revalidate_disk(struct gendisk *disk) |
| |
| if (disk->fops->revalidate_disk) |
| ret = disk->fops->revalidate_disk(disk); |
| - blk_integrity_revalidate(disk); |
| bdev = bdget_disk(disk, 0); |
| if (!bdev) |
| return ret; |
| diff --git a/include/linux/genhd.h b/include/linux/genhd.h |
| index 1dbf52f9c24b..9e8cfdb5d976 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) |
| #if defined(CONFIG_BLK_DEV_INTEGRITY) |
| extern void blk_integrity_add(struct gendisk *); |
| extern void blk_integrity_del(struct gendisk *); |
| -extern void blk_integrity_revalidate(struct gendisk *); |
| #else /* CONFIG_BLK_DEV_INTEGRITY */ |
| static inline void blk_integrity_add(struct gendisk *disk) { } |
| static inline void blk_integrity_del(struct gendisk *disk) { } |
| -static inline void blk_integrity_revalidate(struct gendisk *disk) { } |
| #endif /* CONFIG_BLK_DEV_INTEGRITY */ |
| |
| #else /* CONFIG_BLOCK */ |
| -- |
| 2.12.0 |
| |