From b4271b0e8bf88c300c65261cc2413fe185139636 Mon Sep 17 00:00:00 2001 From: Horst Birthelmer Date: Tue, 18 Aug 2026 19:25:17 +0200 Subject: [PATCH 1/5] Revert "fuse: default the request timeout to the hung task timeout" This reverts commit 6462b6957546dbb8f8dcae16775640351e8eb9fe. This has to be thought through better since done this way it will make disabling request timeouts impossible since it will take the hung task automaitcally on zero. This led to request terminations during io500 bench testing --- Documentation/admin-guide/sysctl/fs.rst | 6 ----- fs/fuse/fuse_i.h | 6 ----- fs/fuse/inode.c | 33 +++---------------------- fs/fuse/sysctl.c | 6 ++++- 4 files changed, 8 insertions(+), 43 deletions(-) diff --git a/Documentation/admin-guide/sysctl/fs.rst b/Documentation/admin-guide/sysctl/fs.rst index 89d645546f34d0..6c54718c9d04ba 100644 --- a/Documentation/admin-guide/sysctl/fs.rst +++ b/Documentation/admin-guide/sysctl/fs.rst @@ -367,12 +367,6 @@ greater than max_request_timeout, the system will use max_request_timeout as the timeout. 0 indicates no max request timeout. The maximum value that can be set is 65535. -If the server did not specify a timeout at mount and both of the above are set -to 0, the timeout is derived from ``/proc/sys/kernel/hung_task_timeout_secs`` -instead, so that a server that stops answering aborts the connection rather than -leaving the waiters around for the hung task detector to report on. Setting -hung_task_timeout_secs to 0 disables this fallback as well. - For timeouts, if the server does not respond to the request by the time the set timeout elapses, then the connection to the fuse server will be aborted. Please note that the timeouts are not 100% precise (eg you may set 60 seconds but diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 55fe9a5368f481..e44b1ddec1289c 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -53,12 +53,6 @@ /* Frequency (in seconds) of request timeout checks, if opted into */ #define FUSE_TIMEOUT_TIMER_FREQ 15 -/* - * Upper bound (in seconds) for request timeouts. fuse_init_out request - * timeouts are u16, and this goes up to ~18 hours, which is plenty. - */ -#define FUSE_REQ_TIMEOUT_LIMIT 65535 - /** Frequency (in jiffies) of request timeout checks, if opted into */ extern const unsigned long fuse_timeout_timer_freq; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 2ef8dd685a4c25..e61dc0321ce598 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -1804,31 +1803,11 @@ static void set_request_timeout(struct fuse_conn *fc, unsigned int timeout) fuse_timeout_timer_freq); } -/* - * Timeout to use when neither the server nor the admin asked for one: keep it - * in sync with the hung task detector, which is the system wide notion of "this - * has been stuck for too long". Returns 0 if the detector is disabled. - */ -static unsigned int hung_task_req_timeout(void) -{ - unsigned long timeout = sysctl_hung_task_timeout_secs; - - if (!timeout) - return 0; - - /* - * Requests are only checked every FUSE_TIMEOUT_TIMER_FREQ seconds, so - * aim one period below the hung task timeout in order to abort the - * connection before the detector reports on the waiters. - */ - if (timeout > FUSE_TIMEOUT_TIMER_FREQ) - timeout -= FUSE_TIMEOUT_TIMER_FREQ; - - return min_t(unsigned long, timeout, FUSE_REQ_TIMEOUT_LIMIT); -} - static void init_server_timeout(struct fuse_conn *fc, unsigned int timeout) { + if (!timeout && !fuse_max_req_timeout && !fuse_default_req_timeout) + return; + if (!timeout) timeout = fuse_default_req_timeout; @@ -1839,12 +1818,6 @@ static void init_server_timeout(struct fuse_conn *fc, unsigned int timeout) timeout = fuse_max_req_timeout; } - if (!timeout) - timeout = hung_task_req_timeout(); - - if (!timeout) - return; - timeout = max(FUSE_TIMEOUT_TIMER_FREQ, timeout); set_request_timeout(fc, timeout); diff --git a/fs/fuse/sysctl.c b/fs/fuse/sysctl.c index 107ecae0e4f9dd..e2d921abcb8832 100644 --- a/fs/fuse/sysctl.c +++ b/fs/fuse/sysctl.c @@ -13,7 +13,11 @@ static struct ctl_table_header *fuse_table_header; /* Bound by fuse_init_out max_pages, which is a u16 */ static unsigned int sysctl_fuse_max_pages_limit = 65535; -static unsigned int sysctl_fuse_req_timeout_limit = FUSE_REQ_TIMEOUT_LIMIT; +/* + * fuse_init_out request timeouts are u16. + * This goes up to ~18 hours, which is plenty for a timeout. + */ +static unsigned int sysctl_fuse_req_timeout_limit = 65535; static const struct ctl_table fuse_sysctl_table[] = { { From 45a48e25bbf57d95eaca48c984c715ce59d00ca4 Mon Sep 17 00:00:00 2001 From: Horst Birthelmer Date: Tue, 18 Aug 2026 20:59:42 +0200 Subject: [PATCH 2/5] fuse: re-lock the append range when generic_write_checks() moves it The append grant is taken at a sampled i_size, but the exclusive inode lock does not pin it: attribute replies move i_size under fi->lock alone. generic_write_checks() then rewrites ki_pos to the fresher i_size and the write lands past the granted range, dirtying the cache without DLM coverage. The in-gate re-validation checks the stale range and cannot catch it. Request the lock again for the final ki_pos when it moved, and let dlm_pos track it so the in-gate re-validation guards the range the write really lands in. Signed-off-by: Horst Birthelmer --- fs/fuse/file.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index c30da1a6452ed6..d92611094944b5 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1975,9 +1975,7 @@ static ssize_t fuse_cache_write_iter(struct kiocb *iocb, struct iov_iter *from) /* * An append write lands at the current EOF no matter what * ki_pos holds: generic_write_checks() rewrites ki_pos to - * i_size for IOCB_APPEND, and i_size is stable here because - * append writes hold the inode lock exclusive. Lock where - * the data will land. + * i_size for IOCB_APPEND. Lock where the data will land. */ dlm_pos = i_size_read(inode); dlm_len = iov_iter_count(from); @@ -1992,6 +1990,24 @@ static ssize_t fuse_cache_write_iter(struct kiocb *iocb, struct iov_iter *from) if (err <= 0) goto out; + /* + * The exclusive inode lock does not pin i_size for the append: + * attribute replies move it under fi->lock alone, so + * generic_write_checks() may have put ki_pos past the granted + * range. Re-lock where the write really lands; dlm_pos tracks it + * so the in-gate re-validation below guards the same range. + */ + if (writeback && fc->dlm && (iocb->ki_flags & IOCB_APPEND) && + iocb->ki_pos != dlm_pos) { + dlm_pos = iocb->ki_pos; + dlm_len = count; + + err = fuse_cache_wr_dlm_lock(file, dlm_pos, dlm_len, + &dlm_unrecorded); + if (err) + goto out; + } + /* * Kill suid/sgid and stamp the timestamps here, before the gate, * instead of leaving them next to the write itself. kiocb_modified() From fd44473cd6a71511edffd52e7b797512a26ec96e Mon Sep 17 00:00:00 2001 From: Horst Birthelmer Date: Wed, 19 Aug 2026 09:22:12 +0200 Subject: [PATCH 3/5] fuse: drop the expansion zero-fill Read-modify-writes of blocks past the server EOF go back to reading: the zero-fill needed fi->server_size verified against every recorded write grant, and the verification GETATTRs are server traffic and complexity the saved READs are not worth. Partial pages of expanding writes will be sent as separate FUSE_WRITE requests instead, which needs no read-modify-write at all. Remove the fi->server_size bound with its grow and shrink sites, the grant verification debt, and the zero-fill in fuse_iomap_read_folio_range(). Signed-off-by: Horst Birthelmer --- fs/fuse/dir.c | 8 ------- fs/fuse/file.c | 57 ------------------------------------------------ fs/fuse/fuse_i.h | 14 ------------ fs/fuse/inode.c | 16 -------------- 4 files changed, 95 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 096e0953cdcbca..5f426228f4c76a 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -2129,7 +2129,6 @@ int fuse_do_setattr(struct mnt_idmap *idmap, struct dentry *dentry, if (fc->dlm && fc->writeback_cache) fuse_dlm_cache_release_locks(fi); spin_lock(&fi->lock); - fi->server_size = 0; i_size_write(inode, 0); spin_unlock(&fi->lock); truncate_pagecache(inode, 0); @@ -2225,13 +2224,6 @@ int fuse_do_setattr(struct mnt_idmap *idmap, struct dentry *dentry, /* see the comment in fuse_change_attributes() */ if (!is_wb || is_truncate) i_size_write(inode, outarg.attr.size); - /* - * A truncate settles the size on the server; only shrink the - * server-materialized bound: growing just exposes zeros, which the - * bound need not cover (see fuse_iomap_read_folio_range()). - */ - if (is_truncate && (loff_t) outarg.attr.size < fi->server_size) - fi->server_size = outarg.attr.size; if (is_truncate) { /* NOTE: this may release/reacquire fi->lock */ diff --git a/fs/fuse/file.c b/fs/fuse/file.c index d92611094944b5..aec29b46d0dce6 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -334,7 +334,6 @@ static void fuse_truncate_update_attr(struct inode *inode, struct file *file) spin_lock(&fi->lock); fi->attr_version = atomic64_inc_return(&fc->attr_version); - fi->server_size = 0; i_size_write(inode, 0); spin_unlock(&fi->lock); file_update_time(file); @@ -1034,41 +1033,9 @@ static int fuse_iomap_read_folio_range(const struct iomap_iter *iter, struct file *file = iter->private; struct inode *inode = file_inode(file); struct fuse_conn *fc = get_fuse_conn(inode); - struct fuse_inode *fi = get_fuse_inode(inode); size_t off = offset_in_folio(folio, pos); - bool hole; int ret; - /* - * Expanding writes claim their new i_size up front (see - * fuse_cache_write_iter()), which keeps iomap's own beyond-EOF - * zeroing in iomap_block_needs_zeroing() from ever firing for the - * write's own range: every block of a file expansion would be read - * from the server although it cannot contain data. Zero-fill - * locally instead when the server is known to hold no data in the - * range and we hold the DLM write lock covering it: - * - * - fi->server_size bounds the data materialized on the server - * (writeback and direct write acknowledgements, server - * attributes), - * - local data not yet acknowledged sits in uptodate blocks, which - * iomap never passes to this callback, - * - the page-granular DLM write lock excludes data written by - * other nodes, re-checked against the live lock tree so a - * revoked lock falls back to reading. - */ - if (fc->dlm) { - spin_lock(&fi->lock); - hole = pos >= fi->server_size; - spin_unlock(&fi->lock); - - if (hole && fuse_dlm_range_is_locked(fi, pos, pos + len - 1, - FUSE_PAGE_LOCK_WRITE)) { - folio_zero_range(folio, off, len); - return 0; - } - } - ret = fuse_do_readfolio(file, folio, off, len); /* @@ -1423,15 +1390,6 @@ bool fuse_write_update_attr(struct inode *inode, loff_t pos, ssize_t written) spin_lock(&fi->lock); fi->attr_version = atomic64_inc_return(&fc->attr_version); - if (written > 0 && S_ISREG(inode->i_mode)) { - /* - * The server acknowledged data up to @pos, keep the - * server-materialized bound in sync for the expansion - * zero-fill in fuse_iomap_read_folio_range(). - */ - if (pos > fi->server_size) - fi->server_size = pos; - } if (written > 0 && pos > inode->i_size) { i_size_write(inode, pos); ret = true; @@ -2614,20 +2572,6 @@ static void fuse_writepage_end(struct fuse_mount *fm, struct fuse_args *args, if (!fc->writeback_cache) fuse_invalidate_attr_mask(inode, FUSE_STATX_MODIFY); spin_lock(&fi->lock); - if (!error) { - struct fuse_write_in *inarg = &wpa->ia.write.in; - - /* - * The server acknowledged this writeback, so data up to the - * end of the request is materialized on the server. Advance - * the bound before the folios end writeback below, i.e. - * before they can go clean and be reclaimed, so that - * fuse_iomap_read_folio_range() can never zero-fill a - * reclaimed range the server holds data in. - */ - if ((loff_t) (inarg->offset + inarg->size) > fi->server_size) - fi->server_size = inarg->offset + inarg->size; - } fi->writectr--; fuse_writepage_finish(wpa); spin_unlock(&fi->lock); @@ -3937,7 +3881,6 @@ void fuse_init_file_inode(struct inode *inode, unsigned int flags) fuse_dlm_cache_init(fi); fi->writectr = 0; fi->iocachectr = 0; - fi->server_size = 0; init_waitqueue_head(&fi->page_waitq); init_waitqueue_head(&fi->direct_io_waitq); /* diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index e44b1ddec1289c..31580b7834e296 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -202,20 +202,6 @@ struct fuse_inode { /* dlm locked areas we have sent lock requests for */ struct fuse_dlm_cache dlm_locked_areas; - /* - * Server-materialized size: an upper bound for how far - * the server holds file data. Seeded from - * server-reported attributes, advanced when the server - * acknowledges data (writeback completion, - * fuse_write_update_attr()), lowered again on - * truncate. A read-modify-write of a block starting - * at or past this bound needs no READ request under a - * held DLM write lock: the server has no data there - * (see fuse_iomap_read_folio_range()). Protected by - * fi->lock. - */ - loff_t server_size; - /* * Serializes buffered-write page-cache dirtying against * the forced-direct-IO latch transition driven by diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index e61dc0321ce598..d54676b73abf9e 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -583,13 +583,10 @@ static void fuse_change_attributes_i(struct inode *inode, struct fuse_attr *attr loff_t oldsize; struct timespec64 old_mtime; bool have_size = !sx || (sx->mask & STATX_SIZE); - u64 srv_size; cache_mask = fuse_attr_cache_mask(inode, attr, have_size); spin_lock(&fi->lock); - srv_size = attr->size; - if (cache_mask & STATX_SIZE) attr->size = i_size_read(inode); @@ -608,19 +605,6 @@ static void fuse_change_attributes_i(struct inode *inode, struct fuse_attr *attr return; } - /* - * srv_size is the size the server reported before the writeback - * cache_mask above replaced attr->size with the local value. It - * bounds how far the server can hold data, letting the iomap write - * path zero-fill expansion read-modify-writes instead of sending - * READ requests, see fuse_iomap_read_folio_range(). Only ever grow - * it here: stale attributes were rejected above and truncation - * lowers it directly. - */ - if (have_size && S_ISREG(inode->i_mode) && - (loff_t) srv_size > fi->server_size) - fi->server_size = srv_size; - old_mtime = inode_get_mtime(inode); fuse_change_attributes_common(inode, attr, sx, attr_valid, cache_mask, evict_ctr); From 495dddeae2da0ffbc5cfd793fabee140f53496fe Mon Sep 17 00:00:00 2001 From: Horst Birthelmer Date: Wed, 19 Aug 2026 09:46:19 +0200 Subject: [PATCH 4/5] fuse: write unaligned edges through to the server under DLM With the expansion zero-fill gone, every unaligned buffered write under DLM pays a read-modify-write READ per partial page, and past the server EOF that READ returns zero bytes: a wasted round trip for data that cannot exist. The write path cannot tell the wasted READ from a needed one without trusting a bound the grant may predate. Do not complete partial pages at all. Split the buffered write (fuse_dlm_buffered_write()): cache only the page-aligned interior, whole pages need no read-modify-write, and send the unaligned head and tail through the existing writethrough path (fuse_perform_write()). A partial page is written byte-exact and left non-uptodate, so nothing is read and neighbouring writers sharing a boundary page accumulate their bytes on the server. A sub-page write with no aligned interior goes fully through. The DLM write lock is taken over the whole range before i_rwsem, so all chunks are covered, and the pre-claimed i_size extension with its reconciliation keeps working on the chunk total. The read-modify-write path stays functional for the rare unaligned restart of the interior after a faulted user copy. Signed-off-by: Horst Birthelmer --- fs/fuse/file.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index aec29b46d0dce6..9377446a838e11 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1765,6 +1765,87 @@ static ssize_t fuse_writeback_write_iter(struct kiocb *iocb, return written < 0 ? written : total_written; } +/* + * Write @len bytes of @from at the current iocb position, either straight + * through to the server (@through, for an unaligned edge) or through the + * iomap page cache path (@through == false, for the aligned interior). + * Both primitives consume @len bytes from @from and advance iocb->ki_pos; + * the iterator is temporarily capped to @len so the unconsumed tail stays + * available for the next chunk. Returns bytes written (< @len means a + * short write, the caller stops) or a negative error. + */ +static ssize_t fuse_dlm_write_chunk(struct kiocb *iocb, struct iov_iter *from, + struct file *file, size_t len, bool through) +{ + size_t hidden; + ssize_t res; + + if (!len) + return 0; + + /* Cap the iterator to this chunk, keeping the tail for later chunks. */ + hidden = iov_iter_count(from) - len; + iov_iter_truncate(from, len); + res = through ? fuse_perform_write(iocb, from) + : fuse_writeback_write_iter(iocb, from, file); + /* Restore from the iterator's own residue, so short writes/errors + * (which leave it partly advanced) reexpand to the exact remainder. */ + iov_iter_reexpand(from, iov_iter_count(from) + hidden); + + return res; +} + +/* + * Buffered write under DLM. A partial page dirtied for writeback would + * have to be completed by reading the untouched remainder back from the + * server, and for a write past the server EOF that READ can only return + * zero bytes: a wasted round trip per unaligned edge. So cache only the + * page-aligned interior, whole pages need no read-modify-write, and + * route the unaligned head and tail straight through to the server. The + * writethrough path writes just those bytes and leaves the page + * non-uptodate, doing no read, and each edge lands as an independent + * FUSE_WRITE, so writers sharing a boundary page accumulate their bytes + * on the server. Aligned writes take the interior path whole; a + * sub-page write with no aligned interior goes fully through. + */ +static ssize_t fuse_dlm_buffered_write(struct kiocb *iocb, + struct iov_iter *from, + struct file *file) +{ + loff_t pos = iocb->ki_pos; + loff_t end = pos + iov_iter_count(from); + loff_t mid_start = round_up(pos, PAGE_SIZE); + loff_t mid_end = round_down(end, PAGE_SIZE); + ssize_t res, total = 0; + + /* No whole page inside the write: nothing cacheable, all through. */ + if (mid_end <= mid_start) + return fuse_perform_write(iocb, from); + + /* Unaligned head [pos, mid_start): through. */ + res = fuse_dlm_write_chunk(iocb, from, file, mid_start - pos, true); + if (res < 0) + return res; + total += res; + if (res < mid_start - pos) + return total; + + /* Aligned interior [mid_start, mid_end): cached whole pages. */ + res = fuse_dlm_write_chunk(iocb, from, file, mid_end - mid_start, false); + if (res < 0) + return total; + total += res; + if (res < mid_end - mid_start) + return total; + + /* Unaligned tail [mid_end, end): through. */ + res = fuse_dlm_write_chunk(iocb, from, file, end - mid_end, true); + if (res > 0) + total += res; + + return total; +} + static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from); /* @@ -2059,7 +2140,16 @@ static ssize_t fuse_cache_write_iter(struct kiocb *iocb, struct iov_iter *from) pagecache_isize_extended(inode, orig_size, pos); } - written = fuse_writeback_write_iter(iocb, from, file); + /* + * Under DLM the unaligned edges go through to the server + * instead of being completed by a read-modify-write READ + * (see fuse_dlm_buffered_write()); only whole pages are + * cached for writeback. + */ + if (fc->dlm) + written = fuse_dlm_buffered_write(iocb, from, file); + else + written = fuse_writeback_write_iter(iocb, from, file); /* * Reconcile the speculative extension with what was actually From de4ddbecf7f957907d43559e73342a8c42e59ad9 Mon Sep 17 00:00:00 2001 From: Horst Birthelmer Date: Thu, 20 Aug 2026 10:35:41 +0200 Subject: [PATCH 5/5] fuse: mark DLM edge writes with FUSE_WRITE_CACHE Signed-off-by: Horst Birthelmer --- fs/fuse/file.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 9377446a838e11..7c5b5e8b4ba268 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1545,7 +1545,8 @@ static inline unsigned int fuse_wr_pages(loff_t pos, size_t len, max_pages); } -static ssize_t fuse_perform_write(struct kiocb *iocb, struct iov_iter *ii) +static ssize_t fuse_perform_write(struct kiocb *iocb, struct iov_iter *ii, + bool cache) { struct address_space *mapping = iocb->ki_filp->f_mapping; struct inode *inode = mapping->host; @@ -1575,6 +1576,14 @@ static ssize_t fuse_perform_write(struct kiocb *iocb, struct iov_iter *ii) if (count <= 0) { err = count; } else { + /* + * On behalf of a buffered write whose bytes bypass + * the page cache (DLM unaligned edges): the server + * must classify them like the writeback they + * replace. + */ + if (cache) + ia.write.in.write_flags |= FUSE_WRITE_CACHE; err = fuse_send_write_pages(&ia, iocb, inode, pos, count); if (!err) { @@ -1786,7 +1795,7 @@ static ssize_t fuse_dlm_write_chunk(struct kiocb *iocb, struct iov_iter *from, /* Cap the iterator to this chunk, keeping the tail for later chunks. */ hidden = iov_iter_count(from) - len; iov_iter_truncate(from, len); - res = through ? fuse_perform_write(iocb, from) + res = through ? fuse_perform_write(iocb, from, true) : fuse_writeback_write_iter(iocb, from, file); /* Restore from the iterator's own residue, so short writes/errors * (which leave it partly advanced) reexpand to the exact remainder. */ @@ -1804,8 +1813,9 @@ static ssize_t fuse_dlm_write_chunk(struct kiocb *iocb, struct iov_iter *from, * route the unaligned head and tail straight through to the server. The * writethrough path writes just those bytes and leaves the page * non-uptodate, doing no read, and each edge lands as an independent - * FUSE_WRITE, so writers sharing a boundary page accumulate their bytes - * on the server. Aligned writes take the interior path whole; a + * FUSE_WRITE carrying FUSE_WRITE_CACHE like the writeback it replaces, + * so writers sharing a boundary page accumulate their bytes on the + * server. Aligned writes take the interior path whole; a * sub-page write with no aligned interior goes fully through. */ static ssize_t fuse_dlm_buffered_write(struct kiocb *iocb, @@ -1820,7 +1830,7 @@ static ssize_t fuse_dlm_buffered_write(struct kiocb *iocb, /* No whole page inside the write: nothing cacheable, all through. */ if (mid_end <= mid_start) - return fuse_perform_write(iocb, from); + return fuse_perform_write(iocb, from, true); /* Unaligned head [pos, mid_start): through. */ res = fuse_dlm_write_chunk(iocb, from, file, mid_start - pos, true); @@ -2099,7 +2109,8 @@ static ssize_t fuse_cache_write_iter(struct kiocb *iocb, struct iov_iter *from) if (written < 0 || !iov_iter_count(from)) goto out; written = direct_write_fallback(iocb, from, written, - fuse_perform_write(iocb, from)); + fuse_perform_write(iocb, from, + false)); } else if (writeback) { loff_t pos = iocb->ki_pos; loff_t end = pos + count; @@ -2175,7 +2186,7 @@ static ssize_t fuse_cache_write_iter(struct kiocb *iocb, struct iov_iter *from) goto out; } } else { - written = fuse_perform_write(iocb, from); + written = fuse_perform_write(iocb, from, false); } out: if (wb_guard)