Skip to content

Commit

Permalink
Adjust block device size after an online resize of a disk.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Andrew Patterson authored and Jens Axboe committed Oct 9, 2008
1 parent 0c002c2 commit c3279d1
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
37 changes: 37 additions & 0 deletions fs/block_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down

0 comments on commit c3279d1

Please sign in to comment.