[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