Skip to content

Commit db26d62

Browse files
dhowellsbrauner
authored andcommitted
netfs: Fix undifferentiation of DIO reads from unbuffered reads
On cifs, "DIO reads" (specified by O_DIRECT) need to be differentiated from "unbuffered reads" (specified by cache=none in the mount parameters). The difference is flagged in the protocol and the server may behave differently: Windows Server will, for example, mandate that DIO reads are block aligned. Fix this by adding a NETFS_UNBUFFERED_READ to differentiate this from NETFS_DIO_READ, parallelling the write differentiation that already exists. cifs will then do the right thing. Fixes: 016dc85 ("netfs: Implement unbuffered/DIO read support") Signed-off-by: David Howells <[email protected]> Link: https://lore.kernel.org/[email protected] Reviewed-by: "Paulo Alcantara (Red Hat)" <[email protected]> Reviewed-by: Viacheslav Dubeyko <[email protected]> cc: Steve French <[email protected]> cc: [email protected] cc: [email protected] cc: [email protected] cc: [email protected] cc: [email protected] cc: [email protected] cc: [email protected] Signed-off-by: Christian Brauner <[email protected]>
1 parent 5fddfbc commit db26d62

File tree

12 files changed

+21
-6
lines changed

12 files changed

+21
-6
lines changed

fs/9p/vfs_addr.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ static void v9fs_issue_read(struct netfs_io_subrequest *subreq)
7777

7878
/* if we just extended the file size, any portion not in
7979
* cache won't be on server and is zeroes */
80-
if (subreq->rreq->origin != NETFS_DIO_READ)
80+
if (subreq->rreq->origin != NETFS_UNBUFFERED_READ &&
81+
subreq->rreq->origin != NETFS_DIO_READ)
8182
__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
8283
if (pos + total >= i_size_read(rreq->inode))
8384
__set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags);

fs/afs/write.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ void afs_retry_request(struct netfs_io_request *wreq, struct netfs_io_stream *st
202202
case NETFS_READ_GAPS:
203203
case NETFS_READ_SINGLE:
204204
case NETFS_READ_FOR_WRITE:
205+
case NETFS_UNBUFFERED_READ:
205206
case NETFS_DIO_READ:
206207
return;
207208
default:

fs/ceph/addr.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ static void finish_netfs_read(struct ceph_osd_request *req)
238238
if (sparse && err > 0)
239239
err = ceph_sparse_ext_map_end(op);
240240
if (err < subreq->len &&
241+
subreq->rreq->origin != NETFS_UNBUFFERED_READ &&
241242
subreq->rreq->origin != NETFS_DIO_READ)
242243
__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
243244
if (IS_ENCRYPTED(inode) && err > 0) {
@@ -281,7 +282,8 @@ static bool ceph_netfs_issue_op_inline(struct netfs_io_subrequest *subreq)
281282
size_t len;
282283
int mode;
283284

284-
if (rreq->origin != NETFS_DIO_READ)
285+
if (rreq->origin != NETFS_UNBUFFERED_READ &&
286+
rreq->origin != NETFS_DIO_READ)
285287
__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
286288
__clear_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags);
287289

fs/netfs/direct_read.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,8 @@ ssize_t netfs_unbuffered_read_iter_locked(struct kiocb *iocb, struct iov_iter *i
185185

186186
rreq = netfs_alloc_request(iocb->ki_filp->f_mapping, iocb->ki_filp,
187187
iocb->ki_pos, orig_count,
188-
NETFS_DIO_READ);
188+
iocb->ki_flags & IOCB_DIRECT ?
189+
NETFS_DIO_READ : NETFS_UNBUFFERED_READ);
189190
if (IS_ERR(rreq))
190191
return PTR_ERR(rreq);
191192

fs/netfs/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ static const char *netfs_origins[nr__netfs_io_origin] = {
3939
[NETFS_READ_GAPS] = "RG",
4040
[NETFS_READ_SINGLE] = "R1",
4141
[NETFS_READ_FOR_WRITE] = "RW",
42+
[NETFS_UNBUFFERED_READ] = "UR",
4243
[NETFS_DIO_READ] = "DR",
4344
[NETFS_WRITEBACK] = "WB",
4445
[NETFS_WRITEBACK_SINGLE] = "W1",

fs/netfs/misc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ static ssize_t netfs_wait_for_request(struct netfs_io_request *rreq,
461461
case NETFS_DIO_READ:
462462
case NETFS_DIO_WRITE:
463463
case NETFS_READ_SINGLE:
464+
case NETFS_UNBUFFERED_READ:
464465
case NETFS_UNBUFFERED_WRITE:
465466
break;
466467
default:

fs/netfs/objects.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
5959
origin == NETFS_READ_GAPS ||
6060
origin == NETFS_READ_SINGLE ||
6161
origin == NETFS_READ_FOR_WRITE ||
62+
origin == NETFS_UNBUFFERED_READ ||
6263
origin == NETFS_DIO_READ) {
6364
INIT_WORK(&rreq->work, netfs_read_collection_worker);
6465
rreq->io_streams[0].avail = true;

fs/netfs/read_collect.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,8 @@ static void netfs_rreq_assess_dio(struct netfs_io_request *rreq)
340340
{
341341
unsigned int i;
342342

343-
if (rreq->origin == NETFS_DIO_READ) {
343+
if (rreq->origin == NETFS_UNBUFFERED_READ ||
344+
rreq->origin == NETFS_DIO_READ) {
344345
for (i = 0; i < rreq->direct_bv_count; i++) {
345346
flush_dcache_page(rreq->direct_bv[i].bv_page);
346347
// TODO: cifs marks pages in the destination buffer
@@ -358,7 +359,8 @@ static void netfs_rreq_assess_dio(struct netfs_io_request *rreq)
358359
}
359360
if (rreq->netfs_ops->done)
360361
rreq->netfs_ops->done(rreq);
361-
if (rreq->origin == NETFS_DIO_READ)
362+
if (rreq->origin == NETFS_UNBUFFERED_READ ||
363+
rreq->origin == NETFS_DIO_READ)
362364
inode_dio_end(rreq->inode);
363365
}
364366

@@ -414,6 +416,7 @@ bool netfs_read_collection(struct netfs_io_request *rreq)
414416
//netfs_rreq_is_still_valid(rreq);
415417

416418
switch (rreq->origin) {
419+
case NETFS_UNBUFFERED_READ:
417420
case NETFS_DIO_READ:
418421
case NETFS_READ_GAPS:
419422
netfs_rreq_assess_dio(rreq);

fs/nfs/fscache.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ void nfs_netfs_read_completion(struct nfs_pgio_header *hdr)
367367

368368
sreq = netfs->sreq;
369369
if (test_bit(NFS_IOHDR_EOF, &hdr->flags) &&
370+
sreq->rreq->origin != NETFS_UNBUFFERED_READ &&
370371
sreq->rreq->origin != NETFS_DIO_READ)
371372
__set_bit(NETFS_SREQ_CLEAR_TAIL, &sreq->flags);
372373

fs/smb/client/file.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ static void cifs_issue_read(struct netfs_io_subrequest *subreq)
219219
goto failed;
220220
}
221221

222-
if (subreq->rreq->origin != NETFS_DIO_READ)
222+
if (subreq->rreq->origin != NETFS_UNBUFFERED_READ &&
223+
subreq->rreq->origin != NETFS_DIO_READ)
223224
__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
224225

225226
trace_netfs_sreq(subreq, netfs_sreq_trace_submit);

0 commit comments

Comments
 (0)