[Devel] [PATCH VZ9] fs/fuse: clear splice buffers from response to a killed request
Alexey Kuznetsov
kuznet at virtuozzo.com
Fri Feb 28 17:57:13 MSK 2025
Ack
On Fri, Feb 28, 2025 at 10:56 PM Liu Kui <kui.liu at virtuozzo.com> wrote:
>
> 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