History

loop: remove manually added partitions on detach

Commit 267ec4d7223a ("loop: fix partition scan race between udev and loop_reread_partitions()") stopped disk_force_media_change() from setting GD_NEED_PART_SCAN because loop devices with LO_FLAGS_PARTSCAN rescan partitions explicitly. However, partitions can also be added manually with BLKPG while LO_FLAGS_PARTSCAN is clear. When such a loop device is detached, __loop_clr_fd() skips bdev_disk_changed(). Without GD_NEED_PART_SCAN, reopening the unbound device no longer performs the previous lazy cleanup, leaving dead partition devices behind. A subsequent LOOP_CONFIGURE can then fail its partition scan with -EBUSY, as seen in blktests loop/009 after loop/008. Call bdev_disk_changed() unconditionally during __loop_clr_fd(). The disk capacity is already zero and the release path holds open_mutex, so this drops all partitions without rescanning the detached backing file. The new blktests loop/013 case covers this sequence by adding a partition with BLKPG without LO_FLAGS_PARTSCAN, detaching the loop device, and checking that the partition is gone when the device is reopened.

Daan De Meyer committed 3 months ago

Commit c4f4c0f1 parent 691b0521 file · +14 −18Browse files

Unified · Split

drivers/block/loop.c+14−18
@@ -1113,6 +1113,7 @@ static void __loop_clr_fd(struct loop_device *lo) · 1112 unmodified lines
11131113 struct queue_limits lim;
11141114 struct file *filp;
11151115 gfp_t gfp = lo->old_gfp_mask;
1116+ int err;
11161117
11171118 spin_lock_irq(&lo->lo_lock);
11181119 filp = lo->lo_backing_file;
@@ -1146,26 +1147,21 @@ static void __loop_clr_fd(struct loop_device *lo) · 27 unmodified lines
11461147
11471148 disk_force_media_change(lo->lo_disk);
11481149
1149− if (lo->lo_flags & LO_FLAGS_PARTSCAN) {
1150− int err;
1151−
1152− /*
1153− * open_mutex has been held already in release path, so don't
1154− * acquire it if this function is called in such case.
1155− *
1156− * If the reread partition isn't from release path, lo_refcnt
1157− * must be at least one and it can only become zero when the
1158− * current holder is released.
1159− */
1160− err = bdev_disk_changed(lo->lo_disk, false);
1161− if (err)
1162− pr_warn("%s: partition scan of loop%d failed (rc=%d)\n",
1163− __func__, lo->lo_number, err);
1164− /* Device is gone, no point in returning error */
1165− }
1150+ /*
1151+ * Remove all partitions, including partitions added manually with
1152+ * BLKPG, which may exist even if LO_FLAGS_PARTSCAN is not set.
1153+ *
1154+ * open_mutex has been held already in release path, so don't acquire
1155+ * it here.
1156+ */
1157+ err = bdev_disk_changed(lo->lo_disk, false);
1158+ if (err)
1159+ pr_warn("%s: partition scan of loop%d failed (rc=%d)\n",
1160+ __func__, lo->lo_number, err);
1161+ /* Device is gone, no point in returning error */
11661162
11671163 /*
1168− * lo->lo_state is set to Lo_unbound here after above partscan has
1164+ * lo->lo_state is set to Lo_unbound here after removing partitions has
11691165 * finished. There cannot be anybody else entering __loop_clr_fd() as
11701166 * Lo_rundown state protects us from all the other places trying to
11711167 * change the 'lo' device.