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
