summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2026-10-08 19:16:34 +0100
committerChristian Brauner <brauner@kernel.org>2026-10-16 11:02:26 +0200
commitb6134f76740497004f72954ae67bd4ba45d2f044 (patch)
tree1fc99382d13d2a5efae38f0a47f8170861c92211 /include
parent9310c6d7cdbbce55c254c935862fd66dc26a730a (diff)
downloadlinux-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.h2
-rw-r--r--include/linux/fscache.h11
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);
}
/**