[RFC PATCH 27/76] fscache: Keep track of size of a file last set independently on the server

From: David Howells
Date: Fri Nov 20 2020 - 10:09:41 EST


Keep track of the size of a file that we're caching as last set
independently on the server by another client. As long as this does not
change, we can make the assumption that anything over that boundary, if not
represented in the local cache, will not be represented on the server
either and can be just cleared rather than being read, thereby saving a
trip to the server.

This only works if we make space in the cache by zapping whole files and
not just punching bits out of them as if we write to the server but don't
keep a copy in the cache, the assumption mentioned above no longer holds
true.

We also need to update this size when invalidation occurs.

Signed-off-by: David Howells <dhowells@xxxxxxxxxx>
---

fs/afs/inode.c | 2 +-
fs/fscache/cookie.c | 6 +++++-
include/linux/fscache.h | 8 +++++---
3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index df999d703e2b..0ba2815f8152 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -569,7 +569,7 @@ static void afs_zap_data(struct afs_vnode *vnode)
_enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode);

#ifdef CONFIG_AFS_FSCACHE
- fscache_invalidate(vnode->cache);
+ fscache_invalidate(vnode->cache, i_size_read(&vnode->vfs_inode));
#endif

/* nuke all the non-dirty pages that aren't locked, mapped or being
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
index e6b87596b1d0..230025a1495c 100644
--- a/fs/fscache/cookie.c
+++ b/fs/fscache/cookie.c
@@ -159,6 +159,7 @@ struct fscache_cookie *fscache_alloc_cookie(
cookie->key_len = index_key_len;
cookie->aux_len = aux_data_len;
cookie->object_size = object_size;
+ cookie->zero_point = object_size;
strlcpy(cookie->type_name, type_name, sizeof(cookie->type_name));

if (fscache_set_key(cookie, index_key, index_key_len) < 0)
@@ -532,7 +533,7 @@ void fscache_set_cookie_stage(struct fscache_cookie *cookie,
/*
* Invalidate an object. Callable with spinlocks held.
*/
-void __fscache_invalidate(struct fscache_cookie *cookie)
+void __fscache_invalidate(struct fscache_cookie *cookie, loff_t new_size)
{
struct fscache_object *object = NULL;

@@ -548,6 +549,9 @@ void __fscache_invalidate(struct fscache_cookie *cookie)
ASSERTCMP(cookie->type, ==, FSCACHE_COOKIE_TYPE_DATAFILE);

spin_lock(&cookie->lock);
+ cookie->object_size = new_size;
+ cookie->zero_point = new_size;
+
if (!hlist_empty(&cookie->backing_objects))
object = hlist_entry(cookie->backing_objects.first,
struct fscache_object, cookie_link);
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
index 3cd18ddc3903..8d47c7a08456 100644
--- a/include/linux/fscache.h
+++ b/include/linux/fscache.h
@@ -118,6 +118,7 @@ struct fscache_cookie {
struct list_head proc_link; /* Link in proc list */
char type_name[8]; /* Cookie type name */
loff_t object_size; /* Size of the netfs object */
+ loff_t zero_point; /* Size after which no data on server */

unsigned long flags;
#define FSCACHE_COOKIE_RELINQUISHED 6 /* T if cookie has been relinquished */
@@ -201,7 +202,7 @@ extern int __fscache_begin_operation(struct fscache_cookie *, struct fscache_op_
enum fscache_want_stage);
extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool);
extern void __fscache_update_cookie(struct fscache_cookie *, const void *, const loff_t *);
-extern void __fscache_invalidate(struct fscache_cookie *);
+extern void __fscache_invalidate(struct fscache_cookie *, loff_t);

/**
* fscache_register_netfs - Register a filesystem as desiring caching services
@@ -427,6 +428,7 @@ void fscache_unpin_cookie(struct fscache_cookie *cookie)
/**
* fscache_invalidate - Notify cache that an object needs invalidation
* @cookie: The cookie representing the cache object
+ * @size: The revised size of the object.
*
* Notify the cache that an object is needs to be invalidated and that it
* should abort any retrievals or stores it is doing on the cache. The object
@@ -438,10 +440,10 @@ void fscache_unpin_cookie(struct fscache_cookie *cookie)
* description.
*/
static inline
-void fscache_invalidate(struct fscache_cookie *cookie)
+void fscache_invalidate(struct fscache_cookie *cookie, loff_t size)
{
if (fscache_cookie_valid(cookie))
- __fscache_invalidate(cookie);
+ __fscache_invalidate(cookie, size);
}

/**