aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fscache/object.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fscache/object.c')
-rw-r--r--fs/fscache/object.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/fs/fscache/object.c b/fs/fscache/object.c
index 773bc798a416..80b549141ea6 100644
--- a/fs/fscache/object.c
+++ b/fs/fscache/object.c
@@ -14,6 +14,7 @@
14 14
15#define FSCACHE_DEBUG_LEVEL COOKIE 15#define FSCACHE_DEBUG_LEVEL COOKIE
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/slab.h>
17#include "internal.h" 18#include "internal.h"
18 19
19const char *fscache_object_states[FSCACHE_OBJECT__NSTATES] = { 20const char *fscache_object_states[FSCACHE_OBJECT__NSTATES] = {
@@ -22,6 +23,7 @@ const char *fscache_object_states[FSCACHE_OBJECT__NSTATES] = {
22 [FSCACHE_OBJECT_CREATING] = "OBJECT_CREATING", 23 [FSCACHE_OBJECT_CREATING] = "OBJECT_CREATING",
23 [FSCACHE_OBJECT_AVAILABLE] = "OBJECT_AVAILABLE", 24 [FSCACHE_OBJECT_AVAILABLE] = "OBJECT_AVAILABLE",
24 [FSCACHE_OBJECT_ACTIVE] = "OBJECT_ACTIVE", 25 [FSCACHE_OBJECT_ACTIVE] = "OBJECT_ACTIVE",
26 [FSCACHE_OBJECT_INVALIDATING] = "OBJECT_INVALIDATING",
25 [FSCACHE_OBJECT_UPDATING] = "OBJECT_UPDATING", 27 [FSCACHE_OBJECT_UPDATING] = "OBJECT_UPDATING",
26 [FSCACHE_OBJECT_DYING] = "OBJECT_DYING", 28 [FSCACHE_OBJECT_DYING] = "OBJECT_DYING",
27 [FSCACHE_OBJECT_LC_DYING] = "OBJECT_LC_DYING", 29 [FSCACHE_OBJECT_LC_DYING] = "OBJECT_LC_DYING",
@@ -39,6 +41,7 @@ const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5] = {
39 [FSCACHE_OBJECT_CREATING] = "CRTN", 41 [FSCACHE_OBJECT_CREATING] = "CRTN",
40 [FSCACHE_OBJECT_AVAILABLE] = "AVBL", 42 [FSCACHE_OBJECT_AVAILABLE] = "AVBL",
41 [FSCACHE_OBJECT_ACTIVE] = "ACTV", 43 [FSCACHE_OBJECT_ACTIVE] = "ACTV",
44 [FSCACHE_OBJECT_INVALIDATING] = "INVL",
42 [FSCACHE_OBJECT_UPDATING] = "UPDT", 45 [FSCACHE_OBJECT_UPDATING] = "UPDT",
43 [FSCACHE_OBJECT_DYING] = "DYNG", 46 [FSCACHE_OBJECT_DYING] = "DYNG",
44 [FSCACHE_OBJECT_LC_DYING] = "LCDY", 47 [FSCACHE_OBJECT_LC_DYING] = "LCDY",
@@ -54,6 +57,7 @@ static void fscache_put_object(struct fscache_object *);
54static void fscache_initialise_object(struct fscache_object *); 57static void fscache_initialise_object(struct fscache_object *);
55static void fscache_lookup_object(struct fscache_object *); 58static void fscache_lookup_object(struct fscache_object *);
56static void fscache_object_available(struct fscache_object *); 59static void fscache_object_available(struct fscache_object *);
60static void fscache_invalidate_object(struct fscache_object *);
57static void fscache_release_object(struct fscache_object *); 61static void fscache_release_object(struct fscache_object *);
58static void fscache_withdraw_object(struct fscache_object *); 62static void fscache_withdraw_object(struct fscache_object *);
59static void fscache_enqueue_dependents(struct fscache_object *); 63static void fscache_enqueue_dependents(struct fscache_object *);
@@ -79,6 +83,15 @@ static inline void fscache_done_parent_op(struct fscache_object *object)
79} 83}
80 84
81/* 85/*
86 * Notify netfs of invalidation completion.
87 */
88static inline void fscache_invalidation_complete(struct fscache_cookie *cookie)
89{
90 if (test_and_clear_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags))
91 wake_up_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING);
92}
93
94/*
82 * process events that have been sent to an object's state machine 95 * process events that have been sent to an object's state machine
83 * - initiates parent lookup 96 * - initiates parent lookup
84 * - does object lookup 97 * - does object lookup
@@ -125,6 +138,16 @@ static void fscache_object_state_machine(struct fscache_object *object)
125 case FSCACHE_OBJECT_ACTIVE: 138 case FSCACHE_OBJECT_ACTIVE:
126 goto active_transit; 139 goto active_transit;
127 140
141 /* Invalidate an object on disk */
142 case FSCACHE_OBJECT_INVALIDATING:
143 clear_bit(FSCACHE_OBJECT_EV_INVALIDATE, &object->events);
144 fscache_stat(&fscache_n_invalidates_run);
145 fscache_stat(&fscache_n_cop_invalidate_object);
146 fscache_invalidate_object(object);
147 fscache_stat_d(&fscache_n_cop_invalidate_object);
148 fscache_raise_event(object, FSCACHE_OBJECT_EV_UPDATE);
149 goto active_transit;
150
128 /* update the object metadata on disk */ 151 /* update the object metadata on disk */
129 case FSCACHE_OBJECT_UPDATING: 152 case FSCACHE_OBJECT_UPDATING:
130 clear_bit(FSCACHE_OBJECT_EV_UPDATE, &object->events); 153 clear_bit(FSCACHE_OBJECT_EV_UPDATE, &object->events);
@@ -275,6 +298,9 @@ active_transit:
275 case FSCACHE_OBJECT_EV_ERROR: 298 case FSCACHE_OBJECT_EV_ERROR:
276 new_state = FSCACHE_OBJECT_DYING; 299 new_state = FSCACHE_OBJECT_DYING;
277 goto change_state; 300 goto change_state;
301 case FSCACHE_OBJECT_EV_INVALIDATE:
302 new_state = FSCACHE_OBJECT_INVALIDATING;
303 goto change_state;
278 case FSCACHE_OBJECT_EV_UPDATE: 304 case FSCACHE_OBJECT_EV_UPDATE:
279 new_state = FSCACHE_OBJECT_UPDATING; 305 new_state = FSCACHE_OBJECT_UPDATING;
280 goto change_state; 306 goto change_state;
@@ -679,6 +705,7 @@ static void fscache_withdraw_object(struct fscache_object *object)
679 if (object->cookie == cookie) { 705 if (object->cookie == cookie) {
680 hlist_del_init(&object->cookie_link); 706 hlist_del_init(&object->cookie_link);
681 object->cookie = NULL; 707 object->cookie = NULL;
708 fscache_invalidation_complete(cookie);
682 detached = true; 709 detached = true;
683 } 710 }
684 spin_unlock(&cookie->lock); 711 spin_unlock(&cookie->lock);
@@ -888,3 +915,48 @@ enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
888 return result; 915 return result;
889} 916}
890EXPORT_SYMBOL(fscache_check_aux); 917EXPORT_SYMBOL(fscache_check_aux);
918
919/*
920 * Asynchronously invalidate an object.
921 */
922static void fscache_invalidate_object(struct fscache_object *object)
923{
924 struct fscache_operation *op;
925 struct fscache_cookie *cookie = object->cookie;
926
927 _enter("{OBJ%x}", object->debug_id);
928
929 /* Reject any new read/write ops and abort any that are pending. */
930 fscache_invalidate_writes(cookie);
931 clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags);
932 fscache_cancel_all_ops(object);
933
934 /* Now we have to wait for in-progress reads and writes */
935 op = kzalloc(sizeof(*op), GFP_KERNEL);
936 if (!op) {
937 fscache_raise_event(object, FSCACHE_OBJECT_EV_ERROR);
938 _leave(" [ENOMEM]");
939 return;
940 }
941
942 fscache_operation_init(op, object->cache->ops->invalidate_object, NULL);
943 op->flags = FSCACHE_OP_ASYNC | (1 << FSCACHE_OP_EXCLUSIVE);
944
945 spin_lock(&cookie->lock);
946 if (fscache_submit_exclusive_op(object, op) < 0)
947 BUG();
948 spin_unlock(&cookie->lock);
949 fscache_put_operation(op);
950
951 /* Once we've completed the invalidation, we know there will be no data
952 * stored in the cache and thus we can reinstate the data-check-skip
953 * optimisation.
954 */
955 set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
956
957 /* We can allow read and write requests to come in once again. They'll
958 * queue up behind our exclusive invalidation operation.
959 */
960 fscache_invalidation_complete(cookie);
961 _leave("");
962}