vfs_io_uring: retry after a short writes in vfs_io_uring_pwrite_completion()
authorStefan Metzmacher <metze@samba.org>
Fri, 8 May 2020 11:30:17 +0000 (13:30 +0200)
committerJeremy Allison <jra@samba.org>
Tue, 12 May 2020 19:53:46 +0000 (19:53 +0000)
We need to be prepared for short writes from the kernel depending on
the state of the page cache.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14361

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/modules/vfs_io_uring.c

index f16c9ae56d335a3d88e67b05fc43ad425fb54076..4625e16c37eece723f0a16cd0cd24100b544bbde 100644 (file)
@@ -637,6 +637,14 @@ static void vfs_io_uring_pwrite_completion(struct vfs_io_uring_request *cur,
                return;
        }
 
+       if (cur->cqe.res == 0) {
+               /*
+                * Ensure we can never spin.
+                */
+               tevent_req_error(cur->req, ENOSPC);
+               return;
+       }
+
        ok = iov_advance(&iov, &num_iov, cur->cqe.res);
        if (!ok) {
                /* This is not expected! */
@@ -647,8 +655,20 @@ static void vfs_io_uring_pwrite_completion(struct vfs_io_uring_request *cur,
                return;
        }
 
-       state->nwritten = state->ur.cqe.res;
-       tevent_req_done(cur->req);
+       /* sys_valid_io_range() already checked the boundaries */
+       state->nwritten += 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 write the rest.
+        */
+       state->offset += state->ur.cqe.res;
+       vfs_io_uring_pwrite_submit(state);
 }
 
 static ssize_t vfs_io_uring_pwrite_recv(struct tevent_req *req,