The commit is pushed to "branch-rh9-5.14.0-427.92.1.vz9.88.x-ovz" and will
appear at [email protected]:openvz/vzkernel.git
after rh9-5.14.0-427.92.1.vz9.88.11
------>
commit 5da864406ff13c7267495b69fc8f20d3d0d93e5e
Author: Liu Kui <[email protected]>
Date: Tue Dec 16 17:25:44 2025 +0800
fs/fuse kio: remove request from revoke list before unlocking pages
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]>
Acked-by: Alexey Kuznetsov <[email protected]>
Feature: vStorage
---
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 baefef99df32b..b59dacd29a6a7 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1220,6 +1220,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]);
@@ -1232,7 +1237,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;
@@ -1240,7 +1244,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;
/*
@@ -1252,7 +1263,7 @@ static void fuse_readpages_end(struct fuse_mount *fm,
struct fuse_args *args,
for (i = 0; i < ap->num_pages; i++) {
struct page *page = ap->pages[i];
- if (likely(!killed)) {
+ if (likely(!args->killed)) {
if (!err)
SetPageUptodate(page);
else
@@ -1263,13 +1274,9 @@ static void fuse_readpages_end(struct fuse_mount *fm,
struct fuse_args *args,
}
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);
}
_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel