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
1113 struct queue_limits lim;1113 struct queue_limits lim;
1114 struct file *filp;1114 struct file *filp;
1115 gfp_t gfp = lo->old_gfp_mask;1115 gfp_t gfp = lo->old_gfp_mask;
1116 int err;
1116 1117
1117 spin_lock_irq(&lo->lo_lock);1118 spin_lock_irq(&lo->lo_lock);
1118 filp = lo->lo_backing_file;1119 filp = lo->lo_backing_file;
@@ -1146,26 +1147,21 @@ static void __loop_clr_fd(struct loop_device *lo) · 27 unmodified lines
1146 1147
1147 disk_force_media_change(lo->lo_disk);1148 disk_force_media_change(lo->lo_disk);
1148 1149
1149 if (lo->lo_flags & LO_FLAGS_PARTSCAN) {1150 /*
1150 int err;1151 * Remove all partitions, including partitions added manually with
1151 1152 * BLKPG, which may exist even if LO_FLAGS_PARTSCAN is not set.
1152 /*1153 *
1153 * open_mutex has been held already in release path, so don't1154 * open_mutex has been held already in release path, so don't acquire
1154 * acquire it if this function is called in such case.1155 * it here.
1155 *1156 */
1156 * If the reread partition isn't from release path, lo_refcnt1157 err = bdev_disk_changed(lo->lo_disk, false);
1157 * must be at least one and it can only become zero when the1158 if (err)
1158 * current holder is released.1159 pr_warn("%s: partition scan of loop%d failed (rc=%d)\n",
1159 */1160 __func__, lo->lo_number, err);
1160 err = bdev_disk_changed(lo->lo_disk, false);1161 /* Device is gone, no point in returning error */
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 }
1166 1162
1167 /*1163 /*
1168 * lo->lo_state is set to Lo_unbound here after above partscan has1164 * lo->lo_state is set to Lo_unbound here after removing partitions has
1169 * finished. There cannot be anybody else entering __loop_clr_fd() as1165 * finished. There cannot be anybody else entering __loop_clr_fd() as
1170 * Lo_rundown state protects us from all the other places trying to1166 * Lo_rundown state protects us from all the other places trying to
1171 * change the 'lo' device.1167 * change the 'lo' device.