[Devel] [PATCH VZ9] fs/fuse: clear splice buffers from response to a killed request
Liu Kui
kui.liu at virtuozzo.com
Fri Feb 28 17:47:26 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 | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index cc6b9f348cf6..118613f17b10 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -1986,6 +1986,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))
@@ -2081,6 +2086,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;
@@ -2105,6 +2113,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;
@@ -2119,7 +2128,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);
@@ -2159,6 +2170,11 @@ static int copy_out_krpczc(struct fuse_copy_state *cs, struct fuse_args *args,
void *dst;
int err;
+ if (unlikely(args->killed)) {
+ cs->req->out.h.error = -EIO;
+ return 0;
+ }
+
if (args->out_numargs != 1 || !args->out_pages)
return -EINVAL;
@@ -2338,10 +2354,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 == FUSE_OUT_KRPCZC) {
--
2.39.5 (Apple Git-154)
More information about the Devel
mailing list