[Linux-cachefs] [PATCH 2/3] fscache: new osm state for handling abort after parent is ready
Jeff Layton
jlayton at kernel.org
Fri Oct 25 12:18:46 UTC 2019
After basic initialization of an fscache object, the oob_table is set
to fscache_osm_init_oob. Eventually though, we'll wait on the parent to
be ready and at that point, fscache_osm_init_oob is not sufficient to
unwind the current state of the object.
Fix this by having fscache_parent_ready set the oob_table to a new
state that properly releases the parent and then transitions to the
ABORT_INIT state to finish the cleanup.
Signed-off-by: Jeff Layton <jlayton at kernel.org>
---
fs/fscache/object.c | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/fs/fscache/object.c b/fs/fscache/object.c
index a42b206c0659..51f2991fed3f 100644
--- a/fs/fscache/object.c
+++ b/fs/fscache/object.c
@@ -15,6 +15,7 @@
#include "internal.h"
static const struct fscache_state *fscache_abort_initialisation(struct fscache_object *, int);
+static const struct fscache_state *fscache_abort_parent(struct fscache_object *, int);
static const struct fscache_state *fscache_kill_dependents(struct fscache_object *, int);
static const struct fscache_state *fscache_drop_object(struct fscache_object *, int);
static const struct fscache_state *fscache_initialise_object(struct fscache_object *, int);
@@ -75,6 +76,7 @@ static const struct fscache_state *fscache_object_dead(struct fscache_object *,
*/
static WORK_STATE(INIT_OBJECT, "INIT", fscache_initialise_object);
static WORK_STATE(PARENT_READY, "PRDY", fscache_parent_ready);
+static WORK_STATE(ABORT_PARENT, "ABTP", fscache_abort_parent);
static WORK_STATE(ABORT_INIT, "ABRT", fscache_abort_initialisation);
static WORK_STATE(LOOK_UP_OBJECT, "LOOK", fscache_look_up_object);
static WORK_STATE(CREATE_OBJECT, "CRTO", fscache_look_up_object);
@@ -120,6 +122,13 @@ static const struct fscache_transition fscache_osm_init_oob[] = {
{ 0, NULL }
};
+static const struct fscache_transition fscache_osm_parent_oob[] = {
+ TRANSIT_TO(ABORT_PARENT,
+ (1 << FSCACHE_OBJECT_EV_ERROR) |
+ (1 << FSCACHE_OBJECT_EV_KILL)),
+ { 0, NULL }
+};
+
static const struct fscache_transition fscache_osm_lookup_oob[] = {
TRANSIT_TO(LOOKUP_FAILURE,
(1 << FSCACHE_OBJECT_EV_ERROR) |
@@ -350,9 +359,7 @@ static inline void fscache_mark_object_dead(struct fscache_object *object)
spin_unlock(&object->lock);
}
-/*
- * Abort object initialisation before we start it.
- */
+/* Abort object initialisation before we start it. */
static const struct fscache_state *fscache_abort_initialisation(struct fscache_object *object,
int event)
{
@@ -363,6 +370,15 @@ static const struct fscache_state *fscache_abort_initialisation(struct fscache_o
return transit_to(KILL_OBJECT);
}
+/* Abort object init after the parent is ready. */
+static const struct fscache_state *fscache_abort_parent(struct fscache_object *object,
+ int event)
+{
+ _enter("{OBJ%x},%d", object->debug_id, event);
+ fscache_done_parent_op(object);
+ return transit_to(ABORT_INIT);
+}
+
/*
* initialise an object
* - check the specified object's parent to see if we can make use of it
@@ -434,6 +450,8 @@ static const struct fscache_state *fscache_parent_ready(struct fscache_object *o
ASSERT(parent != NULL);
+ object->oob_table = fscache_osm_parent_oob;
+
spin_lock(&parent->lock);
parent->n_ops++;
parent->n_obj_ops++;
--
2.21.0
More information about the Linux-cachefs
mailing list