diff options
-rw-r--r-- | block/genhd.c | 8 | ||||
-rw-r--r-- | fs/block_dev.c | 13 |
2 files changed, 16 insertions, 5 deletions
diff --git a/block/genhd.c b/block/genhd.c index e2f67902dd02..d261b73b9744 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -611,6 +611,12 @@ void add_disk(struct gendisk *disk) | |||
611 | register_disk(disk); | 611 | register_disk(disk); |
612 | blk_register_queue(disk); | 612 | blk_register_queue(disk); |
613 | 613 | ||
614 | /* | ||
615 | * Take an extra ref on queue which will be put on disk_release() | ||
616 | * so that it sticks around as long as @disk is there. | ||
617 | */ | ||
618 | WARN_ON_ONCE(blk_get_queue(disk->queue)); | ||
619 | |||
614 | retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj, | 620 | retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj, |
615 | "bdi"); | 621 | "bdi"); |
616 | WARN_ON(retval); | 622 | WARN_ON(retval); |
@@ -1095,6 +1101,8 @@ static void disk_release(struct device *dev) | |||
1095 | disk_replace_part_tbl(disk, NULL); | 1101 | disk_replace_part_tbl(disk, NULL); |
1096 | free_part_stats(&disk->part0); | 1102 | free_part_stats(&disk->part0); |
1097 | free_part_info(&disk->part0); | 1103 | free_part_info(&disk->part0); |
1104 | if (disk->queue) | ||
1105 | blk_put_queue(disk->queue); | ||
1098 | kfree(disk); | 1106 | kfree(disk); |
1099 | } | 1107 | } |
1100 | struct class block_class = { | 1108 | struct class block_class = { |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 95f786ec7f08..1c44b8d54504 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -1085,6 +1085,7 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part); | |||
1085 | static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | 1085 | static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) |
1086 | { | 1086 | { |
1087 | struct gendisk *disk; | 1087 | struct gendisk *disk; |
1088 | struct module *owner; | ||
1088 | int ret; | 1089 | int ret; |
1089 | int partno; | 1090 | int partno; |
1090 | int perm = 0; | 1091 | int perm = 0; |
@@ -1110,6 +1111,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
1110 | disk = get_gendisk(bdev->bd_dev, &partno); | 1111 | disk = get_gendisk(bdev->bd_dev, &partno); |
1111 | if (!disk) | 1112 | if (!disk) |
1112 | goto out; | 1113 | goto out; |
1114 | owner = disk->fops->owner; | ||
1113 | 1115 | ||
1114 | disk_block_events(disk); | 1116 | disk_block_events(disk); |
1115 | mutex_lock_nested(&bdev->bd_mutex, for_part); | 1117 | mutex_lock_nested(&bdev->bd_mutex, for_part); |
@@ -1137,8 +1139,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
1137 | bdev->bd_disk = NULL; | 1139 | bdev->bd_disk = NULL; |
1138 | mutex_unlock(&bdev->bd_mutex); | 1140 | mutex_unlock(&bdev->bd_mutex); |
1139 | disk_unblock_events(disk); | 1141 | disk_unblock_events(disk); |
1140 | module_put(disk->fops->owner); | ||
1141 | put_disk(disk); | 1142 | put_disk(disk); |
1143 | module_put(owner); | ||
1142 | goto restart; | 1144 | goto restart; |
1143 | } | 1145 | } |
1144 | } | 1146 | } |
@@ -1194,8 +1196,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
1194 | goto out_unlock_bdev; | 1196 | goto out_unlock_bdev; |
1195 | } | 1197 | } |
1196 | /* only one opener holds refs to the module and disk */ | 1198 | /* only one opener holds refs to the module and disk */ |
1197 | module_put(disk->fops->owner); | ||
1198 | put_disk(disk); | 1199 | put_disk(disk); |
1200 | module_put(owner); | ||
1199 | } | 1201 | } |
1200 | bdev->bd_openers++; | 1202 | bdev->bd_openers++; |
1201 | if (for_part) | 1203 | if (for_part) |
@@ -1215,8 +1217,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
1215 | out_unlock_bdev: | 1217 | out_unlock_bdev: |
1216 | mutex_unlock(&bdev->bd_mutex); | 1218 | mutex_unlock(&bdev->bd_mutex); |
1217 | disk_unblock_events(disk); | 1219 | disk_unblock_events(disk); |
1218 | module_put(disk->fops->owner); | ||
1219 | put_disk(disk); | 1220 | put_disk(disk); |
1221 | module_put(owner); | ||
1220 | out: | 1222 | out: |
1221 | bdput(bdev); | 1223 | bdput(bdev); |
1222 | 1224 | ||
@@ -1442,14 +1444,15 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) | |||
1442 | if (!bdev->bd_openers) { | 1444 | if (!bdev->bd_openers) { |
1443 | struct module *owner = disk->fops->owner; | 1445 | struct module *owner = disk->fops->owner; |
1444 | 1446 | ||
1445 | put_disk(disk); | ||
1446 | module_put(owner); | ||
1447 | disk_put_part(bdev->bd_part); | 1447 | disk_put_part(bdev->bd_part); |
1448 | bdev->bd_part = NULL; | 1448 | bdev->bd_part = NULL; |
1449 | bdev->bd_disk = NULL; | 1449 | bdev->bd_disk = NULL; |
1450 | if (bdev != bdev->bd_contains) | 1450 | if (bdev != bdev->bd_contains) |
1451 | victim = bdev->bd_contains; | 1451 | victim = bdev->bd_contains; |
1452 | bdev->bd_contains = NULL; | 1452 | bdev->bd_contains = NULL; |
1453 | |||
1454 | put_disk(disk); | ||
1455 | module_put(owner); | ||
1453 | } | 1456 | } |
1454 | mutex_unlock(&bdev->bd_mutex); | 1457 | mutex_unlock(&bdev->bd_mutex); |
1455 | bdput(bdev); | 1458 | bdput(bdev); |