diff options
author | Christoph Hellwig <hch@lst.de> | 2021-06-23 17:59:05 +0300 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2021-07-01 00:34:13 +0300 |
commit | 18d1f200b3807c383d80cc00d6bbdee288e63b1f (patch) | |
tree | 38c44b5cc9c92a201f92489d1f273a4d477627d4 /drivers/block | |
parent | f9d107644aa4943b383986a8aa36125379eeaa81 (diff) | |
download | linux-18d1f200b3807c383d80cc00d6bbdee288e63b1f.tar.xz |
loop: move loop_ctl_mutex locking into loop_add
Move acquiring and releasing loop_ctl_mutex from the callers into
loop_add.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
Link: https://lore.kernel.org/r/20210623145908.92973-7-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/loop.c | 37 |
1 files changed, 13 insertions, 24 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index c3c6cfdcaf34..c18e2930ca11 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -2247,9 +2247,12 @@ static int loop_add(int i) lo = kzalloc(sizeof(*lo), GFP_KERNEL); if (!lo) goto out; - lo->lo_state = Lo_unbound; + err = mutex_lock_killable(&loop_ctl_mutex); + if (err) + goto out_free_dev; + /* allocate id, if @id >= 0, we're requesting that specific id */ if (i >= 0) { err = idr_alloc(&loop_index_idr, lo, i, i + 1, GFP_KERNEL); @@ -2259,7 +2262,7 @@ static int loop_add(int i) err = idr_alloc(&loop_index_idr, lo, 0, 0, GFP_KERNEL); } if (err < 0) - goto out_free_dev; + goto out_unlock; i = err; err = -ENOMEM; @@ -2326,12 +2329,15 @@ static int loop_add(int i) disk->queue = lo->lo_queue; sprintf(disk->disk_name, "loop%d", i); add_disk(disk); - return lo->lo_number; + mutex_unlock(&loop_ctl_mutex); + return i; out_cleanup_tags: blk_mq_free_tag_set(&lo->tag_set); out_free_idr: idr_remove(&loop_index_idr, i); +out_unlock: + mutex_unlock(&loop_ctl_mutex); out_free_dev: kfree(lo); out: @@ -2391,22 +2397,7 @@ static void loop_probe(dev_t dev) if (max_loop && idx >= max_loop) return; - - mutex_lock(&loop_ctl_mutex); loop_add(idx); - mutex_unlock(&loop_ctl_mutex); -} - -static int loop_control_add(int idx) -{ - int ret; - - ret = mutex_lock_killable(&loop_ctl_mutex); - if (ret) - return ret; - ret = loop_add(idx); - mutex_unlock(&loop_ctl_mutex); - return ret; } static int loop_control_remove(int idx) @@ -2450,11 +2441,11 @@ static int loop_control_get_free(int idx) if (ret) return ret; ret = loop_lookup(&lo, -1); - if (ret < 0) - ret = loop_add(-1); mutex_unlock(&loop_ctl_mutex); - return ret; + if (ret >= 0) + return ret; + return loop_add(-1); } static long loop_control_ioctl(struct file *file, unsigned int cmd, @@ -2462,7 +2453,7 @@ static long loop_control_ioctl(struct file *file, unsigned int cmd, { switch (cmd) { case LOOP_CTL_ADD: - return loop_control_add(parm); + return loop_add(parm); case LOOP_CTL_REMOVE: return loop_control_remove(parm); case LOOP_CTL_GET_FREE: @@ -2543,10 +2534,8 @@ static int __init loop_init(void) } /* pre-create number of devices given by config or max_loop */ - mutex_lock(&loop_ctl_mutex); for (i = 0; i < nr; i++) loop_add(i); - mutex_unlock(&loop_ctl_mutex); printk(KERN_INFO "loop: module loaded\n"); return 0; |