aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r--drivers/block/loop.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 2ebacf0..38f8da9 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -928,6 +928,11 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
wake_up_process(lo->lo_thread);
if (max_part > 0)
ioctl_by_bdev(bdev, BLKRRPART, 0);
+
+ /* Grab the block_device to prevent its destruction after we
+ * put /dev/loopXX inode. Later in loop_clr_fd() we bdput(bdev).
+ */
+ bdgrab(bdev);
return 0;
out_clr:
@@ -1024,8 +1029,10 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
memset(lo->lo_file_name, 0, LO_NAME_SIZE);
- if (bdev)
+ if (bdev) {
+ bdput(bdev);
invalidate_bdev(bdev);
+ }
set_capacity(lo->lo_disk, 0);
loop_sysfs_exit(lo);
if (bdev) {
@@ -1274,11 +1281,9 @@ static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev)
/* the width of sector_t may be narrow for bit-shift */
sz = sec;
sz <<= 9;
- mutex_lock(&bdev->bd_mutex);
bd_set_size(bdev, sz);
/* let user-space know about the new size */
kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);
- mutex_unlock(&bdev->bd_mutex);
out:
return err;