Error path for blk_validate_block_size is wrong, we should goto unlock, or lo_mutex won't be release, and bdev will keep claimed.
...
-static int loop_set_block_size(struct loop_device *lo, unsigned long arg) +static int loop_set_block_size(struct loop_device *lo, blk_mode_t mode, + struct block_device *bdev, unsigned long arg) { int err = 0;
- if (lo->lo_state != Lo_bound) - return -ENXIO; + /* + * If we don't hold exclusive handle for the device, upgrade to it + * here to avoid changing device under exclusive owner. + */ + if (!(mode & BLK_OPEN_EXCL)) { + err = bd_prepare_to_claim(bdev, loop_set_block_size, NULL); + if (err) + return err; + } + + err = mutex_lock_killable(&lo->lo_mutex); + if (err) + goto abort_claim; + + if (lo->lo_state != Lo_bound) { + err = -ENXIO; + goto unlock; + }
err = blk_validate_block_size(arg); if (err) return err; ^^^^^^^^^^^^^ should goto unlock
if (lo->lo_queue->limits.logical_block_size == arg) - return 0; + goto unlock;
sync_blockdev(lo->lo_device); invalidate_bdev(lo->lo_device);
blk_mq_freeze_queue(lo->lo_queue); blk_queue_logical_block_size(lo->lo_queue, arg); blk_queue_physical_block_size(lo->lo_queue, arg); blk_queue_io_min(lo->lo_queue, arg); loop_update_dio(lo); blk_mq_unfreeze_queue(lo->lo_queue);
+unlock: + mutex_unlock(&lo->lo_mutex); +abort_claim: + if (!(mode & BLK_OPEN_EXCL)) + bd_abort_claiming(bdev, loop_set_block_size); return err; }
在 2025/9/29 21:28, Greg KH 写道:
On Wed, Sep 24, 2025 at 10:36:19AM +0800, yangerkun wrote:
Error path for blk_validate_block_size is wrong, we should goto unlock, or lo_mutex won't be release, and bdev will keep claimed.
Can you provide a working patch we can apply?
My colleague Zheng Qixing has already made the correct adaptation, and she might release it in a week (we are about to start the National Day holiday).
thanks,
greg k-h
linux-stable-mirror@lists.linaro.org