]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.drivers/bdev-resize-adjust-block-device-size
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / bdev-resize-adjust-block-device-size
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
6
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.
11
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>
15 ---
16 fs/block_dev.c | 37 +++++++++++++++++++++++++++++++++++++
17 include/linux/fs.h | 2 ++
18 2 files changed, 39 insertions(+)
19
20 --- a/fs/block_dev.c
21 +++ b/fs/block_dev.c
22 @@ -869,6 +869,34 @@ struct block_device *open_by_devnum(dev_
23 EXPORT_SYMBOL(open_by_devnum);
24
25 /**
26 + * check_disk_size_change - checks for disk size change and adjusts
27 + * bdev size.
28 + *
29 + * @disk: struct gendisk to check
30 + * @bdev: struct bdev to adjust.
31 + *
32 + * This routine checks to see if the bdev size does not match the disk size
33 + * and adjusts it if it differs.
34 + */
35 +void check_disk_size_change(struct gendisk *disk, struct block_device *bdev)
36 +{
37 + loff_t disk_size, bdev_size;
38 +
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];
43 +
44 + disk_name(disk, 0, name);
45 + printk(KERN_INFO
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);
49 + }
50 +}
51 +EXPORT_SYMBOL(check_disk_size_change);
52 +
53 +/**
54 * revalidate_disk - wrapper for lower-level driver's revalidate_disk
55 * call-back
56 *
57 @@ -880,11 +908,20 @@ EXPORT_SYMBOL(open_by_devnum);
58 */
59 int revalidate_disk(struct gendisk *disk)
60 {
61 + struct block_device *bdev;
62 int ret = 0;
63
64 if (disk->fops->revalidate_disk)
65 ret = disk->fops->revalidate_disk(disk);
66
67 + bdev = bdget_disk(disk, 0);
68 + if (!bdev)
69 + return ret;
70 +
71 + mutex_lock(&bdev->bd_mutex);
72 + check_disk_size_change(disk, bdev);
73 + mutex_unlock(&bdev->bd_mutex);
74 + bdput(bdev);
75 return ret;
76 }
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
81 */
82 #define bio_data_dir(bio) ((bio)->bi_rw & 1)
83
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 *);