]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
loop: move lo_set_size() out of queue freeze
authorMing Lei <ming.lei@redhat.com>
Wed, 11 Jun 2025 08:49:38 +0000 (16:49 +0800)
committerJens Axboe <axboe@kernel.dk>
Wed, 11 Jun 2025 12:41:45 +0000 (06:41 -0600)
It isn't necessary to freeze queue for updating disk size given submit_bio()
doesn't grab queue usage counter for checking eod.

Also many driver won't freeze queue for calling set_capacity_and_notify().

Move lo_set_size() out of queue freeze for fixing many lockdep warning
report.

Link: https://lore.kernel.org/linux-block/67ea99e0.050a0220.3c3d88.0042.GAE@google.com/
Reported-by: syzbot+9dd7dbb1a4b915dee638@syzkaller.appspotmail.com
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20250611084938.108829-1-ming.lei@redhat.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/block/loop.c

index f8d136684109aa72ac1a897bb4340fcc3907f198..500840e4a74efc16c213522787ba8c1079f09380 100644 (file)
@@ -1248,12 +1248,6 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
        lo->lo_flags &= ~LOOP_SET_STATUS_CLEARABLE_FLAGS;
        lo->lo_flags |= (info->lo_flags & LOOP_SET_STATUS_SETTABLE_FLAGS);
 
-       if (size_changed) {
-               loff_t new_size = get_size(lo->lo_offset, lo->lo_sizelimit,
-                                          lo->lo_backing_file);
-               loop_set_size(lo, new_size);
-       }
-
        /* update the direct I/O flag if lo_offset changed */
        loop_update_dio(lo);
 
@@ -1261,6 +1255,11 @@ out_unfreeze:
        blk_mq_unfreeze_queue(lo->lo_queue, memflags);
        if (partscan)
                clear_bit(GD_SUPPRESS_PART_SCAN, &lo->lo_disk->state);
+       if (!err && size_changed) {
+               loff_t new_size = get_size(lo->lo_offset, lo->lo_sizelimit,
+                                          lo->lo_backing_file);
+               loop_set_size(lo, new_size);
+       }
 out_unlock:
        mutex_unlock(&lo->lo_mutex);
        if (partscan)