[Devel] [PATCH VZ9 for v6.3] fs/fuse: clear splice buffers from response to a killed request

Liu Kui kui.liu at virtuozzo.com
Fri Feb 28 17:53:36 MSK 2025


normally we just ignore the response to a killed request, however
if there are splice buffers returned with the response, we must
clear these splice buffers before returning them to userspace.

Fixed #VSTOR-100385

Signed-off-by: Liu Kui <kui.liu at virtuozzo.com>
---
 fs/fuse/dev.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 2e92b0c88b39..1a9d42e80a1a 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -1985,6 +1985,11 @@ static int copy_out_args(struct fuse_copy_state *cs, struct fuse_args *args,
 {
 	unsigned reqsize = sizeof(struct fuse_out_header);
 
+	if (unlikely(args->killed)) {
+		cs->req->out.h.error = -EIO;
+		return 0;
+	}
+
 	reqsize += fuse_len_args(args->out_numargs, args->out_args);
 
 	if (reqsize < nbytes || (reqsize > nbytes && !args->out_argvar))
@@ -2080,6 +2085,9 @@ static int copy_out_splices(struct fuse_copy_state *cs, struct fuse_args *args,
 				int ioff = pipe->bufs[tail & mask].offset;
 				int ilen = pipe->bufs[tail & mask].len;
 
+				if (unlikely(args->killed))
+					goto skip_copy;
+
 				while (ilen > 0) {
 					int copy = ilen;
 
@@ -2104,6 +2112,7 @@ static int copy_out_splices(struct fuse_copy_state *cs, struct fuse_args *args,
 					ioff += copy;
 					ilen -= copy;
 				}
+skip_copy:
 				put_page(ipage);
 				pipe->bufs[tail & mask].ops = NULL;
 				pipe->bufs[tail & mask].page = NULL;
@@ -2118,7 +2127,9 @@ static int copy_out_splices(struct fuse_copy_state *cs, struct fuse_args *args,
 		}
 	}
 
-	if (args->page_zeroing && didx < ap->num_pages) {
+	if (unlikely(args->killed)) {
+		cs->req->out.h.error = -EIO;
+	} else if (args->page_zeroing && didx < ap->num_pages) {
 		if (doff < dend) {
 			void *dst = kmap_atomic(dpage);
 
@@ -2227,10 +2238,7 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
 	if (!req->args->page_replace)
 		cs->move_pages = 0;
 
-	if (req->args->killed) {
-		err = 0;
-		req->out.h.error = -EIO;
-	} else if (oh.error == FUSE_OUT_SPLICES) {
+	if (oh.error == FUSE_OUT_SPLICES) {
 		req->out.h.error = 0;
 		err = copy_out_splices(cs, req->args, nbytes);
 	} else if (oh.error)
-- 
2.39.5 (Apple Git-154)



More information about the Devel mailing list