]> www.infradead.org Git - users/hch/block.git/commitdiff
loop: only take lo_mutex for the first reference in lo_open
authorChristoph Hellwig <hch@lst.de>
Wed, 26 Jan 2022 14:23:45 +0000 (15:23 +0100)
committerChristoph Hellwig <hch@lst.de>
Wed, 26 Jan 2022 15:25:35 +0000 (16:25 +0100)
lo_refcnt is only incremented in lo_open and decremented in lo_release,
and thus protected by open_mutex.  Only take lo_mutex when lo_open is
called the first time, as only for the first open there is any affect
on the driver state (incremental opens on partitions don't end up in
lo_open at all already).

Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/block/loop.c

index 43980ec69dfddf9bd8f2fa0fb3b712e3b4a46254..4b0058a67c48eb6d13962a8fdb9f41d0f163ac7f 100644 (file)
@@ -1725,13 +1725,16 @@ static int lo_open(struct block_device *bdev, fmode_t mode)
        struct loop_device *lo = bdev->bd_disk->private_data;
        int err;
 
+       if (atomic_inc_return(&lo->lo_refcnt) > 1)
+               return 0;
+
        err = mutex_lock_killable(&lo->lo_mutex);
        if (err)
                return err;
-       if (lo->lo_state == Lo_deleting)
+       if (lo->lo_state == Lo_deleting) {
+               atomic_dec(&lo->lo_refcnt);
                err = -ENXIO;
-       else
-               atomic_inc(&lo->lo_refcnt);
+       }
        mutex_unlock(&lo->lo_mutex);
        return err;
 }