@@ -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