Re: [PATCH 4/8] loop: only take lo_mutex for the last reference in lo_release
From: Jan Kara <jack@suse.cz>
Date: 2022-01-28 13:37:18
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@lst.de> Tested-by: Darrick J. Wong <djwong@kernel.org>
Looks good. Feel free to add: Reviewed-by: Jan Kara <jack@suse.cz> Honza
quoted hunk ↗ jump to hunk
--- 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 [off-list ref] SUSE Labs, CR