[Devel] [PATCH RHEL10 COMMIT] fs/fuse: restore fuse_writepages() to mainstream behavior
Konstantin Khorenko
khorenko at virtuozzo.com
Fri May 15 18:17:10 MSK 2026
The commit is pushed to "branch-rh10-6.12.0-55.52.1.5.x.vz10-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git
after rh10-6.12.0-55.52.1.5.25.vz10
------>
commit ec55dfedf369b2510ae2424a147545965b979838
Author: Liu Kui <kui.liu at virtuozzo.com>
Date: Mon Apr 20 15:13:02 2026 +0800
fs/fuse: restore fuse_writepages() to mainstream behavior
Revert the fuse_writepages()/fuse_writepages_fill() changes introduced
by 67d9ccc4cc1d ("fuse: fix writeback/release race"), which should have
been dropped when 083cb0ac8e38 ("fuse: Wait inflight requests") landed.
The reverted code has several problems:
- It overrides write_cache_pages() errors with err = 0 after
fuse_writepages_send(), silently swallowing writeback failures.
- It releases and re-acquires the fuse_file reference (data->ff)
between batches, which is unnecessary - the reference obtained
at the start of the callback is valid for the entire iteration.
- It uses BUG_ON() for conditions that are not fatal.
Align with the upstream v6.12 behavior: acquire data->ff once at
the top of fuse_writepages_fill(), keep it for the entire iteration,
and release it once in fuse_writepages() after all batches are sent.
Signed-off-by: Liu Kui <kui.liu at virtuozzo.com>
Acked-by: Alexey Kuznetsov <kuznet at virtuozzo.com>
Feature: vStorage
---
fs/fuse/file.c | 27 +++++++++------------------
1 file changed, 9 insertions(+), 18 deletions(-)
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 11fb3996a2ac3..b84aac13bfc91 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1233,7 +1233,7 @@ void fuse_release_ff(struct inode *inode, struct fuse_file *ff)
struct fuse_inode *fi = get_fuse_inode(inode);
spin_lock(&fi->lock);
__fuse_file_put(ff);
- wake_up(&get_fuse_inode(inode)->page_waitq);
+ wake_up(&fi->page_waitq);
spin_unlock(&fi->lock);
} else {
fuse_file_put(ff, false);
@@ -2724,17 +2724,20 @@ static int fuse_writepages_fill(struct folio *folio,
int err;
int check_for_blocked = 0;
- BUG_ON(wpa && !data->ff);
-
if (!wpa && test_bit(FUSE_I_INVAL_FILES, &fi->state)) {
unlock_page(&folio->page);
return -EIO;
}
+ if (!data->ff) {
+ err = -EIO;
+ data->ff = fuse_write_file_get(fi);
+ if (!data->ff)
+ goto out_unlock;
+ }
+
if (wpa && fuse_writepage_need_send(fc, &folio->page, ap, data)) {
fuse_writepages_send(data);
- fuse_release_ff(inode, data->ff);
- data->ff = NULL;
data->wpa = NULL;
}
@@ -2757,13 +2760,6 @@ static int fuse_writepages_fill(struct folio *folio,
* under writeback, so we can release the page lock.
*/
if (data->wpa == NULL) {
- /* we can acquire ff here because we do have locked pages here! */
- BUG_ON(data->ff);
- err = -EIO;
- data->ff = fuse_write_file_get(fi);
- if (!data->ff)
- goto out_unlock;
-
err = -ENOMEM;
wpa = fuse_writepage_args_setup(folio, data->ff);
if (!wpa) {
@@ -2794,8 +2790,6 @@ static int fuse_writepages_fill(struct folio *folio,
data->wpa = wpa;
} else {
folio_end_writeback(folio);
- fuse_release_ff(inode, data->ff);
- data->ff = NULL;
}
out_unlock:
folio_unlock(folio);
@@ -2845,11 +2839,8 @@ static int fuse_writepages(struct address_space *mapping,
if (data.wpa) {
WARN_ON(!data.wpa->ia.ap.num_pages);
fuse_writepages_send(&data);
- fuse_release_ff(inode, data.ff);
- data.ff = NULL;
- err = 0;
}
- BUG_ON(data.ff);
+ fuse_release_ff(inode, data.ff);
kfree(data.orig_pages);
out:
More information about the Devel
mailing list