From 3fef7d561ee71307945f7e31980581eec93da55c Mon Sep 17 00:00:00 2001 From: Andrew Patterson Date: Thu, 4 Sep 2008 14:27:25 -0600 Subject: [PATCH] --- yaml --- r: 110519 b: refs/heads/master c: c3279d1454cdfed02a557d789d8a6d08ab4cbe70 h: refs/heads/master i: 110517: 5f865251cf541db5ec0d6606e7bf8a05cc1632f6 110515: 744ed94d86977a8e29abe02fed212d9f272216ae 110511: da5a10c74efa5026efcb2192e021166320335f91 v: v3 --- [refs] | 2 +- trunk/fs/block_dev.c | 37 +++++++++++++++++++++++++++++++++++++ trunk/include/linux/fs.h | 2 ++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 736e44a71258..49897873a9c6 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 0c002c2f74e10baa9021d3ecc50585c6eafea568 +refs/heads/master: c3279d1454cdfed02a557d789d8a6d08ab4cbe70 diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index 4eeb69a88734..b721955d382e 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -852,6 +852,34 @@ struct block_device *open_by_devnum(dev_t dev, unsigned mode) EXPORT_SYMBOL(open_by_devnum); +/** + * check_disk_size_change - checks for disk size change and adjusts + * bdev size. + * + * @disk: struct gendisk to check + * @bdev: struct bdev to adjust. + * + * This routine checks to see if the bdev size does not match the disk size + * and adjusts it if it differs. + */ +void check_disk_size_change(struct gendisk *disk, struct block_device *bdev) +{ + loff_t disk_size, bdev_size; + + disk_size = (loff_t)get_capacity(disk) << 9; + bdev_size = i_size_read(bdev->bd_inode); + if (disk_size != bdev_size) { + char name[BDEVNAME_SIZE]; + + disk_name(disk, 0, name); + printk(KERN_INFO + "%s: detected capacity change from %lld to %lld\n", + name, bdev_size, disk_size); + i_size_write(bdev->bd_inode, disk_size); + } +} +EXPORT_SYMBOL(check_disk_size_change); + /** * revalidate_disk - wrapper for lower-level driver's revalidate_disk * call-back @@ -864,11 +892,20 @@ EXPORT_SYMBOL(open_by_devnum); */ int revalidate_disk(struct gendisk *disk) { + struct block_device *bdev; int ret = 0; if (disk->fops->revalidate_disk) ret = disk->fops->revalidate_disk(disk); + bdev = bdget_disk(disk, 0); + if (!bdev) + return ret; + + mutex_lock(&bdev->bd_mutex); + check_disk_size_change(disk, bdev); + mutex_unlock(&bdev->bd_mutex); + bdput(bdev); return ret; } EXPORT_SYMBOL(revalidate_disk); diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index d63461f97983..32477e8872d5 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -1722,6 +1722,8 @@ extern int fs_may_remount_ro(struct super_block *); */ #define bio_data_dir(bio) ((bio)->bi_rw & 1) +extern void check_disk_size_change(struct gendisk *disk, + struct block_device *bdev); extern int revalidate_disk(struct gendisk *); extern int check_disk_change(struct block_device *); extern int __invalidate_device(struct block_device *);