Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

loop: revert exclusive opener loop status change

This commit effectively reverts the following two commits:

2704024d83fa ("loop: add missing bd_abort_claiming in loop_set_status")
08e136ebd193 ("loop: don't change loop device under exclusive opener in loop_set_status")

as there are reports of them causing issues with unmounting. As we're
close to the 6.19 kernel release and the original author hasn't taken a
closer look at this yet, revert them for release.

Reported-by: nokangaroo <nokangaroo@aon.at>
Link: https://lore.kernel.org/all/62de4453-17e8-47f6-a10b-39bf5a49fdee@leemhuis.info/
Signed-off-by: Jens Axboe <axboe@kernel.dk>

+12 -33
+12 -33
drivers/block/loop.c
··· 1225 1225 } 1226 1226 1227 1227 static int 1228 - loop_set_status(struct loop_device *lo, blk_mode_t mode, 1229 - struct block_device *bdev, const struct loop_info64 *info) 1228 + loop_set_status(struct loop_device *lo, const struct loop_info64 *info) 1230 1229 { 1231 1230 int err; 1232 1231 bool partscan = false; 1233 1232 bool size_changed = false; 1234 1233 unsigned int memflags; 1235 1234 1236 - /* 1237 - * If we don't hold exclusive handle for the device, upgrade to it 1238 - * here to avoid changing device under exclusive owner. 1239 - */ 1240 - if (!(mode & BLK_OPEN_EXCL)) { 1241 - err = bd_prepare_to_claim(bdev, loop_set_status, NULL); 1242 - if (err) 1243 - goto out_reread_partitions; 1244 - } 1245 - 1246 1235 err = mutex_lock_killable(&lo->lo_mutex); 1247 1236 if (err) 1248 - goto out_abort_claiming; 1249 - 1237 + return err; 1250 1238 if (lo->lo_state != Lo_bound) { 1251 1239 err = -ENXIO; 1252 1240 goto out_unlock; ··· 1273 1285 } 1274 1286 out_unlock: 1275 1287 mutex_unlock(&lo->lo_mutex); 1276 - out_abort_claiming: 1277 - if (!(mode & BLK_OPEN_EXCL)) 1278 - bd_abort_claiming(bdev, loop_set_status); 1279 - out_reread_partitions: 1280 1288 if (partscan) 1281 1289 loop_reread_partitions(lo); 1282 1290 ··· 1352 1368 } 1353 1369 1354 1370 static int 1355 - loop_set_status_old(struct loop_device *lo, blk_mode_t mode, 1356 - struct block_device *bdev, 1357 - const struct loop_info __user *arg) 1371 + loop_set_status_old(struct loop_device *lo, const struct loop_info __user *arg) 1358 1372 { 1359 1373 struct loop_info info; 1360 1374 struct loop_info64 info64; ··· 1360 1378 if (copy_from_user(&info, arg, sizeof (struct loop_info))) 1361 1379 return -EFAULT; 1362 1380 loop_info64_from_old(&info, &info64); 1363 - return loop_set_status(lo, mode, bdev, &info64); 1381 + return loop_set_status(lo, &info64); 1364 1382 } 1365 1383 1366 1384 static int 1367 - loop_set_status64(struct loop_device *lo, blk_mode_t mode, 1368 - struct block_device *bdev, 1369 - const struct loop_info64 __user *arg) 1385 + loop_set_status64(struct loop_device *lo, const struct loop_info64 __user *arg) 1370 1386 { 1371 1387 struct loop_info64 info64; 1372 1388 1373 1389 if (copy_from_user(&info64, arg, sizeof (struct loop_info64))) 1374 1390 return -EFAULT; 1375 - return loop_set_status(lo, mode, bdev, &info64); 1391 + return loop_set_status(lo, &info64); 1376 1392 } 1377 1393 1378 1394 static int ··· 1549 1569 case LOOP_SET_STATUS: 1550 1570 err = -EPERM; 1551 1571 if ((mode & BLK_OPEN_WRITE) || capable(CAP_SYS_ADMIN)) 1552 - err = loop_set_status_old(lo, mode, bdev, argp); 1572 + err = loop_set_status_old(lo, argp); 1553 1573 break; 1554 1574 case LOOP_GET_STATUS: 1555 1575 return loop_get_status_old(lo, argp); 1556 1576 case LOOP_SET_STATUS64: 1557 1577 err = -EPERM; 1558 1578 if ((mode & BLK_OPEN_WRITE) || capable(CAP_SYS_ADMIN)) 1559 - err = loop_set_status64(lo, mode, bdev, argp); 1579 + err = loop_set_status64(lo, argp); 1560 1580 break; 1561 1581 case LOOP_GET_STATUS64: 1562 1582 return loop_get_status64(lo, argp); ··· 1650 1670 } 1651 1671 1652 1672 static int 1653 - loop_set_status_compat(struct loop_device *lo, blk_mode_t mode, 1654 - struct block_device *bdev, 1655 - const struct compat_loop_info __user *arg) 1673 + loop_set_status_compat(struct loop_device *lo, 1674 + const struct compat_loop_info __user *arg) 1656 1675 { 1657 1676 struct loop_info64 info64; 1658 1677 int ret; ··· 1659 1680 ret = loop_info64_from_compat(arg, &info64); 1660 1681 if (ret < 0) 1661 1682 return ret; 1662 - return loop_set_status(lo, mode, bdev, &info64); 1683 + return loop_set_status(lo, &info64); 1663 1684 } 1664 1685 1665 1686 static int ··· 1685 1706 1686 1707 switch(cmd) { 1687 1708 case LOOP_SET_STATUS: 1688 - err = loop_set_status_compat(lo, mode, bdev, 1709 + err = loop_set_status_compat(lo, 1689 1710 (const struct compat_loop_info __user *)arg); 1690 1711 break; 1691 1712 case LOOP_GET_STATUS: