From 42e77c4cf245d8420641d216d1abefe81f7a3b79 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 May 2020 13:30:17 +0200 Subject: [PATCH] vfs_io_uring: retry after a short read in vfs_io_uring_pread_completion() We need to be prepared for short reads from the kernel depending on the state of the page cache. Windows and Mac clients don't expect short reads for files, so we need to retry ourself. For the future we may be able to play with some io_uring flags in order to avoid the retries in userspace, but for now we just fix the data corruption bug... BUG: https://bugzilla.samba.org/show_bug.cgi?id=14361 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source3/modules/vfs_io_uring.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/source3/modules/vfs_io_uring.c b/source3/modules/vfs_io_uring.c index 0b1583f962a..f16c9ae56d3 100644 --- a/source3/modules/vfs_io_uring.c +++ b/source3/modules/vfs_io_uring.c @@ -489,6 +489,14 @@ static void vfs_io_uring_pread_completion(struct vfs_io_uring_request *cur, return; } + if (cur->cqe.res == 0) { + /* + * We reached EOF, we're done + */ + tevent_req_done(cur->req); + return; + } + ok = iov_advance(&iov, &num_iov, cur->cqe.res); if (!ok) { /* This is not expected! */ @@ -499,8 +507,20 @@ static void vfs_io_uring_pread_completion(struct vfs_io_uring_request *cur, return; } - state->nread = state->ur.cqe.res; - tevent_req_done(cur->req); + /* sys_valid_io_range() already checked the boundaries */ + state->nread += state->ur.cqe.res; + if (num_iov == 0) { + /* We're done */ + tevent_req_done(cur->req); + return; + } + + /* + * sys_valid_io_range() already checked the boundaries + * now try to get the rest. + */ + state->offset += state->ur.cqe.res; + vfs_io_uring_pread_submit(state); } static ssize_t vfs_io_uring_pread_recv(struct tevent_req *req, -- 2.34.1