Skip to content

Commit f2fed44

Browse files
Christoph Hellwigaxboe
authored andcommitted
loop: stop using vfs_iter_{read,write} for buffered I/O
vfs_iter_{read,write} always perform direct I/O when the file has the O_DIRECT flag set, which breaks disabling direct I/O using the LOOP_SET_STATUS / LOOP_SET_STATUS64 ioctls. This was recenly reported as a regression, but as far as I can tell was only uncovered by better checking for block sizes and has been around since the direct I/O support was added. Fix this by using the existing aio code that calls the raw read/write iter methods instead. Note that despite the comments there is no need for block drivers to ever call flush_dcache_page themselves, and the call is a left-over from prehistoric times. Fixes: ab1cb27 ("block: loop: introduce ioctl command of LOOP_SET_DIRECT_IO") Reported-by: Darrick J. Wong <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Ming Lei <[email protected]> Tested-by: Darrick J. Wong <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 0dba7a0 commit f2fed44

File tree

1 file changed

+17
-95
lines changed

1 file changed

+17
-95
lines changed

drivers/block/loop.c

Lines changed: 17 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -211,72 +211,6 @@ static void loop_set_size(struct loop_device *lo, loff_t size)
211211
kobject_uevent(&disk_to_dev(lo->lo_disk)->kobj, KOBJ_CHANGE);
212212
}
213213

214-
static int lo_write_bvec(struct file *file, struct bio_vec *bvec, loff_t *ppos)
215-
{
216-
struct iov_iter i;
217-
ssize_t bw;
218-
219-
iov_iter_bvec(&i, ITER_SOURCE, bvec, 1, bvec->bv_len);
220-
221-
bw = vfs_iter_write(file, &i, ppos, 0);
222-
223-
if (likely(bw == bvec->bv_len))
224-
return 0;
225-
226-
printk_ratelimited(KERN_ERR
227-
"loop: Write error at byte offset %llu, length %i.\n",
228-
(unsigned long long)*ppos, bvec->bv_len);
229-
if (bw >= 0)
230-
bw = -EIO;
231-
return bw;
232-
}
233-
234-
static int lo_write_simple(struct loop_device *lo, struct request *rq,
235-
loff_t pos)
236-
{
237-
struct bio_vec bvec;
238-
struct req_iterator iter;
239-
int ret = 0;
240-
241-
rq_for_each_segment(bvec, rq, iter) {
242-
ret = lo_write_bvec(lo->lo_backing_file, &bvec, &pos);
243-
if (ret < 0)
244-
break;
245-
cond_resched();
246-
}
247-
248-
return ret;
249-
}
250-
251-
static int lo_read_simple(struct loop_device *lo, struct request *rq,
252-
loff_t pos)
253-
{
254-
struct bio_vec bvec;
255-
struct req_iterator iter;
256-
struct iov_iter i;
257-
ssize_t len;
258-
259-
rq_for_each_segment(bvec, rq, iter) {
260-
iov_iter_bvec(&i, ITER_DEST, &bvec, 1, bvec.bv_len);
261-
len = vfs_iter_read(lo->lo_backing_file, &i, &pos, 0);
262-
if (len < 0)
263-
return len;
264-
265-
flush_dcache_page(bvec.bv_page);
266-
267-
if (len != bvec.bv_len) {
268-
struct bio *bio;
269-
270-
__rq_for_each_bio(bio, rq)
271-
zero_fill_bio(bio);
272-
break;
273-
}
274-
cond_resched();
275-
}
276-
277-
return 0;
278-
}
279-
280214
static void loop_clear_limits(struct loop_device *lo, int mode)
281215
{
282216
struct queue_limits lim = queue_limits_start_update(lo->lo_queue);
@@ -342,7 +276,7 @@ static void lo_complete_rq(struct request *rq)
342276
struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq);
343277
blk_status_t ret = BLK_STS_OK;
344278

