summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2021-10-20 17:53:34 +0300
committerDavid Howells <dhowells@redhat.com>2022-01-07 12:22:19 +0300
commitd24af13e2e2358a602740c7817ea90da43d3e740 (patch)
tree344a8b83aff3845d17f46eaa8fae751351b9a233 /include
parent12bb21a29c19aae50cfad4e2bb5c943108f34a7d (diff)
downloadlinux-d24af13e2e2358a602740c7817ea90da43d3e740.tar.xz
fscache: Implement cookie invalidation
Add a function to invalidate the cache behind a cookie: void fscache_invalidate(struct fscache_cookie *cookie, const void *aux_data, loff_t size, unsigned int flags) This causes any cached data for the specified cookie to be discarded. If the cookie is marked as being in use, a new cache object will be created if possible and future I/O will use that instead. In-flight I/O should be abandoned (writes) or reconsidered (reads). Each time it is called cookie->inval_counter is incremented and this can be used to detect invalidation at the end of an I/O operation. The coherency data attached to the cookie can be updated and the cookie size should be reset. One flag is available, FSCACHE_INVAL_DIO_WRITE, which should be used to indicate invalidation due to a DIO write on a file. This will temporarily disable caching for this cookie. Changes ======= ver #2: - Should only change to inval state if can get access to cache. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> cc: linux-cachefs@redhat.com Link: https://lore.kernel.org/r/163819602231.215744.11206598147269491575.stgit@warthog.procyon.org.uk/ # v1 Link: https://lore.kernel.org/r/163906909707.143852.18056070560477964891.stgit@warthog.procyon.org.uk/ # v2 Link: https://lore.kernel.org/r/163967107447.1823006.5945029409592119962.stgit@warthog.procyon.org.uk/ # v3 Link: https://lore.kernel.org/r/164021512640.640689.11418616313147754172.stgit@warthog.procyon.org.uk/ # v4
Diffstat (limited to 'include')
-rw-r--r--include/linux/fscache-cache.h4
-rw-r--r--include/linux/fscache.h31
-rw-r--r--include/linux/netfs.h1
-rw-r--r--include/trace/events/fscache.h25
4 files changed, 61 insertions, 0 deletions
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index ae6a75976450..1ad56bfd9d72 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
@@ -64,6 +64,9 @@ struct fscache_cache_ops {
/* Withdraw an object without any cookie access counts held */
void (*withdraw_cookie)(struct fscache_cookie *cookie);
+ /* Invalidate an object */
+ bool (*invalidate_cookie)(struct fscache_cookie *cookie);
+
/* Prepare to write to a live cache object */
void (*prepare_to_write)(struct fscache_cookie *cookie);
};
@@ -96,6 +99,7 @@ extern void fscache_put_cookie(struct fscache_cookie *cookie,
extern void fscache_end_cookie_access(struct fscache_cookie *cookie,
enum fscache_access_trace why);
extern void fscache_cookie_lookup_negative(struct fscache_cookie *cookie);
+extern void fscache_resume_after_invalidation(struct fscache_cookie *cookie);
extern void fscache_caching_failed(struct fscache_cookie *cookie);
/**
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
index e6c321e5bf73..0f36d1fac237 100644
--- a/include/linux/fscache.h
+++ b/include/linux/fscache.h
@@ -39,6 +39,8 @@ struct fscache_cookie;
#define FSCACHE_ADV_WRITE_CACHE 0x00 /* Do cache if written to locally */
#define FSCACHE_ADV_WRITE_NOCACHE 0x02 /* Don't cache if written to locally */
+#define FSCACHE_INVAL_DIO_WRITE 0x01 /* Invalidate due to DIO write */
+
/*
* Data object state.
*/
@@ -47,6 +49,7 @@ enum fscache_cookie_state {
FSCACHE_COOKIE_STATE_LOOKING_UP, /* The cache object is being looked up */
FSCACHE_COOKIE_STATE_CREATING, /* The cache object is being created */
FSCACHE_COOKIE_STATE_ACTIVE, /* The cache is active, readable and writable */
+ FSCACHE_COOKIE_STATE_INVALIDATING, /* The cache is being invalidated */
FSCACHE_COOKIE_STATE_FAILED, /* The cache failed, withdraw to clear */
FSCACHE_COOKIE_STATE_LRU_DISCARDING, /* The cookie is being discarded by the LRU */
FSCACHE_COOKIE_STATE_WITHDRAWING, /* The cookie is being withdrawn */
@@ -153,6 +156,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 loff_t *);
extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool);
+extern void __fscache_invalidate(struct fscache_cookie *, const void *, loff_t, unsigned int);
/**
* fscache_acquire_volume - Register a volume as desiring caching services
@@ -327,4 +331,31 @@ void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data
set_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &cookie->flags);
}
+/**
+ * fscache_invalidate - Notify cache that an object needs invalidation
+ * @cookie: The cookie representing the cache object
+ * @aux_data: The updated auxiliary data for the cookie (may be NULL)
+ * @size: The revised size of the object.
+ * @flags: Invalidation flags (FSCACHE_INVAL_*)
+ *
+ * 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. This
+ * increments inval_counter on the cookie which can be used by the caller to
+ * reconsider I/O requests as they complete.
+ *
+ * If @flags has FSCACHE_INVAL_DIO_WRITE set, this indicates that this is due
+ * to a direct I/O write and will cause caching to be disabled on this cookie
+ * until it is completely unused.
+ *
+ * See Documentation/filesystems/caching/netfs-api.rst for a complete
+ * description.
+ */
+static inline
+void fscache_invalidate(struct fscache_cookie *cookie,
+ const void *aux_data, loff_t size, unsigned int flags)
+{
+ if (fscache_cookie_enabled(cookie))
+ __fscache_invalidate(cookie, aux_data, size, flags);
+}
+
#endif /* _LINUX_FSCACHE_H */
diff --git a/include/linux/netfs.h b/include/linux/netfs.h
index 1ea22fc48818..5a46fde65759 100644
--- a/include/linux/netfs.h
+++ b/include/linux/netfs.h
@@ -124,6 +124,7 @@ struct netfs_cache_resources {
void *cache_priv;
void *cache_priv2;
unsigned int debug_id; /* Cookie debug ID */
+ unsigned int inval_counter; /* object->inval_counter at begin_op */
};
/*
diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h
index b0409b1fad23..294792881434 100644
--- a/include/trace/events/fscache.h
+++ b/include/trace/events/fscache.h
@@ -51,6 +51,7 @@ enum fscache_cookie_trace {
fscache_cookie_discard,
fscache_cookie_get_end_access,
fscache_cookie_get_hash_collision,
+ fscache_cookie_get_inval_work,
fscache_cookie_get_lru,
fscache_cookie_get_use_work,
fscache_cookie_new_acquire,
@@ -73,6 +74,8 @@ enum fscache_access_trace {
fscache_access_acquire_volume_end,
fscache_access_cache_pin,
fscache_access_cache_unpin,
+ fscache_access_invalidate_cookie,
+ fscache_access_invalidate_cookie_end,
fscache_access_lookup_cookie,
fscache_access_lookup_cookie_end,
fscache_access_lookup_cookie_end_failed,
@@ -116,6 +119,7 @@ enum fscache_access_trace {
EM(fscache_cookie_discard, "DISCARD ") \
EM(fscache_cookie_get_hash_collision, "GET hcoll") \
EM(fscache_cookie_get_end_access, "GQ endac") \
+ EM(fscache_cookie_get_inval_work, "GQ inval") \
EM(fscache_cookie_get_lru, "GET lru ") \
EM(fscache_cookie_get_use_work, "GQ use ") \
EM(fscache_cookie_new_acquire, "NEW acq ") \
@@ -137,6 +141,8 @@ enum fscache_access_trace {
EM(fscache_access_acquire_volume_end, "END acq_vol") \
EM(fscache_access_cache_pin, "PIN cache ") \
EM(fscache_access_cache_unpin, "UNPIN cache ") \
+ EM(fscache_access_invalidate_cookie, "BEGIN inval ") \
+ EM(fscache_access_invalidate_cookie_end,"END inval ") \
EM(fscache_access_lookup_cookie, "BEGIN lookup ") \
EM(fscache_access_lookup_cookie_end, "END lookup ") \
EM(fscache_access_lookup_cookie_end_failed,"END lookupf") \
@@ -385,6 +391,25 @@ TRACE_EVENT(fscache_relinquish,
__entry->n_active, __entry->flags, __entry->retire)
);
+TRACE_EVENT(fscache_invalidate,
+ TP_PROTO(struct fscache_cookie *cookie, loff_t new_size),
+
+ TP_ARGS(cookie, new_size),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, cookie )
+ __field(loff_t, new_size )
+ ),
+
+ TP_fast_assign(
+ __entry->cookie = cookie->debug_id;
+ __entry->new_size = new_size;
+ ),
+
+ TP_printk("c=%08x sz=%llx",
+ __entry->cookie, __entry->new_size)
+ );
+
#endif /* _TRACE_FSCACHE_H */
/* This part must be outside protection */