On Fri 28-01-22 14:00:19, Christoph Hellwig wrote: > 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@xxxxxx> > Tested-by: Darrick J. Wong <djwong@xxxxxxxxxx> Looks good. Feel free to add: Reviewed-by: Jan Kara <jack@xxxxxxx> Honza > --- > drivers/block/loop.c | 13 ++++++++++--- > 1 file changed, 10 insertions(+), 3 deletions(-) > > diff --git a/drivers/block/loop.c b/drivers/block/loop.c > index b58dc95f80d96..f349ddfc0e84a 100644 > --- a/drivers/block/loop.c > +++ b/drivers/block/loop.c > @@ -1725,13 +1725,20 @@ static int lo_open(struct block_device *bdev, fmode_t mode) > struct loop_device *lo = bdev->bd_disk->private_data; > int err; > > + /* > + * Note: this requires disk->open_mutex to protect against races > + * with lo_release. > + */ > + 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; > } > -- > 2.30.2 > -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR