Skip to content

Commit dc90952

Browse files
Christoph Hellwigaxboe
authored andcommitted
loop: open code the direct I/O flag update in loop_set_dio
loop_set_dio is different from the other (__)loop_update_dio callers in that it doesn't take any implicit conditions into account and wants to update the direct I/O flag to the user passed in value and fail if that can't be done. Open code the logic here to prepare for simplifying the other direct I/O flag updates and to make the error handling less convoluted. Signed-off-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/20250110073750.1582447-6-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 09ccf55 commit dc90952

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

drivers/block/loop.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1455,16 +1455,28 @@ static int loop_set_capacity(struct loop_device *lo)
14551455

14561456
static int loop_set_dio(struct loop_device *lo, unsigned long arg)
14571457
{
1458-
int error = -ENXIO;
1459-
if (lo->lo_state != Lo_bound)
1460-
goto out;
1458+
bool use_dio = !!arg;
14611459

1462-
__loop_update_dio(lo, !!arg);
1463-
if (lo->use_dio == !!arg)
1460+
if (lo->lo_state != Lo_bound)
1461+
return -ENXIO;
1462+
if (use_dio == lo->use_dio)
14641463
return 0;
1465-
error = -EINVAL;
1466-
out:
1467-
return error;
1464+
1465+
if (use_dio) {
1466+
if (!lo_can_use_dio(lo))
1467+
return -EINVAL;
1468+
/* flush dirty pages before starting to use direct I/O */
1469+
vfs_fsync(lo->lo_backing_file, 0);
1470+
}
1471+
1472+
blk_mq_freeze_queue(lo->lo_queue);
1473+
lo->use_dio = use_dio;
1474+
if (use_dio)
1475+
lo->lo_flags |= LO_FLAGS_DIRECT_IO;
1476+
else
1477+
lo->lo_flags &= ~LO_FLAGS_DIRECT_IO;
1478+
blk_mq_unfreeze_queue(lo->lo_queue);
1479+
return 0;
14681480
}
14691481

14701482
static int loop_set_block_size(struct loop_device *lo, unsigned long arg)

0 commit comments

Comments
 (0)