Skip to content

Commit 2bc9742

Browse files
committed
Merge branch 'for-6.17/block' into for-next
* for-6.17/block: loop: Avoid updating block size under exclusive owner
2 parents d7d3914 + 7e49538 commit 2bc9742

1 file changed

Lines changed: 30 additions & 8 deletions

File tree

drivers/block/loop.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,17 +1432,34 @@ static int loop_set_dio(struct loop_device *lo, unsigned long arg)
14321432
return 0;
14331433
}
14341434

1435-
static int loop_set_block_size(struct loop_device *lo, unsigned long arg)
1435+
static int loop_set_block_size(struct loop_device *lo, blk_mode_t mode,
1436+
struct block_device *bdev, unsigned long arg)
14361437
{
14371438
struct queue_limits lim;
14381439
unsigned int memflags;
14391440
int err = 0;
14401441

1441-
if (lo->lo_state != Lo_bound)
1442-
return -ENXIO;
1442+
/*
1443+
* If we don't hold exclusive handle for the device, upgrade to it
1444+
* here to avoid changing device under exclusive owner.
1445+
*/
1446+
if (!(mode & BLK_OPEN_EXCL)) {
1447+
err = bd_prepare_to_claim(bdev, loop_set_block_size, NULL);
1448+
if (err)
1449+
return err;
1450+
}
1451+
1452+
err = mutex_lock_killable(&lo->lo_mutex);
1453+
if (err)
1454+
goto abort_claim;
1455+
1456+
if (lo->lo_state != Lo_bound) {
1457+
err = -ENXIO;
1458+
goto unlock;
1459+
}
14431460

14441461
if (lo->lo_queue->limits.logical_block_size == arg)
1445-
return 0;
1462+
goto unlock;
14461463

14471464
sync_blockdev(lo->lo_device);
14481465
invalidate_bdev(lo->lo_device);
@@ -1455,6 +1472,11 @@ static int loop_set_block_size(struct loop_device *lo, unsigned long arg)
14551472
loop_update_dio(lo);
14561473
blk_mq_unfreeze_queue(lo->lo_queue, memflags);
14571474

1475+
unlock:
1476+
mutex_unlock(&lo->lo_mutex);
1477+
abort_claim:
1478+
if (!(mode & BLK_OPEN_EXCL))
1479+
bd_abort_claiming(bdev, loop_set_block_size);
14581480
return err;
14591481
}
14601482

@@ -1473,9 +1495,6 @@ static int lo_simple_ioctl(struct loop_device *lo, unsigned int cmd,
14731495
case LOOP_SET_DIRECT_IO:
14741496
err = loop_set_dio(lo, arg);
14751497
break;
1476-
case LOOP_SET_BLOCK_SIZE:
1477-
err = loop_set_block_size(lo, arg);
1478-
break;
14791498
default:
14801499
err = -EINVAL;
14811500
}
@@ -1530,9 +1549,12 @@ static int lo_ioctl(struct block_device *bdev, blk_mode_t mode,
15301549
break;
15311550
case LOOP_GET_STATUS64:
15321551
return loop_get_status64(lo, argp);
1552+
case LOOP_SET_BLOCK_SIZE:
1553+
if (!(mode & BLK_OPEN_WRITE) && !capable(CAP_SYS_ADMIN))
1554+
return -EPERM;
1555+
return loop_set_block_size(lo, mode, bdev, arg);
15331556
case LOOP_SET_CAPACITY:
15341557
case LOOP_SET_DIRECT_IO:
1535-
case LOOP_SET_BLOCK_SIZE:
15361558
if (!(mode & BLK_OPEN_WRITE) && !capable(CAP_SYS_ADMIN))
15371559
return -EPERM;
15381560
fallthrough;

0 commit comments

Comments
 (0)