Ack to both

On Tue, Dec 16, 2025 at 5:41 PM Liu Kui <[email protected]> wrote:
>
> The read request must be removed from the revoke list before unlocking
> the pages. Otherwise, fuse_invalidate_file() could incorrectly unlock
> the pages if another process has locked them in the meantime.
>
> Also add a sanity check in fuse_revoke_readpages() to catch unexpected
> conditions.
>
> https://virtuozzo.atlassian.net/browse/VSTOR-120919
>
> Signed-off-by: Liu Kui <[email protected]>
> ---
>  fs/fuse/file.c | 25 ++++++++++++++++---------
>  1 file changed, 16 insertions(+), 9 deletions(-)
>
> diff --git a/fs/fuse/file.c b/fs/fuse/file.c
> index 1bbad4798f0b..28e6b3c1aa06 100644
> --- a/fs/fuse/file.c
> +++ b/fs/fuse/file.c
> @@ -1242,6 +1242,11 @@ void fuse_revoke_readpages(struct fuse_file *ff)
>         spin_lock(&ff->lock);
>         /* revoke all pending read issued from page cache */
>         list_for_each_entry(ia, &ff->revoke_list, revoke_entry) {
> +               /* this should never happen unless userspace misbehaves */
> +               if (unlikely(ia->ap.args.killed)) {
> +                       WARN_ON_ONCE(1);
> +                       continue;
> +               }
>                 ia->ap.args.killed = 1;
>                 for (i = 0; i < ia->ap.num_pages; i++)
>                         unlock_page(ia->ap.pages[i]);
> @@ -1254,7 +1259,6 @@ static void fuse_readpages_end(struct fuse_mount *fm, 
> struct fuse_args *args,
>                                int err)
>  {
>         int i;
> -       bool killed = args->killed;
>         struct fuse_io_args *ia = container_of(args, typeof(*ia), ap.args);
>         struct fuse_args_pages *ap = &ia->ap;
>         size_t count = ia->read.in.size;
> @@ -1262,7 +1266,14 @@ static void fuse_readpages_end(struct fuse_mount *fm, 
> struct fuse_args *args,
>         struct inode *inode = args->io_inode;
>         struct fuse_file *ff = ia->ff;
>
> -       if (unlikely(killed))
> +       /* remove request from revoke list first */
> +       if (ff) {
> +               spin_lock(&ff->lock);
> +               list_del(&ia->revoke_entry);
> +               spin_unlock(&ff->lock);
> +       }
> +
> +       if (unlikely(args->killed))
>                 err = -EIO;
>
>         /*
> @@ -1274,19 +1285,15 @@ static void fuse_readpages_end(struct fuse_mount *fm, 
> struct fuse_args *args,
>         for (i = 0; i < ap->num_pages; i++) {
>                 struct folio *folio = page_folio(ap->pages[i]);
>
> -               if (likely(!killed))
> +               if (likely(!args->killed))
>                         folio_end_read(folio, !err);
>                 folio_put(folio);
>         }
>         fuse_invalidate_atime(inode);
>
> -       if (ff) {
> -               spin_lock(&ff->lock);
> -               list_del(&ia->revoke_entry);
> -               spin_unlock(&ff->lock);
> -
> +       if (ff)
>                 fuse_release_ff(inode, ff);
> -       }
> +
>         fuse_io_free(ia);
>  }
>
> --
> 2.39.5 (Apple Git-154)

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to