aboutsummaryrefslogtreecommitdiffstats
path: root/fs/block_dev.c
diff options
context:
space:
mode:
authorAndrew Patterson <andrew.patterson@hp.com>2008-09-04 16:27:25 -0400
committerJens Axboe <jens.axboe@oracle.com>2008-10-09 02:56:12 -0400
commitc3279d1454cdfed02a557d789d8a6d08ab4cbe70 (patch)
tree2591c7c0886f9b6b63aa40e3ef3caa984370c38b /fs/block_dev.c
parent0c002c2f74e10baa9021d3ecc50585c6eafea568 (diff)
Adjust block device size after an online resize of a disk.
The revalidate_disk routine now checks if a disk has been resized by comparing the gendisk capacity to the bdev inode size. If they are different (usually because the disk has been resized underneath the kernel) the bdev inode size is adjusted to match the capacity. Signed-off-by: Andrew Patterson <andrew.patterson@hp.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r--fs/block_dev.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 4eeb69a88734..b721955d382e 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -853,6 +853,34 @@ struct block_device *open_by_devnum(dev_t dev, unsigned mode)
853EXPORT_SYMBOL(open_by_devnum); 853EXPORT_SYMBOL(open_by_devnum);
854 854
855/** 855/**
856 * check_disk_size_change - checks for disk size change and adjusts
857 * bdev size.
858 *
859 * @disk: struct gendisk to check
860 * @bdev: struct bdev to adjust.
861 *
862 * This routine checks to see if the bdev size does not match the disk size
863 * and adjusts it if it differs.
864 */
865void check_disk_size_change(struct gendisk *disk, struct block_device *bdev)
866{
867 loff_t disk_size, bdev_size;
868
869 disk_size = (loff_t)get_capacity(disk) << 9;
870 bdev_size = i_size_read(bdev->bd_inode);
871 if (disk_size != bdev_size) {
872 char name[BDEVNAME_SIZE];
873
874 disk_name(disk, 0, name);
875 printk(KERN_INFO
876 "%s: detected capacity change from %lld to %lld\n",
877 name, bdev_size, disk_size);
878 i_size_write(bdev->bd_inode, disk_size);
879 }
880}
881EXPORT_SYMBOL(check_disk_size_change);
882
883/**
856 * revalidate_disk - wrapper for lower-level driver's revalidate_disk 884 * revalidate_disk - wrapper for lower-level driver's revalidate_disk
857 * call-back 885 * call-back
858 * 886 *
@@ -864,11 +892,20 @@ EXPORT_SYMBOL(open_by_devnum);
864 */ 892 */
865int revalidate_disk(struct gendisk *disk) 893int revalidate_disk(struct gendisk *disk)
866{ 894{
895 struct block_device *bdev;
867 int ret = 0; 896 int ret = 0;
868 897
869 if (disk->fops->revalidate_disk) 898 if (disk->fops->revalidate_disk)
870 ret = disk->fops->revalidate_disk(disk); 899 ret = disk->fops->revalidate_disk(disk);
871 900
901 bdev = bdget_disk(disk, 0);
902 if (!bdev)
903 return ret;
904
905 mutex_lock(&bdev->bd_mutex);
906 check_disk_size_change(disk, bdev);
907 mutex_unlock(&bdev->bd_mutex);
908 bdput(bdev);
872 return ret; 909 return ret;
873} 910}
874EXPORT_SYMBOL(revalidate_disk); 911EXPORT_SYMBOL(revalidate_disk);