diff options
| author | David Howells <dhowells@redhat.com> | 2026-10-08 19:16:34 +0100 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2026-10-16 11:02:26 +0200 |
| commit | b6134f76740497004f72954ae67bd4ba45d2f044 (patch) | |
| tree | 1fc99382d13d2a5efae38f0a47f8170861c92211 /include | |
| parent | 9310c6d7cdbbce55c254c935862fd66dc26a730a (diff) | |
| download | linux-next-b6134f76740497004f72954ae67bd4ba45d2f044.tar.gz linux-next-b6134f76740497004f72954ae67bd4ba45d2f044.zip | |
fscache, cachefiles: Fix resize handling
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>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/fscache-cache.h | 2 | ||||
| -rw-r--r-- | include/linux/fscache.h | 11 |
2 files changed, 7 insertions, 6 deletions
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index ee524c863fa9..2b83ffa4510e 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -67,7 +67,7 @@ struct fscache_cache_ops { /* Change the size of a data object */ void (*resize_cookie)(struct netfs_cache_resources *cres, - uoff_t new_size); + uoff_t new_size, bool shrank); /* Invalidate an object */ bool (*invalidate_cookie)(struct fscache_cookie *cookie); diff --git a/include/linux/fscache.h b/include/linux/fscache.h index f2d958bd1f48..ecd14d645690 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -184,7 +184,7 @@ extern struct fscache_cookie *__fscache_acquire_cookie( extern void __fscache_use_cookie(struct fscache_cookie *, bool); extern void __fscache_unuse_cookie(struct fscache_cookie *, const void *, const uoff_t *); extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool); -extern void __fscache_resize_cookie(struct fscache_cookie *, uoff_t); +void __fscache_resize_cookie(struct fscache_cookie *cookie, uoff_t new_size, bool shrank); extern void __fscache_invalidate(struct fscache_cookie *, const void *, uoff_t, unsigned int); extern int __fscache_begin_read_operation(struct netfs_cache_resources *, struct fscache_cookie *); extern int __fscache_begin_write_operation(struct netfs_cache_resources *, struct fscache_cookie *); @@ -394,8 +394,9 @@ void fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data, /** * fscache_resize_cookie - Request that a cache object be resized - * @cookie: The cookie representing the cache object - * @new_size: The new size of the object (may be NULL) + * @cookie: The cookie representing the cache object (may be NULL) + * @new_size: The new size of the object + * @shrank: True if the file shrank; false if it expanded * * Request that the size of an object be changed. * @@ -403,10 +404,10 @@ void fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data, * description. */ static inline -void fscache_resize_cookie(struct fscache_cookie *cookie, uoff_t new_size) +void fscache_resize_cookie(struct fscache_cookie *cookie, uoff_t new_size, bool shrank) { if (fscache_cookie_enabled(cookie)) - __fscache_resize_cookie(cookie, new_size); + __fscache_resize_cookie(cookie, new_size, shrank); } /** |
