diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-06-14 08:59:06 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-06-14 08:59:06 +0200 |
commit | db4e54aefdfe03f1aea82bb65d61f25c3ea035d7 (patch) | |
tree | 1a4b30dc2b6c8ac3173ff686b36f49dee5f0bd73 /drivers/block | |
parent | eab61fb1cc2eeeffbceb2cf891c1b7272141af82 (diff) | |
parent | 009c9aa5be652675a06d5211e1640e02bbb1c33d (diff) |
Merge tag 'v5.13-rc6' into char-misc-next
We need the fixes in here as well.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/loop.c | 25 | ||||
-rw-r--r-- | drivers/block/loop.h | 1 |
2 files changed, 8 insertions, 18 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index d58d68f3c7cd..76e12f3482a9 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1879,29 +1879,18 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode, static int lo_open(struct block_device *bdev, fmode_t mode) { - struct loop_device *lo; + struct loop_device *lo = bdev->bd_disk->private_data; int err; - /* - * take loop_ctl_mutex to protect lo pointer from race with - * loop_control_ioctl(LOOP_CTL_REMOVE), however, to reduce contention - * release it prior to updating lo->lo_refcnt. - */ - err = mutex_lock_killable(&loop_ctl_mutex); - if (err) - return err; - lo = bdev->bd_disk->private_data; - if (!lo) { - mutex_unlock(&loop_ctl_mutex); - return -ENXIO; - } err = mutex_lock_killable(&lo->lo_mutex); - mutex_unlock(&loop_ctl_mutex); if (err) return err; - atomic_inc(&lo->lo_refcnt); + if (lo->lo_state == Lo_deleting) + err = -ENXIO; + else + atomic_inc(&lo->lo_refcnt); mutex_unlock(&lo->lo_mutex); - return 0; + return err; } static void lo_release(struct gendisk *disk, fmode_t mode) @@ -2285,7 +2274,7 @@ static long loop_control_ioctl(struct file *file, unsigned int cmd, mutex_unlock(&lo->lo_mutex); break; } - lo->lo_disk->private_data = NULL; + lo->lo_state = Lo_deleting; mutex_unlock(&lo->lo_mutex); idr_remove(&loop_index_idr, lo->lo_number); loop_remove(lo); diff --git a/drivers/block/loop.h b/drivers/block/loop.h index a3c04f310672..5beb959b94d3 100644 --- a/drivers/block/loop.h +++ b/drivers/block/loop.h @@ -22,6 +22,7 @@ enum { Lo_unbound, Lo_bound, Lo_rundown, + Lo_deleting, }; struct loop_func_table; |