|
@@ -48,6 +48,21 @@ inline struct block_device *I_BDEV(struct inode *inode)
|
|
|
|
|
|
EXPORT_SYMBOL(I_BDEV);
|
|
EXPORT_SYMBOL(I_BDEV);
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * move the inode from it's current bdi to the a new bdi. if the inode is dirty
|
|
|
|
+ * we need to move it onto the dirty list of @dst so that the inode is always
|
|
|
|
+ * on the right list.
|
|
|
|
+ */
|
|
|
|
+static void bdev_inode_switch_bdi(struct inode *inode,
|
|
|
|
+ struct backing_dev_info *dst)
|
|
|
|
+{
|
|
|
|
+ spin_lock(&inode_lock);
|
|
|
|
+ inode->i_data.backing_dev_info = dst;
|
|
|
|
+ if (inode->i_state & I_DIRTY)
|
|
|
|
+ list_move(&inode->i_list, &dst->wb.b_dirty);
|
|
|
|
+ spin_unlock(&inode_lock);
|
|
|
|
+}
|
|
|
|
+
|
|
static sector_t max_block(struct block_device *bdev)
|
|
static sector_t max_block(struct block_device *bdev)
|
|
{
|
|
{
|
|
sector_t retval = ~((sector_t)0);
|
|
sector_t retval = ~((sector_t)0);
|
|
@@ -1390,7 +1405,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
|
|
bdi = blk_get_backing_dev_info(bdev);
|
|
bdi = blk_get_backing_dev_info(bdev);
|
|
if (bdi == NULL)
|
|
if (bdi == NULL)
|
|
bdi = &default_backing_dev_info;
|
|
bdi = &default_backing_dev_info;
|
|
- bdev->bd_inode->i_data.backing_dev_info = bdi;
|
|
|
|
|
|
+ bdev_inode_switch_bdi(bdev->bd_inode, bdi);
|
|
}
|
|
}
|
|
if (bdev->bd_invalidated)
|
|
if (bdev->bd_invalidated)
|
|
rescan_partitions(disk, bdev);
|
|
rescan_partitions(disk, bdev);
|
|
@@ -1405,8 +1420,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
|
|
if (ret)
|
|
if (ret)
|
|
goto out_clear;
|
|
goto out_clear;
|
|
bdev->bd_contains = whole;
|
|
bdev->bd_contains = whole;
|
|
- bdev->bd_inode->i_data.backing_dev_info =
|
|
|
|
- whole->bd_inode->i_data.backing_dev_info;
|
|
|
|
|
|
+ bdev_inode_switch_bdi(bdev->bd_inode,
|
|
|
|
+ whole->bd_inode->i_data.backing_dev_info);
|
|
bdev->bd_part = disk_get_part(disk, partno);
|
|
bdev->bd_part = disk_get_part(disk, partno);
|
|
if (!(disk->flags & GENHD_FL_UP) ||
|
|
if (!(disk->flags & GENHD_FL_UP) ||
|
|
!bdev->bd_part || !bdev->bd_part->nr_sects) {
|
|
!bdev->bd_part || !bdev->bd_part->nr_sects) {
|
|
@@ -1439,7 +1454,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
|
|
disk_put_part(bdev->bd_part);
|
|
disk_put_part(bdev->bd_part);
|
|
bdev->bd_disk = NULL;
|
|
bdev->bd_disk = NULL;
|
|
bdev->bd_part = NULL;
|
|
bdev->bd_part = NULL;
|
|
- bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
|
|
|
|
|
|
+ bdev_inode_switch_bdi(bdev->bd_inode, &default_backing_dev_info);
|
|
if (bdev != bdev->bd_contains)
|
|
if (bdev != bdev->bd_contains)
|
|
__blkdev_put(bdev->bd_contains, mode, 1);
|
|
__blkdev_put(bdev->bd_contains, mode, 1);
|
|
bdev->bd_contains = NULL;
|
|
bdev->bd_contains = NULL;
|
|
@@ -1533,7 +1548,8 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
|
|
disk_put_part(bdev->bd_part);
|
|
disk_put_part(bdev->bd_part);
|
|
bdev->bd_part = NULL;
|
|
bdev->bd_part = NULL;
|
|
bdev->bd_disk = NULL;
|
|
bdev->bd_disk = NULL;
|
|
- bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
|
|
|
|
|
|
+ bdev_inode_switch_bdi(bdev->bd_inode,
|
|
|
|
+ &default_backing_dev_info);
|
|
if (bdev != bdev->bd_contains)
|
|
if (bdev != bdev->bd_contains)
|
|
victim = bdev->bd_contains;
|
|
victim = bdev->bd_contains;
|
|
bdev->bd_contains = NULL;
|
|
bdev->bd_contains = NULL;
|