diff options
| -rw-r--r-- | drivers/block/loop.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 102d79575895..f11b7dc16e9d 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
| @@ -945,9 +945,20 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, | |||
| 945 | if (!file) | 945 | if (!file) |
| 946 | goto out; | 946 | goto out; |
| 947 | 947 | ||
| 948 | /* | ||
| 949 | * If we don't hold exclusive handle for the device, upgrade to it | ||
| 950 | * here to avoid changing device under exclusive owner. | ||
| 951 | */ | ||
| 952 | if (!(mode & FMODE_EXCL)) { | ||
| 953 | bdgrab(bdev); | ||
| 954 | error = blkdev_get(bdev, mode | FMODE_EXCL, loop_set_fd); | ||
| 955 | if (error) | ||
| 956 | goto out_putf; | ||
| 957 | } | ||
| 958 | |||
| 948 | error = mutex_lock_killable(&loop_ctl_mutex); | 959 | error = mutex_lock_killable(&loop_ctl_mutex); |
| 949 | if (error) | 960 | if (error) |
| 950 | goto out_putf; | 961 | goto out_bdev; |
| 951 | 962 | ||
| 952 | error = -EBUSY; | 963 | error = -EBUSY; |
| 953 | if (lo->lo_state != Lo_unbound) | 964 | if (lo->lo_state != Lo_unbound) |
| @@ -1012,10 +1023,15 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, | |||
| 1012 | mutex_unlock(&loop_ctl_mutex); | 1023 | mutex_unlock(&loop_ctl_mutex); |
| 1013 | if (partscan) | 1024 | if (partscan) |
| 1014 | loop_reread_partitions(lo, bdev); | 1025 | loop_reread_partitions(lo, bdev); |
| 1026 | if (!(mode & FMODE_EXCL)) | ||
| 1027 | blkdev_put(bdev, mode | FMODE_EXCL); | ||
| 1015 | return 0; | 1028 | return 0; |
| 1016 | 1029 | ||
| 1017 | out_unlock: | 1030 | out_unlock: |
| 1018 | mutex_unlock(&loop_ctl_mutex); | 1031 | mutex_unlock(&loop_ctl_mutex); |
| 1032 | out_bdev: | ||
| 1033 | if (!(mode & FMODE_EXCL)) | ||
| 1034 | blkdev_put(bdev, mode | FMODE_EXCL); | ||
| 1019 | out_putf: | 1035 | out_putf: |
| 1020 | fput(file); | 1036 | fput(file); |
| 1021 | out: | 1037 | out: |
