diff options
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r-- | fs/block_dev.c | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index 889287019599..5147bdd3b8e1 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -55,11 +55,13 @@ EXPORT_SYMBOL(I_BDEV); | |||
55 | static void bdev_inode_switch_bdi(struct inode *inode, | 55 | static void bdev_inode_switch_bdi(struct inode *inode, |
56 | struct backing_dev_info *dst) | 56 | struct backing_dev_info *dst) |
57 | { | 57 | { |
58 | spin_lock(&inode_lock); | 58 | spin_lock(&inode_wb_list_lock); |
59 | spin_lock(&inode->i_lock); | ||
59 | inode->i_data.backing_dev_info = dst; | 60 | inode->i_data.backing_dev_info = dst; |
60 | if (inode->i_state & I_DIRTY) | 61 | if (inode->i_state & I_DIRTY) |
61 | list_move(&inode->i_wb_list, &dst->wb.b_dirty); | 62 | list_move(&inode->i_wb_list, &dst->wb.b_dirty); |
62 | spin_unlock(&inode_lock); | 63 | spin_unlock(&inode->i_lock); |
64 | spin_unlock(&inode_wb_list_lock); | ||
63 | } | 65 | } |
64 | 66 | ||
65 | static sector_t max_block(struct block_device *bdev) | 67 | static sector_t max_block(struct block_device *bdev) |
@@ -651,7 +653,7 @@ void bd_forget(struct inode *inode) | |||
651 | * @whole: whole block device containing @bdev, may equal @bdev | 653 | * @whole: whole block device containing @bdev, may equal @bdev |
652 | * @holder: holder trying to claim @bdev | 654 | * @holder: holder trying to claim @bdev |
653 | * | 655 | * |
654 | * Test whther @bdev can be claimed by @holder. | 656 | * Test whether @bdev can be claimed by @holder. |
655 | * | 657 | * |
656 | * CONTEXT: | 658 | * CONTEXT: |
657 | * spin_lock(&bdev_lock). | 659 | * spin_lock(&bdev_lock). |
@@ -1087,6 +1089,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
1087 | if (!disk) | 1089 | if (!disk) |
1088 | goto out; | 1090 | goto out; |
1089 | 1091 | ||
1092 | disk_block_events(disk); | ||
1090 | mutex_lock_nested(&bdev->bd_mutex, for_part); | 1093 | mutex_lock_nested(&bdev->bd_mutex, for_part); |
1091 | if (!bdev->bd_openers) { | 1094 | if (!bdev->bd_openers) { |
1092 | bdev->bd_disk = disk; | 1095 | bdev->bd_disk = disk; |
@@ -1108,10 +1111,11 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
1108 | */ | 1111 | */ |
1109 | disk_put_part(bdev->bd_part); | 1112 | disk_put_part(bdev->bd_part); |
1110 | bdev->bd_part = NULL; | 1113 | bdev->bd_part = NULL; |
1111 | module_put(disk->fops->owner); | ||
1112 | put_disk(disk); | ||
1113 | bdev->bd_disk = NULL; | 1114 | bdev->bd_disk = NULL; |
1114 | mutex_unlock(&bdev->bd_mutex); | 1115 | mutex_unlock(&bdev->bd_mutex); |
1116 | disk_unblock_events(disk); | ||
1117 | module_put(disk->fops->owner); | ||
1118 | put_disk(disk); | ||
1115 | goto restart; | 1119 | goto restart; |
1116 | } | 1120 | } |
1117 | if (ret) | 1121 | if (ret) |
@@ -1148,9 +1152,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
1148 | bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9); | 1152 | bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9); |
1149 | } | 1153 | } |
1150 | } else { | 1154 | } else { |
1151 | module_put(disk->fops->owner); | ||
1152 | put_disk(disk); | ||
1153 | disk = NULL; | ||
1154 | if (bdev->bd_contains == bdev) { | 1155 | if (bdev->bd_contains == bdev) { |
1155 | if (bdev->bd_disk->fops->open) { | 1156 | if (bdev->bd_disk->fops->open) { |
1156 | ret = bdev->bd_disk->fops->open(bdev, mode); | 1157 | ret = bdev->bd_disk->fops->open(bdev, mode); |
@@ -1160,11 +1161,15 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
1160 | if (bdev->bd_invalidated) | 1161 | if (bdev->bd_invalidated) |
1161 | rescan_partitions(bdev->bd_disk, bdev); | 1162 | rescan_partitions(bdev->bd_disk, bdev); |
1162 | } | 1163 | } |
1164 | /* only one opener holds refs to the module and disk */ | ||
1165 | module_put(disk->fops->owner); | ||
1166 | put_disk(disk); | ||
1163 | } | 1167 | } |
1164 | bdev->bd_openers++; | 1168 | bdev->bd_openers++; |
1165 | if (for_part) | 1169 | if (for_part) |
1166 | bdev->bd_part_count++; | 1170 | bdev->bd_part_count++; |
1167 | mutex_unlock(&bdev->bd_mutex); | 1171 | mutex_unlock(&bdev->bd_mutex); |
1172 | disk_unblock_events(disk); | ||
1168 | return 0; | 1173 | return 0; |
1169 | 1174 | ||
1170 | out_clear: | 1175 | out_clear: |
@@ -1177,10 +1182,10 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
1177 | bdev->bd_contains = NULL; | 1182 | bdev->bd_contains = NULL; |
1178 | out_unlock_bdev: | 1183 | out_unlock_bdev: |
1179 | mutex_unlock(&bdev->bd_mutex); | 1184 | mutex_unlock(&bdev->bd_mutex); |
1180 | out: | 1185 | disk_unblock_events(disk); |
1181 | if (disk) | 1186 | module_put(disk->fops->owner); |
1182 | module_put(disk->fops->owner); | ||
1183 | put_disk(disk); | 1187 | put_disk(disk); |
1188 | out: | ||
1184 | bdput(bdev); | 1189 | bdput(bdev); |
1185 | 1190 | ||
1186 | return ret; | 1191 | return ret; |
@@ -1446,14 +1451,13 @@ int blkdev_put(struct block_device *bdev, fmode_t mode) | |||
1446 | if (bdev_free) { | 1451 | if (bdev_free) { |
1447 | if (bdev->bd_write_holder) { | 1452 | if (bdev->bd_write_holder) { |
1448 | disk_unblock_events(bdev->bd_disk); | 1453 | disk_unblock_events(bdev->bd_disk); |
1449 | bdev->bd_write_holder = false; | ||
1450 | } else | ||
1451 | disk_check_events(bdev->bd_disk); | 1454 | disk_check_events(bdev->bd_disk); |
1455 | bdev->bd_write_holder = false; | ||
1456 | } | ||
1452 | } | 1457 | } |
1453 | 1458 | ||
1454 | mutex_unlock(&bdev->bd_mutex); | 1459 | mutex_unlock(&bdev->bd_mutex); |
1455 | } else | 1460 | } |
1456 | disk_check_events(bdev->bd_disk); | ||
1457 | 1461 | ||
1458 | return __blkdev_put(bdev, mode, 0); | 1462 | return __blkdev_put(bdev, mode, 0); |
1459 | } | 1463 | } |
@@ -1527,7 +1531,6 @@ static int blkdev_releasepage(struct page *page, gfp_t wait) | |||
1527 | static const struct address_space_operations def_blk_aops = { | 1531 | static const struct address_space_operations def_blk_aops = { |
1528 | .readpage = blkdev_readpage, | 1532 | .readpage = blkdev_readpage, |
1529 | .writepage = blkdev_writepage, | 1533 | .writepage = blkdev_writepage, |
1530 | .sync_page = block_sync_page, | ||
1531 | .write_begin = blkdev_write_begin, | 1534 | .write_begin = blkdev_write_begin, |
1532 | .write_end = blkdev_write_end, | 1535 | .write_end = blkdev_write_end, |
1533 | .writepages = generic_writepages, | 1536 | .writepages = generic_writepages, |