On Fri 28-01-22 14:00:18, 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_release > actually takes action for the final release. > > 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 | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/drivers/block/loop.c b/drivers/block/loop.c > index d3a7f281ce1b6..b58dc95f80d96 100644 > --- a/drivers/block/loop.c > +++ b/drivers/block/loop.c > @@ -1740,10 +1740,14 @@ static void lo_release(struct gendisk *disk, fmode_t mode) > { > struct loop_device *lo = disk->private_data; > > - mutex_lock(&lo->lo_mutex); > - if (atomic_dec_return(&lo->lo_refcnt)) > - goto out_unlock; > + /* > + * Note: this requires disk->open_mutex to protect against races > + * with lo_open. > + */ > + if (!atomic_dec_and_test(&lo->lo_refcnt)) > + return; > > + mutex_lock(&lo->lo_mutex); > if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) { > if (lo->lo_state != Lo_bound) > goto out_unlock; > -- > 2.30.2 > -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR