Commit 659e56ba authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe

block: add a new revalidate_disk_size helper

revalidate_disk is a relative awkward helper for driver use, as it first
calls an optional driver method and then updates the block device size,
while most callers either don't need the method call at all, or want to
keep state between the caller and the called method.

Add a revalidate_disk_size helper that just performs the update of the
block device size from the gendisk one, and switch all drivers that do
not implement ->revalidate_disk to use the new helper instead of
revalidate_disk()
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
Reviewed-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Acked-by: default avatarSong Liu <song@kernel.org>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent f4ad06f2
...@@ -4921,7 +4921,7 @@ static void rbd_dev_update_size(struct rbd_device *rbd_dev) ...@@ -4921,7 +4921,7 @@ static void rbd_dev_update_size(struct rbd_device *rbd_dev)
size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE; size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE;
dout("setting size to %llu sectors", (unsigned long long)size); dout("setting size to %llu sectors", (unsigned long long)size);
set_capacity(rbd_dev->disk, size); set_capacity(rbd_dev->disk, size);
revalidate_disk(rbd_dev->disk); revalidate_disk_size(rbd_dev->disk, true);
} }
} }
......
...@@ -102,18 +102,12 @@ static int rnbd_clt_set_dev_attr(struct rnbd_clt_dev *dev, ...@@ -102,18 +102,12 @@ static int rnbd_clt_set_dev_attr(struct rnbd_clt_dev *dev,
static int rnbd_clt_change_capacity(struct rnbd_clt_dev *dev, static int rnbd_clt_change_capacity(struct rnbd_clt_dev *dev,
size_t new_nsectors) size_t new_nsectors)
{ {
int err = 0;
rnbd_clt_info(dev, "Device size changed from %zu to %zu sectors\n", rnbd_clt_info(dev, "Device size changed from %zu to %zu sectors\n",
dev->nsectors, new_nsectors); dev->nsectors, new_nsectors);
dev->nsectors = new_nsectors; dev->nsectors = new_nsectors;
set_capacity(dev->gd, dev->nsectors); set_capacity(dev->gd, dev->nsectors);
err = revalidate_disk(dev->gd); revalidate_disk_size(dev->gd, true);
if (err) return 0;
rnbd_clt_err(dev,
"Failed to change device size from %zu to %zu, err: %d\n",
dev->nsectors, new_nsectors, err);
return err;
} }
static int process_msg_open_rsp(struct rnbd_clt_dev *dev, static int process_msg_open_rsp(struct rnbd_clt_dev *dev,
......
...@@ -598,7 +598,7 @@ static void virtblk_update_cache_mode(struct virtio_device *vdev) ...@@ -598,7 +598,7 @@ static void virtblk_update_cache_mode(struct virtio_device *vdev)
struct virtio_blk *vblk = vdev->priv; struct virtio_blk *vblk = vdev->priv;
blk_queue_write_cache(vblk->disk->queue, writeback, false); blk_queue_write_cache(vblk->disk->queue, writeback, false);
revalidate_disk(vblk->disk); revalidate_disk_size(vblk->disk, true);
} }
static const char *const virtblk_cache_types[] = { static const char *const virtblk_cache_types[] = {
......
...@@ -1739,7 +1739,7 @@ static ssize_t disksize_store(struct device *dev, ...@@ -1739,7 +1739,7 @@ static ssize_t disksize_store(struct device *dev,
zram->disksize = disksize; zram->disksize = disksize;
set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT);
revalidate_disk(zram->disk); revalidate_disk_size(zram->disk, true);
up_write(&zram->init_lock); up_write(&zram->init_lock);
return len; return len;
...@@ -1786,7 +1786,7 @@ static ssize_t reset_store(struct device *dev, ...@@ -1786,7 +1786,7 @@ static ssize_t reset_store(struct device *dev,
/* Make sure all the pending I/O are finished */ /* Make sure all the pending I/O are finished */
fsync_bdev(bdev); fsync_bdev(bdev);
zram_reset_device(zram); zram_reset_device(zram);
revalidate_disk(zram->disk); revalidate_disk_size(zram->disk, true);
bdput(bdev); bdput(bdev);
mutex_lock(&bdev->bd_mutex); mutex_lock(&bdev->bd_mutex);
......
...@@ -701,7 +701,7 @@ static void rs_set_capacity(struct raid_set *rs) ...@@ -701,7 +701,7 @@ static void rs_set_capacity(struct raid_set *rs)
struct gendisk *gendisk = dm_disk(dm_table_get_md(rs->ti->table)); struct gendisk *gendisk = dm_disk(dm_table_get_md(rs->ti->table));
set_capacity(gendisk, rs->md.array_sectors); set_capacity(gendisk, rs->md.array_sectors);
revalidate_disk(gendisk); revalidate_disk_size(gendisk, true);
} }
/* /*
......
...@@ -582,7 +582,7 @@ static int process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg) ...@@ -582,7 +582,7 @@ static int process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg)
break; break;
case CHANGE_CAPACITY: case CHANGE_CAPACITY:
set_capacity(mddev->gendisk, mddev->array_sectors); set_capacity(mddev->gendisk, mddev->array_sectors);
revalidate_disk(mddev->gendisk); revalidate_disk_size(mddev->gendisk, true);
break; break;
case RESYNCING: case RESYNCING:
set_bit(MD_RESYNCING_REMOTE, &mddev->recovery); set_bit(MD_RESYNCING_REMOTE, &mddev->recovery);
...@@ -1296,12 +1296,12 @@ static void update_size(struct mddev *mddev, sector_t old_dev_sectors) ...@@ -1296,12 +1296,12 @@ static void update_size(struct mddev *mddev, sector_t old_dev_sectors)
pr_err("%s:%d: failed to send CHANGE_CAPACITY msg\n", pr_err("%s:%d: failed to send CHANGE_CAPACITY msg\n",
__func__, __LINE__); __func__, __LINE__);
set_capacity(mddev->gendisk, mddev->array_sectors); set_capacity(mddev->gendisk, mddev->array_sectors);
revalidate_disk(mddev->gendisk); revalidate_disk_size(mddev->gendisk, true);
} else { } else {
/* revert to previous sectors */ /* revert to previous sectors */
ret = mddev->pers->resize(mddev, old_dev_sectors); ret = mddev->pers->resize(mddev, old_dev_sectors);
if (!ret) if (!ret)
revalidate_disk(mddev->gendisk); revalidate_disk_size(mddev->gendisk, true);
ret = __sendmsg(cinfo, &cmsg); ret = __sendmsg(cinfo, &cmsg);
if (ret) if (ret)
pr_err("%s:%d: failed to send METADATA_UPDATED msg\n", pr_err("%s:%d: failed to send METADATA_UPDATED msg\n",
......
...@@ -202,7 +202,7 @@ static int linear_add(struct mddev *mddev, struct md_rdev *rdev) ...@@ -202,7 +202,7 @@ static int linear_add(struct mddev *mddev, struct md_rdev *rdev)
md_set_array_sectors(mddev, linear_size(mddev, 0, 0)); md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
set_capacity(mddev->gendisk, mddev->array_sectors); set_capacity(mddev->gendisk, mddev->array_sectors);
mddev_resume(mddev); mddev_resume(mddev);
revalidate_disk(mddev->gendisk); revalidate_disk_size(mddev->gendisk, true);
kfree_rcu(oldconf, rcu); kfree_rcu(oldconf, rcu);
return 0; return 0;
} }
......
...@@ -5358,7 +5358,7 @@ array_size_store(struct mddev *mddev, const char *buf, size_t len) ...@@ -5358,7 +5358,7 @@ array_size_store(struct mddev *mddev, const char *buf, size_t len)
mddev->array_sectors = sectors; mddev->array_sectors = sectors;
if (mddev->pers) { if (mddev->pers) {
set_capacity(mddev->gendisk, mddev->array_sectors); set_capacity(mddev->gendisk, mddev->array_sectors);
revalidate_disk(mddev->gendisk); revalidate_disk_size(mddev->gendisk, true);
} }
} }
mddev_unlock(mddev); mddev_unlock(mddev);
...@@ -6109,7 +6109,7 @@ int do_md_run(struct mddev *mddev) ...@@ -6109,7 +6109,7 @@ int do_md_run(struct mddev *mddev)
md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */
set_capacity(mddev->gendisk, mddev->array_sectors); set_capacity(mddev->gendisk, mddev->array_sectors);
revalidate_disk(mddev->gendisk); revalidate_disk_size(mddev->gendisk, true);
clear_bit(MD_NOT_READY, &mddev->flags); clear_bit(MD_NOT_READY, &mddev->flags);
mddev->changed = 1; mddev->changed = 1;
kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE); kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE);
...@@ -6427,7 +6427,7 @@ static int do_md_stop(struct mddev *mddev, int mode, ...@@ -6427,7 +6427,7 @@ static int do_md_stop(struct mddev *mddev, int mode,
set_capacity(disk, 0); set_capacity(disk, 0);
mutex_unlock(&mddev->open_mutex); mutex_unlock(&mddev->open_mutex);
mddev->changed = 1; mddev->changed = 1;
revalidate_disk(disk); revalidate_disk_size(disk, true);
if (mddev->ro) if (mddev->ro)
mddev->ro = 0; mddev->ro = 0;
...@@ -7259,7 +7259,7 @@ static int update_size(struct mddev *mddev, sector_t num_sectors) ...@@ -7259,7 +7259,7 @@ static int update_size(struct mddev *mddev, sector_t num_sectors)
md_cluster_ops->update_size(mddev, old_dev_sectors); md_cluster_ops->update_size(mddev, old_dev_sectors);
else if (mddev->queue) { else if (mddev->queue) {
set_capacity(mddev->gendisk, mddev->array_sectors); set_capacity(mddev->gendisk, mddev->array_sectors);
revalidate_disk(mddev->gendisk); revalidate_disk_size(mddev->gendisk, true);
} }
} }
return rv; return rv;
...@@ -9018,7 +9018,7 @@ void md_do_sync(struct md_thread *thread) ...@@ -9018,7 +9018,7 @@ void md_do_sync(struct md_thread *thread)
mddev_unlock(mddev); mddev_unlock(mddev);
if (!mddev_is_clustered(mddev)) { if (!mddev_is_clustered(mddev)) {
set_capacity(mddev->gendisk, mddev->array_sectors); set_capacity(mddev->gendisk, mddev->array_sectors);
revalidate_disk(mddev->gendisk); revalidate_disk_size(mddev->gendisk, true);
} }
} }
......
...@@ -1311,6 +1311,34 @@ static void check_disk_size_change(struct gendisk *disk, ...@@ -1311,6 +1311,34 @@ static void check_disk_size_change(struct gendisk *disk,
} }
} }
/**
* revalidate_disk_size - checks for disk size change and adjusts bdev size.
* @disk: struct gendisk to check
* @verbose: if %true log a message about a size change if there is any
*
* This routine checks to see if the bdev size does not match the disk size
* and adjusts it if it differs. When shrinking the bdev size, its all caches
* are freed.
*/
void revalidate_disk_size(struct gendisk *disk, bool verbose)
{
struct block_device *bdev;
/*
* Hidden disks don't have associated bdev so there's no point in
* revalidating them.
*/
if (disk->flags & GENHD_FL_HIDDEN)
return;
bdev = bdget_disk(disk, 0);
if (bdev) {
check_disk_size_change(disk, bdev, verbose);
bdput(bdev);
}
}
EXPORT_SYMBOL(revalidate_disk_size);
/** /**
* revalidate_disk - wrapper for lower-level driver's revalidate_disk call-back * revalidate_disk - wrapper for lower-level driver's revalidate_disk call-back
* @disk: struct gendisk to be revalidated * @disk: struct gendisk to be revalidated
...@@ -1325,19 +1353,7 @@ int revalidate_disk(struct gendisk *disk) ...@@ -1325,19 +1353,7 @@ 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);
revalidate_disk_size(disk, ret == 0);
/*
* Hidden disks don't have associated bdev so there's no point in
* revalidating it.
*/
if (!(disk->flags & GENHD_FL_HIDDEN)) {
struct block_device *bdev = bdget_disk(disk, 0);
if (bdev) {
check_disk_size_change(disk, bdev, ret == 0);
bdput(bdev);
}
}
return ret; return ret;
} }
EXPORT_SYMBOL(revalidate_disk); EXPORT_SYMBOL(revalidate_disk);
......
...@@ -371,6 +371,7 @@ int register_blkdev(unsigned int major, const char *name); ...@@ -371,6 +371,7 @@ int register_blkdev(unsigned int major, const char *name);
void unregister_blkdev(unsigned int major, const char *name); void unregister_blkdev(unsigned int major, const char *name);
int revalidate_disk(struct gendisk *disk); int revalidate_disk(struct gendisk *disk);
void revalidate_disk_size(struct gendisk *disk, bool verbose);
int check_disk_change(struct block_device *bdev); int check_disk_change(struct block_device *bdev);
int __invalidate_device(struct block_device *bdev, bool kill_dirty); int __invalidate_device(struct block_device *bdev, bool kill_dirty);
void bd_set_nr_sectors(struct block_device *bdev, sector_t sectors); void bd_set_nr_sectors(struct block_device *bdev, sector_t sectors);
......
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