summaryrefslogtreecommitdiff
path: root/fs/netfs
AgeCommit message (Collapse)Author
2 daysfscache, cachefiles: Fix resize handlingDavid Howells
Fix the resize handling in fscache and cachefiles by passing down a flag to indicate if the file is being shrunk as the cache's idea of how big the file should be may be stale and thus not useful in comparison to the object's size. The issue is that netfs_perform_write() updates the network filesystem's file's i_size as it adds data to the pagecache, but the cache isn't updated until writeback flushes that data. A truncation may then scrap that data and so the cache never sees it and doesn't update before it is told to resize. In the resize, cachefiles was comparing the new size against the current cache size and then thinking the file was being expanded. Note that this is a bit more complicated for ceph than other filesystems as ceph splits the truncation of the local pagecache and fscache to after the RPC reply handler has updated the inode record - the reply handler communicates the need for the truncation finalisation through ceph inode flags. To this end, ceph is changed such that the outstanding truncation count in the inode turns into a bool and just set instead of being incremented (the code only cares if it's zero or non-zero) and then a second bool is added to record if the file was being shrunk. Reported-by: Marc Dionne <marc.dionne@auristor.com> Fixes: 1a9fe4b6e787 ("cachefiles: Don't rely on backing fs storage map for most use cases") Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/1091807.1791483394@warthog.procyon.org.uk Reviewed-by: Alex Markuze <amarkuze@redhat.com> cc: Ilya Dryomov <idryomov@gmail.com> cc: Alex Markuze <amarkuze@redhat.com> cc: Viacheslav Dubeyko <slava@dubeyko.com> cc: Paulo Alcantara <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: v9fs@lists.linux.dev cc: linux-afs@lists.infradead.org cc: ceph-devel@vger.kernel.org cc: linux-cifs@vger.kernel.org cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2 dayscachefiles: Fix unset error when calling netfs_prepare_write_failed()David Howells
Fix cachefiles to set subreq->error before calling netfs_prepare_write_failed() otherwise netfslib will try (and fail) to retry the subrequest (it shouldn't retry writes to the cache, but rather abandon them). This causes it to hang waiting for the request to complete. Reported-by: Marc Dionne <marc.dionne@auristor.com> Fixes: 1a9fe4b6e787 ("cachefiles: Don't rely on backing fs storage map for most use cases") Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/3227746.1790772118@warthog.procyon.org.uk Tested-by: Marc Dionne <marc.dionne@auristor.com> cc: Paulo Alcantara <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: linux-cifs@vger.kernel.org cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2 daysnetfs: remove unused fscache_internal.h headerEthan Nelson-Moore
fs/netfs/fscache_internal.h has been unused since commit 915cd30cdea8 ("netfs, fscache: Combine fscache with netfs"). Remove it. Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com> Link: https://patch.msgid.link/20260918024040.338737-1-enelsonmoore@gmail.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2 dayscachefiles: Don't rely on backing fs storage map for most use casesDavid Howells
Cachefiles currently uses the backing filesystem's idea of what data is held in a backing file and queries this by means of SEEK_DATA and SEEK_HOLE. However, this means it does two seek operations on the backing file for each individual read call it wants to prepare (unless the first returns -ENXIO). Worse, the backing filesystem is at liberty to insert or remove blocks of zeros in order to optimise its layout which may cause false positives and false negatives. The problem is that keeping track of what is dirty is tricky (if storing info in xattrs, which may have limited capacity and must be read and written as one piece) and expensive (in terms of diskspace at least) and is basically duplicating what a filesystem does. However, the most common write case, in which the application does { open(O_TRUNC); write(); write(); ... write(); close(); } where each write follows directly on from the previous and leaves no gaps in the file is reasonably easy to detect and can be noted in the primary xattr as CACHEFILES_CONTENT_ALL, indicating we have everything up to the object size stored. In this specific case, given that it is known that there are no holes in the file, there's no need to call SEEK_DATA/HOLE or use any other mechanism to track the contents. That speeds things up enormously. Even when it is necessary to use SEEK_DATA/HOLE, it may not be necessary to call it for each cache read subrequest generated. Implement this by adding support for the CACHEFILES_CONTENT_ALL content type (which is defined, but currently unused), which requires a slight adjustment in how backing files are managed. Specifically, the driver needs to know how much of the tail block is data and whether storing more data will create a hole. To this end, the way that the size of a backing file is managed is changed. Currently, the backing file is expanded to strictly match the size of the network file, but this can be changed to carry more useful information. This makes two pieces of metadata available: xattr.object_size and the backing file's i_size. Apply the following schema: (a) i_size is always a multiple of the DIO block size. (b) i_size is only updated to the end of the highest write stored. This is used to work out if we are following on without leaving a hole. (c) xattr.object_size is the size of the network filesystem file cached in this backing file. (d) xattr.object_size must point after the start of the last block (unless both are 0). (e) If xattr.object_size is at or after the block at the current end of the backing file (ie. i_size), then we have all the contents of the block (if xattr.content == CACHEFILES_CONTENT_ALL). (f) If xattr.object_size is somewhere in the middle of the last block, then the data following it is invalid and must be ignored. (g) If data is added to the last block, then that block must be fetched, modified and rewritten (it must be a buffered write through the pagecache and not DIO). (h) Writes to cache are rounded out to blocks on both sides and the folios used as sources must contain data for any lower gap and must have been cleared for any upper gap, and so will rewrite any non-data area in the tail block. To implement this, the following changes are made: (1) cookie->object_size is no longer updated when writes are copied into the pagecache, but rather only updated when a write request completes. This prevents object size miscomparison when checking the xattr causing the backing file to be invalidated (opening and marking the backing file and modifying the pagecache run in parallel). (2) The cache's current idea of the amount of data that should be stored in the backing file is kept track of in object->object_size. Possibly this is redundant with cookie->object_size, but the latter gets updated in some addition circumstances. (3) The size of the backing file at the start of a request is now tracked in struct netfs_cache_resources so that the partial EOF block can be located and cleaned. (4) The cache block size is now used consistently rather than using CACHEFILES_DIO_BLOCK_SIZE (4096). (5) The backing file size is no longer adjusted when looking up an object. (6) When shortening a file, if the new size is not block aligned, the part beyond the new size is cleared. If the file is truncated to zero, the content_info gets reset to CACHEFILES_CONTENT_NO_DATA. (7) A new struct, fscache_occupancy, is instituted to track the region being read. Netfslib allocates it and fills in the start and end of the region to be read then calls the ->query_occupancy() method to find and fill in the extents. It also indicates whether a recorded extent contains data or just contains a region that's all zeros (FSCACHE_EXTENT_DATA or FSCACHE_EXTENT_ZERO). (8) The ->prepare_read() cache method is changed such that, if given, it just limits the amount that can be read from the cache in one go. It no longer indicates what source of read should be done; that information is now obtained from ->query_occupancy(). (9) A new cache method, ->collect_write(), is added that is called when a contiguous series of writes have completed and a discontiguity or the end of the request has been hit. It it supplied with the start and length of the write made to the backing file and can use this information to update the cache metadata. (10) cachefiles_query_occupancy() is altered to find the next two "extents" of data stored in the backing file by doing SEEK_DATA/HOLE between the bounds set - unless it is known that there are no holes, in which case a whole-file first extent can be set. (11) cachefiles_collect_write() is implemented to take the collated write completion information and use this to update the cache metadata, in particular working out whether there's now a hole in the backing file requiring future use of SEEK_DATA/HOLE instead of just assuming the data is all present. It also uses fallocate(FALLOC_FL_ZERO_RANGE) to clean the part of a partial block that extended beyond the old object size. It might be better to perform a synchronous DIO write for this purpose, but that would mandate an RMW cycle. Ideally, it should be all zeros anyway, but, unfortunately, shared-writable mmap can interfere. (12) cachefiles_begin_operation() is updated to note the current backing file size and the cache DIO size. (13) cachefiles_create_tmpfile() no longer expands the backing file when it creates it. (14) cachefiles_set_object_xattr() is changed to use object->object_size rather than cookie->object_size. (15) cachefiles_check_auxdata() is altered to actually store the content type and to also set object->object_size. The cachefiles_coherency tracepoint is also modified to display xattr.object_size. (16) netfs_read_to_pagecache() is reworked. The cache ->prepare_read() method is replaced with ->query_occupancy() as the arbiter of what region of the file is read from where, and that retrieves up to two occupied extents of the backing file at once. The cache ->prepare_read() method is now repurposed to be the same as the equivalent network filesystem method and allows the cache to limit the size of the read before the iterator is prepared. netfs_single_dispatch_read() is similarly modified. (17) netfs_update_i_size() and afs_update_i_size() no longer call fscache_update_cookie() to update cookie->object_size. (18) Write collection now collates contiguous sequences of writes to the cache and calls the cache ->collect_write() method. Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260910220242.2165023-5-dhowells@redhat.com Reviewed-by: Paulo Alcantara <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: linux-cifs@vger.kernel.org cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
12 daysnetfs: Set subrequest->source at alloc before trace emissionDavid Howells
Set subrequest->source in netfs_alloc_subrequest() before we emit the trace line indicating we allocated the subrequest. Note that this requires the allocation of the subreq in netfs_read_to_pagecache() to be pushed to after the decision about what sort of subreq it should be. Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260909072105.1663687-9-dhowells@redhat.com Reviewed-by: Paulo Alcantara <pc@manguebit.org> cc: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org cc: linux-mm@kvack.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
12 daysnetfs: Add some functions to wrap the all-queued handlingDavid Howells
Add some helper functions to wrap the handling of the NETFS_RREQ_ALL_QUEUED flag and to insert the appropriate barriers. Also add an smb_mb__after_atomic() after the set_bit() to make sure stuff after the set_bit() in the same thread doesn't get ordered before. Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260909072105.1663687-8-dhowells@redhat.com Reviewed-by: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
12 daysnetfs: Make deprecated PG_private_2 support opt-inDavid Howells
Make the deprecated PG_private_2 support opt-in, requiring it to be selected by the filesystems that might want to use it. Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260909072105.1663687-7-dhowells@redhat.com Reviewed-by: Paulo Alcantara <pc@manguebit.org> cc: Trond Myklebust <trondmy@kernel.org> cc: Anna Schumaker <anna@kernel.org> cc: Ilya Dryomov <idryomov@gmail.com> cc: Alex Markuze <amarkuze@redhat.com> cc: Viacheslav Dubeyko <slava@dubeyko.com> cc: netfs@lists.linux.dev cc: linux-nfs@vger.kernel.org cc: ceph-devel@vger.kernel.org cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
12 daysnetfs: Add the cache object ID to netfs_read/write tracepointsDavid Howells
Add the cache object debug ID to netfs_read/write tracepoints to make debugging easier as there's now a direct cross-reference with the cachefiles tracepoints that only log that debug ID. Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260909072105.1663687-6-dhowells@redhat.com Reviewed-by: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
12 daysnetfs: trace: Rejig a couple of the tracepointsDavid Howells
Rejig the following tracepoints: (1) Change netfs_folio to show the pfn. (2) Change netfs_collect_folio to show a folio index range rather than file position range and don't show the cleaned_to or collected_to points. Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260909072105.1663687-5-dhowells@redhat.com Reviewed-by: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
12 daysnetfs: trace: Change the "clear" folio traces to "endwb"David Howells
Change the "clear" folio traces to "endwb" as it's more obvious what it means. Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260909072105.1663687-4-dhowells@redhat.com Reviewed-by: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
12 daysnetfs: Remove the writethrough codeDavid Howells
Remove the netfs writethrough code as it's very tricky to get the locking right and it will probably deadlock if used in conjunction with Ceph snapshots because it excludes writeback for the duration, but to flush out old snapshots, it does a synchronous flush that invokes writeback. Instead, O_SYNC writes do a flush after performing the write - which is already there as the callers of netfs_perform_write() all call generic_write_sync(). Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260909072105.1663687-3-dhowells@redhat.com Reviewed-by: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
12 daysnetfs: Use uoff_t instead of unsigned long long and loff_tDavid Howells
Use uoff_t instead of unsigned long long and loff_t for file positions that can't be negative. Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260909072105.1663687-2-dhowells@redhat.com Reviewed-by: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-09-30netfs: zero the tail of a short DIO/unbuffered readPaulo Alcantara
The buffered read collector zero-fills the tail of a short read that stops below the inode's i_size (netfs_clear_unread()), so a read that races an extending write still returns the expected number of bytes. The non-buffered collector path does no such thing: it just records how much was transferred. Add the same zero-fill for the non-buffered case, gated on NETFS_SREQ_CLEAR_TAIL: a subreq's source sets that flag when a short result from it is known to be safe to treat as a hole, as opposed to NETFS_SREQ_HIT_EOF, which means the read genuinely ran off the end of the file and should be reported short as-is. Only CLEAR_TAIL should zero-fill here; a real EOF must stay a real short read. No source currently sets CLEAR_TAIL on an unbuffered/DIO subrequest, so this is inert on its own -- a following change teaches cifs to set it in the one case that needs it. Fixes: e2d46f2ec332 ("netfs: Change the read result collector to only use one work item") Reviewed-by: David Howells <dhowells@redhat.com> Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org> Cc: Christian Brauner <brauner@kernel.org> Cc: Matthew Wilcox <willy@infradead.org> Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com> Cc: Shyam Prasad N <sprasad@microsoft.com> Cc: Tom Talpey <tom@talpey.com> Cc: Bharath SM <bharathsm@microsoft.com> Cc: stable@vger.kernel.org
2026-09-30netfs: zero gaps in read-gaps folio to avoid writing back stale dataPaulo Alcantara
netfs_read_gaps() leaves gaps around a streaming write's dirty region unread on the server side, so a short/EOF response there left stale folio content that later got written back. Zero it after the read completes, not before: netfs_wait_for_read() returns rreq->transferred once ret >= 0, so build an iterator over the same bvec array the read used, advance past ret, and zero the rest. The dirty region already maps to sink pages in that array rather than the real folio, so this can't touch it, and only the actual shortfall gets zeroed instead of the whole gap upfront. Fixes: ee4cdf7ba857 ("netfs: Speed up buffered reading") Reviewed-by: David Howells <dhowells@redhat.com> Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org> Cc: Christian Brauner <brauner@kernel.org> Cc: Matthew Wilcox <willy@infradead.org> Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com> Cc: Shyam Prasad N <sprasad@microsoft.com> Cc: Tom Talpey <tom@talpey.com> Cc: Bharath SM <bharathsm@microsoft.com> Cc: stable@vger.kernel.org
2026-09-30netfs: clear post-EOF pagecache when extending a file via writePaulo Alcantara
Fix netfs to erase the contents of a hole created after the EOF by an ordinary write if dirty data has been previously left there by writes through an mmapped region. Neither the buffered nor the unbuffered/DIO write path clears that stale pagecache. Zero the tail of the folio straddling the EOF before an extending write. That is the only folio that can hold data written past the EOF through an mmap, as pages wholly beyond the EOF can't be faulted in. The folio is zeroed rather than dropped so a concurrent extending write can't lose data. Both write paths downgrade the i_rwsem to shared, so extending writes can run concurrently and the i_size read by the caller may be stale by the time the folio is locked. Re-read i_size under the folio lock and clamp the zeroed range up to it, so a racing write that already put data into the folio isn't clobbered. Wait for any writeback on the folio to finish before zeroing it so that the pagecache isn't modified while it may still be read by the transport during transmission. Honour IOCB_NOWAIT by returning -EAGAIN rather than blocking on the folio lock, on writeback, or in folio_mkclean()'s rmap walk when the folio is mapped. truncate_pagecache() can't be used here: it must be called with the i_rwsem held exclusively, but these write paths only hold it shared, and it would block unconditionally, breaking IOCB_NOWAIT. Callers that hold i_rwsem exclusively for the whole resize (truncate, setattr, fallocate, clone) exclude any genuine concurrent buffered writer, so staleness can instead be decided from the folio's dirty state, as pagecache_isize_extended() already does for filesystems that serialise writes against truncate/setattr via a single i_rwsem. Export netfs_clear_stale_post_isize() helper to handle such case. The helper is required by the CIFS client to fix generic/363. Closes: https://sashiko.dev/#/patchset/20260921230755.1133425-1-pc%40manguebit.org Fixes: 938e13a73b24 ("netfs: Implement buffered write API") Fixes: 153a9961b551 ("netfs: Implement unbuffered/DIO write support") Reviewed-by: David Howells <dhowells@redhat.com> Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org> Cc: Christian Brauner <brauner@kernel.org> Cc: Matthew Wilcox <willy@infradead.org> Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com> Cc: Shyam Prasad N <sprasad@microsoft.com> Cc: Tom Talpey <tom@talpey.com> Cc: Bharath SM <bharathsm@microsoft.com> Cc: stable@vger.kernel.org
2026-09-25netfs: Fix missing alloc tagging of direct mempool allocationsHao Ge
Commit 1d78d56c43ef ("netfs: Fix folio_queue ENOMEM in writeback by adding a mempool") added a mempool for the folio_queues and made the request, subrequest and folio_queue allocations distinguish between writeback and everything else. Writeback is part of memory reclaim and must not fail due to ENOMEM, so it allocates under GFP_NOFS through mempool_alloc(), which may dip into the pool's reserve and, if that runs empty, wait for elements to be returned. The GFP_KERNEL paths, which can return -ENOMEM to their callers, invoke the pool's ->alloc() callback directly instead. The direct call, however, skips the alloc_hooks() wrapper that the mempool_alloc() macro provides. The pool callbacks, mempool_alloc_slab() and mempool_kmalloc(), call kmem_cache_alloc_noprof() and kmalloc_noprof() and rely on current->alloc_tag having been set by the caller. With CONFIG_MEM_ALLOC_PROFILING_DEBUG=y this leads to current->alloc_tag not set WARNING: ./include/linux/alloc_tag.h:161 at __alloc_tagging_slab_alloc_hook alloc_tag was not set WARNING: ./include/linux/alloc_tag.h:166 at __alloc_tagging_slab_free_hook at allocation and free time respectively, as reported when reading files on a CIFS mount. The allocations are also missing from /proc/allocinfo. Wrap the direct ->alloc() invocations in alloc_hooks() with a new mempool_alloc_noreserve() helper in include/linux/mempool.h, next to the other alloc_hooks()-wrapped macros such as mempool_alloc(). The GFP_KERNEL paths keep their failable allocation semantics, they just get tagged now. Fixes: 1d78d56c43ef ("netfs: Fix folio_queue ENOMEM in writeback by adding a mempool") Reported-by: Erhard Furtner <erhard_f@mailbox.org> Closes: https://lore.kernel.org/all/0b004319-9ef7-437c-a4dd-174d6a9a83db@mailbox.org/ Tested-by: Erhard Furtner <erhard_f@mailbox.org> Suggested-by: Suren Baghdasaryan <surenb@google.com> Cc: stable@vger.kernel.org Signed-off-by: Hao Ge <hao.ge@linux.dev> Link: https://patch.msgid.link/20260923063759.34667-1-hao.ge@linux.dev Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-09-17netfs, afs: Fix symlink readingDavid Howells
Fix the reading of symlinks from the cache in afs by making netfslib trim the amount read down to i_size. The problem is that afs sets the size of the iterator to the size of the buffer (PAGE_SIZE) so that the cache can round the read size up to the cache's DIO size. Note that this also impacts the reading of AFS mountpoints as they're just stored as symlinks with an odd file mode. Link: https://patch.msgid.link/3912795.1789489319@warthog.procyon.org.uk Fixes: c0410adf3da6 ("afs: Fix the locking used by afs_get_link()") Reviewed-by: Paulo Alcantara <pc@manguebit.org> cc: Paulo Alcantara <pc@manguebit.org> cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-09-17netfs: Fix netfs_read_gaps() to use separate sink foliosDavid Howells
Fix netfs_read_gaps() to use separate folios rather than re-using a single sink folio to discard the unwanted data so that cifs checksum checking sees all the data that was fetched. Fixes: 7f84a7b9892d ("netfs: Make netfs_read_folio() handle streaming-write pages") Reported-by: Frank Sorenson <sorenson@redhat.com> Closes: https://lore.kernel.org/r/a385053c-1c4a-4060-a3bb-befa007ddb33@redhat.com/ Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/3228134.1789399227@warthog.procyon.org.uk Tested-by: Frank Sorenson <sorenson@redhat.com> Reviewed-by: Paulo Alcantara <pc@manguebit.org> cc: Paulo Alcantara <pc@manguebit.org> cc: Namjae Jeon <linkinjeon@kernel.org> cc: netfs@lists.linux.dev cc: linux-cifs@vger.kernel.org cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-31netfs: Fix read progress reportingDavid Howells
For really big read RPC ops that span multiple folios, netfslib allows the filesystem to give progress notifications to wake up the collector thread to do a collection of folios that have now been fetched, even if the RPC is still ongoing, thereby allowing the application to make progress. This works by taking the current rreq->cleaned_to value (which indicates which folios have been unlocked) and adding the stashed size of the next folio to it. cleaned_to, however, is subject to 64-bit tearing on a 32-bit arch. Fix this by stashing the next progress notification point as a size_t (which won't tear) to be added to rreq->start (which won't change), with the collector thread calculating that from cleaned_to plus the next folio size. Further, however, if the folios are small, the collector thread gets constantly woken up - which has a negative performance impact on the system. Fix that too by setting a minimum trigger of 256KiB or the size of the folio at the front of the queue, whichever is larger. Note that this has an issue that different subreqs have different need-to-be-cached properties; this is solved by a preceding patch that marks the property on the folios whilst issuing subreqs rather than when collecting them. Also, make sure rreq->cleaned_to is initialised up front, along with rreq->collected_to and stream->collected_to. Fixes: e2d46f2ec332 ("netfs: Change the read result collector to only use one work item") Link: https://sashiko.dev/#/patchset/20260804100224.2748935-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260827134304.2075713-10-dhowells@redhat.com Acked-by: Paulo Alcantara <pc@manguebit.org> cc: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-31netfs: Mark folios with COPY_TO_CACHE whilst issuing subreqsDavid Howells
Mark folios with NETFS_FOLIO_COPY_TO_CACHE whilst issuing subreqs rather than when collecting them. This means that the collector thread doesn't have to try and keep track of which subreqs contribute to which folios - and thus which folios will need to be copied to the cache because at least one byte wasn't in the cache. Instead, this is marked on the folios up front and the collector need only consider the folios. For PG_private_2-using filesystems, PG_private_2 is set instead of NETFS_FOLIO_COPY_TO_CACHE, but otherwise it works the same. The NETFS_RREQ_COPY_TO_CACHE is replaced with NETFS_RREQ_CANCEL_CACHING, which is now set if caching fails somewhere, thereby causing the collection thread to cancel the copy-to-cache marks on the remaining folios. Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260827134304.2075713-9-dhowells@redhat.com Acked-by: Paulo Alcantara <pc@manguebit.org> cc: Paulo Alcantara (Red Hat) <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: netfs@lists.linux.dev cc: linux-mm@kvack.org cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-31netfs: Fix readahead synchronisation issues by loading all folios upfrontDavid Howells
There are some synchronisation issues that derive from the app thread adding more folios to the rolling buffer whilst the collector thread is looking at them or trying to clear them, such as determining the setting of front_folio_order when the next folio hasn't been added yet, The reason for the rolling buffer approach is that loading the buffer upfront and then dropping all the refs just acquired is quite a slow operation, and loading progressively allows some of the cost to be deferred until after at least some of the I/O is started. Instead, a better way is to load all the folios into the rolling buffer upfront - and then drop the refs later, once the I/O is in progress. (Even better would be for the refs not to be there at all.) Fix this by changing the rolling buffer loader to load all the folios selected by the VM for readahead upfront into the folio queue. The folio queue is allocated a batch worth at a time as we don't know how many folios are involved (the readahead_control struct, alas, has a page count, not a folio count). The folio refs acquired from readahead are then dropped in bulk once the first subrequest is dispatched as it's quite a slow operation. The collector waits for NETFS_RREQ_NEED_PUT_RA_REFS to be cleared so that it doesn't unlock folios before the xarray has been scanned for them. This simplifies the buffer handling later and isn't noticeably slower as the xarray doesn't need to be modified and the folios are all already pre-locked. Fixes: ee4cdf7ba857 ("netfs: Speed up buffered reading") Link: https://sashiko.dev/#/patchset/20260824120224.504575-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260827134304.2075713-8-dhowells@redhat.com Acked-by: Paulo Alcantara <pc@manguebit.org> cc: Paulo Alcantara (Red Hat) <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: netfs@lists.linux.dev cc: linux-mm@kvack.org cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-31netfs: break unbuffered write when netfs_alloc_subrequest() failsEdward Adam Davis
syzbot reported a null-ptr-deref below [1] following a fault injection in netfs_alloc_subrequest(). [0] When netfs_alloc_subrequest() fails, subreq is NULL. Later, netfs_prepare_write() tries to initialize members of subreq(e.g., source), the issue in [1] is triggered. Let's handle the error of netfs_prepare_write() properly. [0] FAULT_INJECTION: forcing a failure. name failslab, interval 1, probability 0, space 0, times 0 Call Trace: netfs_alloc_subrequest+0x116/0x3f0 netfs_prepare_write+0x76/0x7b0 netfs_unbuffered_write+0x75c/0x2020 netfs_unbuffered_write_iter_locked+0x7d6/0xa80 netfs_unbuffered_write_iter+0x442/0x720 v9fs_file_write_iter+0xbf/0x100 vfs_write+0x6ac/0x1050 [1] KASAN: null-ptr-deref in range [0x00000000000000a8-0x00000000000000af] RIP: 0010:netfs_prepare_write+0xbc/0x7b0 fs/netfs/write_issue.c:173 Call Trace: netfs_unbuffered_write+0x75c/0x2020 fs/netfs/direct_write.c:111 netfs_unbuffered_write_iter_locked+0x7d6/0xa80 fs/netfs/direct_write.c:290 netfs_unbuffered_write_iter+0x442/0x720 fs/netfs/direct_write.c:382 v9fs_file_write_iter+0xbf/0x100 fs/9p/vfs_file.c:409 new_sync_write fs/read_write.c:595 [inline] Fixes: 288ace2f57c9 ("netfs: New writeback implementation") Reported-by: syzbot+6a13fc77eb6f0802be2d@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=6a13fc77eb6f0802be2d Tested-by: syzbot+6a13fc77eb6f0802be2d@syzkaller.appspotmail.com Signed-off-by: Edward Adam Davis <eadavis@qq.com> Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260827134304.2075713-7-dhowells@redhat.com Acked-by: Paulo Alcantara <pc@manguebit.org> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-31netfs: Fix subreq ref leakDavid Howells
Fix a subrequest ref leak in netfs_unbuffered_write() in the event that subreq->io_iter ends up zero length during preparation. Fixes: a0b4c7a49137e ("netfs: Fix unbuffered/DIO writes to dispatch subrequests in strict sequence") Link: https://sashiko.dev/#/patchset/20260824120224.504575-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260827134304.2075713-6-dhowells@redhat.com Acked-by: Paulo Alcantara <pc@manguebit.org> cc: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-31netfs: Fix i_size update for partial transferDavid Howells
Fix netfs_unbuffered_write_done() to pass the amount written to netfs_update_i_size() in the event of a partial transfer that ends in an error. That said, it might be better for the filesystem to mark the inode data as invalid and recheck it in case something like a network error occurred that prevented the reply from the server from being received. Fixes: a0b4c7a49137e ("netfs: Fix unbuffered/DIO writes to dispatch subrequests in strict sequence") Link: https://sashiko.dev/#/patchset/20260824120224.504575-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260827134304.2075713-5-dhowells@redhat.com Acked-by: Paulo Alcantara <pc@manguebit.org> cc: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-31netfs: Fix error vs transferred passed to ->ki_complete()David Howells
Fix netfs_unbuffered_write_done() to pass the amount written to ->ki_complete() rather than the error in the event of a partially complete transfer. Fixes: a0b4c7a49137e ("netfs: Fix unbuffered/DIO writes to dispatch subrequests in strict sequence") Link: https://sashiko.dev/#/patchset/20260824120224.504575-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260827134304.2075713-4-dhowells@redhat.com Acked-by: Paulo Alcantara <pc@manguebit.org> cc: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-31netfs: Fix unbuffered/DIO write partial transfer error returnDavid Howells
Fix unbuffered/DIO write to return the amount of data transferred in preference to an error if a partial transfer has been achieved, and to prefer an error stashed in the request over the one returned by netfs_unbuffered_write() (likely -EINTR or -ERESTARTSYS). Fixes: a0b4c7a49137e ("netfs: Fix unbuffered/DIO writes to dispatch subrequests in strict sequence") Link: https://sashiko.dev/#/patchset/20260824120224.504575-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260827134304.2075713-3-dhowells@redhat.com Acked-by: Paulo Alcantara <pc@manguebit.org> cc: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-31netfs: Fix uninitialized return value in netfs_unbuffered_write()Karl Mehltretter
If preparation of the first subrequest fails, netfs_unbuffered_write() exits its loop before ret is initialized. The empty-iterator check can do the same. For synchronous writes, netfs_unbuffered_write_iter_locked() may then return an unrelated error instead of wreq->error. This is reachable through CIFS if cifs_prepare_write() fails to reopen the file or obtain credits. Initialize ret to 0 so the caller returns wreq->error if no data was written, or the number of bytes already written otherwise. Found with Clang's -Wconditional-uninitialized. Fixes: a0b4c7a49137e ("netfs: Fix unbuffered/DIO writes to dispatch subrequests in strict sequence") Cc: stable@vger.kernel.org Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com> Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260827134304.2075713-2-dhowells@redhat.com Acked-by: Paulo Alcantara <pc@manguebit.org> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-28netfs: Fix folio_queue ENOMEM in writeback by adding a mempoolDavid Howells
Fix the handling of folio_queue allocation failure in writeback by adding a mempool and passing in gfp_t flags to the rolling buffer functions that allocate memory, using the mempool if gfp != GFP_KERNEL. This is then extended upwards and the gfp to be used for a request is stored in the netfs_io_request struct and is then used for both requests and subrequests, eliminating the sleeping loops there. The failure caused: folio != NULL WARNING: fs/netfs/write_issue.c:603 at netfs_writepages+0x883/0xa10 fs/netfs/write_issue.c:603, CPU#3: syz.0.17/5919 Fixes: cd0277ed0c18 ("netfs: Use new folio_queue data type and iterator instead of xarray iter") Reported-by: syzbot+0da43efa72f88bd3a8af@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=0da43efa72f88bd3a8af Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260727130716.1099906-5-dhowells@redhat.com Tested-by: syzbot+0da43efa72f88bd3a8af@syzkaller.appspotmail.com cc: Paulo Alcantara <pc@manguebit.org> cc: Yun Zhou <yun.zhou@windriver.com> cc: Matthew Wilcox <willy@infradead.org> cc: Christoph Hellwig <hch@infradead.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-28netfs: release readahead folios on iterator preparation failureYichong Chen
netfs_prepare_read_iterator() batches readahead folios in put_batch so that the folio references can be dropped after the I/O iterator has been prepared. If rolling_buffer_load_from_ra() fails after earlier folios have been batched, the function returns immediately and leaves those references held. Release the batch before returning the error. Fixes: 06fa229ceb36 ("netfs: Abstract out a rolling folio buffer implementation") Signed-off-by: Yichong Chen <chenyichong@uniontech.com> Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260727130716.1099906-4-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-28netfs: handle single writeback rolling buffer allocation failureYichong Chen
netfs_write_folio_single() takes an extra folio reference before appending the folio to the rolling buffer. rolling_buffer_append() can fail if it cannot allocate another folio_queue. Check the return value and drop the extra folio reference before returning the error. Fixes: 49866ce7ea8d ("netfs: Add support for caching single monolithic objects such as AFS dirs") Signed-off-by: Yichong Chen <chenyichong@uniontech.com> Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260727130716.1099906-3-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-28netfs: clear PG_private_2 on copy-to-cache append failureYichong Chen
netfs_pgpriv2_copy_to_cache() marks the folio with PG_private_2 before netfs_pgpriv2_copy_folio() appends it to the copy-to-cache rolling buffer. If the append fails, the folio is not queued for cache writeback, so the PG_private_2 state and its reference must be released immediately. Fixes: e2d46f2ec332 ("netfs: Change the read result collector to only use one work item") Signed-off-by: Yichong Chen <chenyichong@uniontech.com> Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260727130716.1099906-2-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-03netfs: Fix barriering when walking subrequest listDavid Howells
Fix the barriering used when walking the subrequest list in retry as there's a possibility of seeing a subreq that's just been added by the application thread. Fixes: ee4cdf7ba857 ("netfs: Speed up buffered reading") Fixes: 288ace2f57c9 ("netfs: New writeback implementation") Link: https://sashiko.dev/#/patchset/20260608145432.681865-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/138807.1782980582@warthog.procyon.org.uk Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> cc: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-01netfs: Fix DIO write retry for filesystems without a ->prepare_write()David Howells
Fix netfs_unbuffered_write() so that it doesn't re-issue a write twice when the filesystem doesn't have a ->prepare_write(). The resetting of the iterator and the call to netfs_reissue_write() should just be removed as almost everything it does is done again when the loop it's in goes back to the top. It does, however, still need the IN_PROGRESS flag setting, so that (and the stat inc) are moved out of the if-statement. Further, the MADE_PROGRESS flags should be cleared and wreq->transferred should be updated, so fix those too. Reported-by: syzbot+3c74b1f0c372e98efc32@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=3c74b1f0c372e98efc32 Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260625140640.3116900-16-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: hongao <hongao@uniontech.com> cc: ChenXiaoSong <chenxiaosong@chenxiaosong.com> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-01netfs: Fix folio state after ENOMEM whilst under writeback iterationDavid Howells
Fix the state of the current folio when ENOMEM occurs during writeback iteration. The folio needs to be redirtied and unlocked before the terminal writeback_iter() is invoked. Fixes: 06fa229ceb36 ("netfs: Abstract out a rolling folio buffer implementation") Link: https://sashiko.dev/#/patchset/20260619140646.2633762-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260625140640.3116900-15-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-01netfs: Fix writeback error handlingDavid Howells
Fix the error handling in writeback_iter() loop. If an error occurs, writeback_iter() needs to be called again with *error set to the error so that it can clean up iteration state. Further, the current folio needs unlocking and redirtying. Fixes: 288ace2f57c9 ("netfs: New writeback implementation") Link: https://sashiko.dev/#/patchset/20260619140646.2633762-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260625140640.3116900-14-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-01netfs: Fix writethrough to use collection offloadDavid Howells
Fix writethrough write to set NETFS_RREQ_OFFLOAD_COLLECTION on the request so that collection is processed asynchronously rather than only right at the end - and also so that asynchronous O_SYNC writes get collected at all. Fixes: 288ace2f57c9 ("netfs: New writeback implementation") Closes: https://sashiko.dev/#/patchset/20260616100821.2062304-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260625140640.3116900-13-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-01netfs: Replace wb_lock with a bit lock for asynchronicityDavid Howells
The netfs_inode::wb_lock mutex is used to prevent multiple simultaneous writebacks from fighting each other (a writeback thread will write multiple discontiguous regions within the same request). The mutex, however, only serialises the issuing of subrequests; it doesn't serialise the collection of results, and, in particular, the updating of file size information and fscache populatedness data. Unfortunately, the mutex cannot be held around the entire process as it has to be unlocked in the same thread in which it is locked - and we don't want to hold up the allocator whilst we complete the writeback. Fix this by replacing the mutex with a bit flag and a list of lock waiters so that the lock can be dropped in the collector thread after collection is complete. Link: https://sashiko.dev/#/patchset/20260608145432.681865-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260625140640.3116900-12-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-01netfs: Fix netfs_create_write_req() to handle async cache object creationDavid Howells
netfs_create_write_req() will skip caching if the fscache cookie is disabled, but this is a problem because async cache object creation might not have got far enough yet that has been enabled - thereby causing the call to fscache_begin_write_operation() to be skipped. Fix this by removing the checks on the cookie and delegating this to fscache_begin_write_operation(). Fixes: 7b589a9b45ae ("netfs: Fix handling of USE_PGPRIV2 and WRITE_TO_CACHE flags") Closes: https://sashiko.dev/#/patchset/20260624115737.2964520-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260625140640.3116900-3-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-01netfs: Fix decision whether to disallow write-streaming due to fscache useDavid Howells
netfs_perform_write() buffers data by writing it into the pagecache for later writeback. If the folio it wants to write to isn't present, it uses "write streaming" in which is will store partial data in a non-uptodate, but dirty folio. However, when fscache is in use, this is a potential problem as writes to the cache have to be aligned to the cache backend's DIO granularity, and so netfs_perform_write() attempts to suppress write-streaming in such a case, requiring the folio content to be fetched first unless the entire folio is going to be overwritten. This allows the content to be written to the cache too. Unfortunately, the test netfs_perform_write() uses isn't correct because it doesn't take into account the fact that the object lookup is asynchronous and farmed off to a work queue, so there's a short window in which the cache is doing a lookup but the test fails because the answer is undefined. This can be triggered by the generic/464 xfstest, and causes a warning to be emitted in cachefiles (in code not yet upstream) because it sees a write that doesn't have its bounds rounded out to DIO alignment. Fix this by changing the condition to whether FSCACHE_COOKIE_IS_CACHING is set on a cookie rather than whether the cookie is marked enabled. Note that this is really just a hint as to whether we allow write streaming or not and no other aspects of the cookie or cache object are accessed. Also apply the same fix to netfs_write_begin(). Reported-by: Marc Dionne <marc.dionne@auristor.com> Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260625140640.3116900-2-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-12netfs, afs: Fix write skipping in dir/link writepagesDavid Howells
Fix netfs_write_single() and afs_single_writepages() to better handle a write that would be skipped due to lock contention and WB_SYNC_NONE by returning 1 from netfs_write_single() if it skipped and making afs_single_writepages() skip also. If a skip occurs, the inode must be re-marked as the VFS may have cleared the mark. This is really only theoretical for directories in netfs_write_single() as the only path to that is through afs_single_writepages() that takes the ->validate_lock around it, thereby serialising it. Fixes: 6dd80936618c ("afs: Use netfslib for directories") Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260512123404.719402-24-dhowells@redhat.com cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-12netfs: Fix netfs_read_folio() to wait on writebackDavid Howells
Fix netfs_read_folio() to wait for an ongoing writeback to complete so that it can trust the dirty flag and whatever is attached to folio->private (folio->private may get cleaned up by the collector before it clears the writeback flag). Fixes: ee4cdf7ba857 ("netfs: Speed up buffered reading") Closes: https://sashiko.dev/#/patchset/20260414082004.3756080-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260512123404.719402-23-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-12netfs: Fix folio->private handling in netfs_perform_write()David Howells
Under some circumstances, netfs_perform_write() doesn't correctly manipulate folio->private between NULL, NETFS_FOLIO_COPY_TO_CACHE, pointing to a group and pointing to a netfs_folio struct, leading to potential multiple attachments of private data with associated folio ref leaks and also leaks of netfs_folio structs or netfs_group refs. Fix this by consolidating the place at which a folio is marked uptodate in one place and having that look at what's attached to folio->private and decide how to clean it up and then set the new group. Also, the content shouldn't be flushed if group is NULL, even if a group is specified in the netfs_group parameter, as that would be the case for a new folio. A filesystem should always specify netfs_group or never specify netfs_group. The Sashiko auto-review tool noted that it was theoretically possible that the fpos >= ctx->zero_point section might leak if it modified a streaming write folio. This is unlikely, but with a network filesystem, third party changes can happen. It also pointed out that __netfs_set_group() would leak if called multiple times on the same folio from the "whole folio modify section". Fixes: 8f52de0077ba ("netfs: Reduce number of conditional branches in netfs_perform_write()") Closes: https://sashiko.dev/#/patchset/20260414082004.3756080-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260512123404.719402-22-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-12netfs: Fix partial invalidation of streaming-write folioDavid Howells
In netfs_invalidate_folio(), if the region of a partial invalidation overlaps the front (but not all) of a dirty write cached in a streaming write page (dirty, but not uptodate, with the dirty region tracked by a netfs_folio struct), the function modifies the dirty region - but incorrectly as it moves the region forward by setting the start to the start, not the end, of the invalidation region. Fix this by setting finfo->dirty_offset to the end of the invalidation region (iend). Fixes: cce6bfa6ca0e ("netfs: Fix trimming of streaming-write folios in netfs_inval_folio()") Closes: https://sashiko.dev/#/patchset/20260414082004.3756080-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260512123404.719402-21-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-12netfs: Fix potential UAF in netfs_unlock_abandoned_read_pages()David Howells
netfs_unlock_abandoned_read_pages(rreq) accesses the index of the folios it is wanting to unlock and compares that to rreq->no_unlock_folio so that it doesn't unlock a folio being read for netfs_perform_write() or netfs_write_begin(). However, given that netfs_unlock_abandoned_read_pages() is called _after_ NETFS_RREQ_IN_PROGRESS is cleared, the one folio that it's not allowed to dereference is the one specified by ->no_unlock_folio as ownership immediately reverts to the caller. Fix this by storing the folio pointer instead and using that rather than the index. Also fix netfs_unlock_read_folio() where the same applies. Fixes: ee4cdf7ba857 ("netfs: Speed up buffered reading") Closes: https://sashiko.dev/#/patchset/20260414082004.3756080-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260512123404.719402-20-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com> cc: Matthew Wilcox <willy@infradead.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-12netfs: Fix leak of request in netfs_write_begin() error handlingDavid Howells
Fix netfs_write_begin() to not leak our ref on the request in the event that we get an error from netfs_wait_for_read(). Fixes: 4090b31422a6 ("netfs: Add a function to consolidate beginning a read") Closes: https://sashiko.dev/#/patchset/20260414082004.3756080-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260512123404.719402-19-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-12netfs: Fix early put of sink folio in netfs_read_gaps()David Howells
Fix netfs_read_gaps() to release the sink page it uses after waiting for the request to complete. The way the sink page is used is that an ITER_BVEC-class iterator is created that has the gaps from the target folio at either end, but has the sink page tiled over the middle so that a single read op can fill in both gaps. The bug was found by KASAN detecting a UAF on the generic/075 xfstest in the cifsd kernel thread that handles reception of data from the TCP socket: BUG: KASAN: use-after-free in _copy_to_iter+0x48a/0xa20 Write of size 885 at addr ffff888107f92000 by task cifsd/1285 CPU: 2 UID: 0 PID: 1285 Comm: cifsd Not tainted 7.0.0 #6 PREEMPT(lazy) Call Trace: dump_stack_lvl+0x5d/0x80 print_report+0x17f/0x4f1 kasan_report+0x100/0x1e0 kasan_check_range+0x10f/0x1e0 __asan_memcpy+0x3c/0x60 _copy_to_iter+0x48a/0xa20 __skb_datagram_iter+0x2c9/0x430 skb_copy_datagram_iter+0x6e/0x160 tcp_recvmsg_locked+0xce0/0x1130 tcp_recvmsg+0xeb/0x300 inet_recvmsg+0xcf/0x3a0 sock_recvmsg+0xea/0x100 cifs_readv_from_socket+0x3a6/0x4d0 [cifs] cifs_read_iter_from_socket+0xdd/0x130 [cifs] cifs_readv_receive+0xaad/0xb10 [cifs] cifs_demultiplex_thread+0x1148/0x1740 [cifs] kthread+0x1cf/0x210 Fixes: ee4cdf7ba857 ("netfs: Speed up buffered reading") Reported-by: Steve French <sfrench@samba.org> Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260512123404.719402-18-dhowells@redhat.com Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> cc: Paulo Alcantara <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-12netfs: Fix write streaming disablement if fd open O_RDWRDavid Howells
In netfs_perform_write(), "write streaming" (the caching of dirty data in dirty but !uptodate folios) is performed to avoid the need to read data that is just going to get immediately overwritten. However, this is/will be disabled in three circumstances: if the fd is open O_RDWR, if fscache is in use (as we need to round out the blocks for DIO) or if content encryption is enabled (again for rounding out purposes). The idea behind disabling it if the fd is open O_RDWR is that we'd need to flush the write-streaming page before we could read the data, particularly through mmap. But netfs now fills in the gaps if ->read_folio() is called on the page, so that is unnecessary. Further, this doesn't actually work if a separate fd is open for reading. Fix this by removing the check for O_RDWR, thereby allowing streaming writes even when we might read. This caused a number of problems with the generic/522 xfstest, but those are now fixed. Fixes: c38f4e96e605 ("netfs: Provide func to copy data to pagecache for buffered write") Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260512123404.719402-17-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-12netfs: Fix read-gaps to remove netfs_folio from filled folioDavid Howells
Fix netfs_read_gaps() to remove the netfs_folio record from the folio record before marking the folio uptodate if it successfully fills the gaps around the dirty data in a streaming write folio (dirty, but not uptodate). Found with: fsx -q -N 1000000 -p 10000 -o 128000 -l 600000 \ /xfstest.test/junk --replay-ops=junk.fsxops using the following as junk.fsxops: truncate 0x0 0x138b1 0x8b15d * write 0x507ee 0x10df7 0x927c0 write 0x19993 0x10e04 0x927c0 * mapwrite 0x66214 0x1a253 0x927c0 copy_range 0xb704 0x89b9 0x24429 0x79380 write 0x2402b 0x144a2 0x90660 * mapwrite 0x204d5 0x140a0 0x927c0 * copy_range 0x1f72c 0x137d0 0x7a906 0x927c0 * read 0 0x9157c 0x9157c on cifs with the default cache option. It shows folio 0x24 misbehaving if the FMODE_READ check is commented out in netfs_perform_write(): if (//(file->f_mode & FMODE_READ) || netfs_is_cache_enabled(ctx)) { and no fscache. This was initially found with the generic/522 xfstest. Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260512123404.719402-16-dhowells@redhat.com Fixes: ee4cdf7ba857 ("netfs: Speed up buffered reading") cc: Paulo Alcantara <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-12netfs: Fix potential deadlock in write-through modeDavid Howells
Fix netfs_advance_writethrough() to always unlock the supplied folio and to mark it dirty if it isn't yet written to the end. Unfortunately, it can't be marked for writeback until the folio is done with as that may cause a deadlock against mmapped reads and writes. Even though it has been marked dirty, premature writeback can't occur as the caller is holding both inode->i_rwsem (which will prevent concurrent truncation, fallocation, DIO and other writes) and ictx->wb_lock (which will cause flushing to wait and writeback to skip or wait). Note that this may be easier to deal with once the queuing of folios is split from the generation of subrequests. Fixes: 288ace2f57c9 ("netfs: New writeback implementation") Closes: https://sashiko.dev/#/patchset/20260427154639.180684-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260512123404.719402-15-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-12netfs: Fix streaming write being overwrittenDavid Howells
In order to avoid reading whilst writing, netfslib will allow "streaming writes" in which dirty data is stored directly into folios without reading them first. Such folios are marked dirty but may not be marked uptodate. If a folio is entirely written by a streaming write, uptodate will be set, otherwise it will have a netfs_folio struct attached to ->private recording the dirty region. In the event that a partially written streaming write page is to be overwritten entirely by a single write(), netfs_perform_write() will try to copy over it, but doesn't discard the netfs_folio if it succeeds; further, it doesn't correctly handle a partial copy that overwrites some of the dirty data. Fix this by the following: (1) If the folio is successfully overwritten, free the netfs_folio struct before marking the page uptodate. (2) If the copy to the folio partially fails, but short of the dirty data, just ignore the copy. (3) If the copy partially fails and overwrites some of the dirty data, accept the copy, update the netfs_folio struct to record the new data. If the folio is now filled, free the netfs_folio and set uptodate, otherwise return a partial write. Found with: fsx -q -N 1000000 -p 10000 -o 128000 -l 600000 \ /xfstest.test/junk --replay-ops=junk.fsxops using the following as junk.fsxops: truncate 0x0 0 0x927c0 write 0x63fb8 0x53c8 0 copy_range 0xb704 0x19b9 0x24429 0x79380 write 0x2402b 0x144a2 0x90660 * write 0x204d5 0x140a0 0x927c0 * copy_range 0x1f72c 0x137d0 0x7a906 0x927c0 * read 0x00000 0x20000 0x9157c read 0x20000 0x20000 0x9157c read 0x40000 0x20000 0x9157c read 0x60000 0x20000 0x9157c read 0x7e1a0 0xcfb9 0x9157c on cifs with the default cache option. It shows folio 0x24 misbehaving if the FMODE_READ check is commented out in netfs_perform_write(): if (//(file->f_mode & FMODE_READ) || netfs_is_cache_enabled(ctx)) { and no fscache. This was initially found with the generic/522 xfstest. Fixes: 8f52de0077ba ("netfs: Reduce number of conditional branches in netfs_perform_write()") Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260512123404.719402-14-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>