[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