Commit 0873ab02 authored by Ilya Dryomov's avatar Ilya Dryomov Committed by Greg Kroah-Hartman

block: get rid of blk_integrity_revalidate()

commit 19b7ccf8 upstream.

Commit 25520d55 ("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: 25520d55 ("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: default avatarDan Williams <dan.j.williams@intel.com>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3ed024e2
...@@ -417,7 +417,7 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template ...@@ -417,7 +417,7 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template
bi->tuple_size = template->tuple_size; bi->tuple_size = template->tuple_size;
bi->tag_size = template->tag_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); EXPORT_SYMBOL(blk_integrity_register);
...@@ -430,26 +430,11 @@ EXPORT_SYMBOL(blk_integrity_register); ...@@ -430,26 +430,11 @@ EXPORT_SYMBOL(blk_integrity_register);
*/ */
void blk_integrity_unregister(struct gendisk *disk) 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)); memset(&disk->queue->integrity, 0, sizeof(struct blk_integrity));
} }
EXPORT_SYMBOL(blk_integrity_unregister); 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) void blk_integrity_add(struct gendisk *disk)
{ {
if (kobject_init_and_add(&disk->integrity_kobj, &integrity_ktype, if (kobject_init_and_add(&disk->integrity_kobj, &integrity_ktype,
......
...@@ -497,7 +497,6 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev) ...@@ -497,7 +497,6 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
if (disk->fops->revalidate_disk) if (disk->fops->revalidate_disk)
disk->fops->revalidate_disk(disk); disk->fops->revalidate_disk(disk);
blk_integrity_revalidate(disk);
check_disk_size_change(disk, bdev); check_disk_size_change(disk, bdev);
bdev->bd_invalidated = 0; bdev->bd_invalidated = 0;
if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) if (!get_capacity(disk) || !(state = check_partition(disk, bdev)))
......
...@@ -1451,7 +1451,6 @@ int revalidate_disk(struct gendisk *disk) ...@@ -1451,7 +1451,6 @@ int revalidate_disk(struct gendisk *disk)
if (disk->fops->revalidate_disk) if (disk->fops->revalidate_disk)
ret = disk->fops->revalidate_disk(disk); ret = disk->fops->revalidate_disk(disk);
blk_integrity_revalidate(disk);
bdev = bdget_disk(disk, 0); bdev = bdget_disk(disk, 0);
if (!bdev) if (!bdev)
return ret; return ret;
......
...@@ -722,11 +722,9 @@ static inline void part_nr_sects_write(struct hd_struct *part, sector_t size) ...@@ -722,11 +722,9 @@ static inline void part_nr_sects_write(struct hd_struct *part, sector_t size)
#if defined(CONFIG_BLK_DEV_INTEGRITY) #if defined(CONFIG_BLK_DEV_INTEGRITY)
extern void blk_integrity_add(struct gendisk *); extern void blk_integrity_add(struct gendisk *);
extern void blk_integrity_del(struct gendisk *); extern void blk_integrity_del(struct gendisk *);
extern void blk_integrity_revalidate(struct gendisk *);
#else /* CONFIG_BLK_DEV_INTEGRITY */ #else /* CONFIG_BLK_DEV_INTEGRITY */
static inline void blk_integrity_add(struct gendisk *disk) { } static inline void blk_integrity_add(struct gendisk *disk) { }
static inline void blk_integrity_del(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 */ #endif /* CONFIG_BLK_DEV_INTEGRITY */
#else /* CONFIG_BLOCK */ #else /* CONFIG_BLOCK */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment