aboutsummaryrefslogtreecommitdiffstats
path: root/fs/block_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r--fs/block_dev.c35
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);
55static void bdev_inode_switch_bdi(struct inode *inode, 55static 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
65static sector_t max_block(struct block_device *bdev) 67static 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)
1527static const struct address_space_operations def_blk_aops = { 1531static 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,