345-
if (!cmd->use_aio || cmd->ret < 0 || cmd->ret == blk_rq_bytes(rq) ||
279+
if (cmd->ret < 0 || cmd->ret == blk_rq_bytes(rq) ||
346280
req_op(rq) != REQ_OP_READ) {
347281
if (cmd->ret < 0)
348282
ret = errno_to_blk_status(cmd->ret);
@@ -358,14 +292,13 @@ static void lo_complete_rq(struct request *rq)
358292
cmd->ret = 0;
359293
blk_mq_requeue_request(rq, true);
360294
} else {
361-
if (cmd->use_aio) {
362-
struct bio *bio = rq->bio;
295+
struct bio *bio = rq->bio;
363296

364-
while (bio) {
365-
zero_fill_bio(bio);
366-
bio = bio->bi_next;
367-
}
297+
while (bio) {
298+
zero_fill_bio(bio);
299+
bio = bio->bi_next;
368300
}
301+
369302
ret = BLK_STS_IOERR;
370303
end_io:
371304
blk_mq_end_request(rq, ret);
@@ -445,9 +378,14 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
445378

446379
cmd->iocb.ki_pos = pos;
447380
cmd->iocb.ki_filp = file;
448-
cmd->iocb.ki_complete = lo_rw_aio_complete;
449-
cmd->iocb.ki_flags = IOCB_DIRECT;
450381
cmd->iocb.ki_ioprio = req_get_ioprio(rq);
382+
if (cmd->use_aio) {
383+
cmd->iocb.ki_complete = lo_rw_aio_complete;
384+
cmd->iocb.ki_flags = IOCB_DIRECT;
385+
} else {
386+
cmd->iocb.ki_complete = NULL;
387+
cmd->iocb.ki_flags = 0;
388+
}
451389

452390
if (rw == ITER_SOURCE)
453391
ret = file->f_op->write_iter(&cmd->iocb, &iter);
@@ -458,23 +396,14 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
458396

459397
if (ret != -EIOCBQUEUED)
460398
lo_rw_aio_complete(&cmd->iocb, ret);
461-
return 0;
399+
return -EIOCBQUEUED;
462400
}
463401

464402
static int do_req_filebacked(struct loop_device *lo, struct request *rq)
465403
{
466404
struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq);
467405
loff_t pos = ((loff_t) blk_rq_pos(rq) << 9) + lo->lo_offset;
468406

469-
/*
470-
* lo_write_simple and lo_read_simple should have been covered
471-
* by io submit style function like lo_rw_aio(), one blocker
472-
* is that lo_read_simple() need to call flush_dcache_page after
473-
* the page is written from kernel, and it isn't easy to handle
474-
* this in io submit style function which submits all segments
475-
* of the req at one time. And direct read IO doesn't need to
476-
* run flush_dcache_page().
477-
*/
478407
switch (req_op(rq)) {
479408
case REQ_OP_FLUSH:
480409
return lo_req_flush(lo, rq);
@@ -490,15 +419,9 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
490419
case REQ_OP_DISCARD:
491420
return lo_fallocate(lo, rq, pos, FALLOC_FL_PUNCH_HOLE);
492421
case REQ_OP_WRITE:
493-
if (cmd->use_aio)
494-
return lo_rw_aio(lo, cmd, pos, ITER_SOURCE);
495-
else
496-
return lo_write_simple(lo, rq, pos);
422+
return lo_rw_aio(lo, cmd, pos, ITER_SOURCE);
497423
case REQ_OP_READ:
498-
if (cmd->use_aio)
499-
return lo_rw_aio(lo, cmd, pos, ITER_DEST);
500-
else
501-
return lo_read_simple(lo, rq, pos);
424+
return lo_rw_aio(lo, cmd, pos, ITER_DEST);
502425
default:
503426
WARN_ON_ONCE(1);
504427
return -EIO;
@@ -1922,7 +1845,6 @@ static void loop_handle_cmd(struct loop_cmd *cmd)
19221845
struct loop_device *lo = rq->q->queuedata;
19231846
int ret = 0;
19241847
struct mem_cgroup *old_memcg = NULL;
1925-
const bool use_aio = cmd->use_aio;
19261848

19271849
if (write && (lo->lo_flags & LO_FLAGS_READ_ONLY)) {
19281850
ret = -EIO;
@@ -1952,7 +1874,7 @@ static void loop_handle_cmd(struct loop_cmd *cmd)
19521874
}
19531875
failed:
19541876
/* complete non-aio request */
1955-
if (!use_aio || ret) {
1877+
if (ret != -EIOCBQUEUED) {
19561878
if (ret == -EOPNOTSUPP)
19571879
cmd->ret = ret;
19581880
else

0 commit comments

Comments
 (0)