1 Subject: Adjust block device size after an online resize of a disk.
2 From: Andrew Patterson <andrew.patterson@hp.com>
3 Date: Thu Oct 9 08:56:12 2008 +0200:
4 Git: c3279d1454cdfed02a557d789d8a6d08ab4cbe70
5 References: FATE#302348,FATE#303786
7 The revalidate_disk routine now checks if a disk has been resized by
8 comparing the gendisk capacity to the bdev inode size. If they are
9 different (usually because the disk has been resized underneath the kernel)
10 the bdev inode size is adjusted to match the capacity.
12 Signed-off-by: Andrew Patterson <andrew.patterson@hp.com>
13 Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
14 Signed-off-by: Hannes Reinecke <hare@suse.de>
16 fs/block_dev.c | 37 +++++++++++++++++++++++++++++++++++++
17 include/linux/fs.h | 2 ++
18 2 files changed, 39 insertions(+)
22 @@ -869,6 +869,34 @@ struct block_device *open_by_devnum(dev_
23 EXPORT_SYMBOL(open_by_devnum);
26 + * check_disk_size_change - checks for disk size change and adjusts
29 + * @disk: struct gendisk to check
30 + * @bdev: struct bdev to adjust.
32 + * This routine checks to see if the bdev size does not match the disk size
33 + * and adjusts it if it differs.
35 +void check_disk_size_change(struct gendisk *disk, struct block_device *bdev)
37 + loff_t disk_size, bdev_size;
39 + disk_size = (loff_t)get_capacity(disk) << 9;
40 + bdev_size = i_size_read(bdev->bd_inode);
41 + if (disk_size != bdev_size) {
42 + char name[BDEVNAME_SIZE];
44 + disk_name(disk, 0, name);
46 + "%s: detected capacity change from %lld to %lld\n",
47 + name, bdev_size, disk_size);
48 + i_size_write(bdev->bd_inode, disk_size);
51 +EXPORT_SYMBOL(check_disk_size_change);
54 * revalidate_disk - wrapper for lower-level driver's revalidate_disk
57 @@ -880,11 +908,20 @@ EXPORT_SYMBOL(open_by_devnum);
59 int revalidate_disk(struct gendisk *disk)
61 + struct block_device *bdev;
64 if (disk->fops->revalidate_disk)
65 ret = disk->fops->revalidate_disk(disk);
67 + bdev = bdget_disk(disk, 0);
71 + mutex_lock(&bdev->bd_mutex);
72 + check_disk_size_change(disk, bdev);
73 + mutex_unlock(&bdev->bd_mutex);
77 EXPORT_SYMBOL(revalidate_disk);
78 --- a/include/linux/fs.h
79 +++ b/include/linux/fs.h
80 @@ -1742,6 +1742,8 @@ extern int fs_may_remount_ro(struct supe
82 #define bio_data_dir(bio) ((bio)->bi_rw & 1)
84 +extern void check_disk_size_change(struct gendisk *disk,
85 + struct block_device *bdev);
86 extern int revalidate_disk(struct gendisk *);
87 extern int check_disk_change(struct block_device *);
88 extern int __invalidate_device(struct block_device *);