[Cluster-devel] [PATCH 06/13] GFS2: Make do_xmote not call the state machine again

Bob Peterson rpeterso at redhat.com
Mon Nov 19 13:29:24 UTC 2018


Before this patch, the state machine could call do_xmote which,
in turn, could call back into the state machine. This patch unravels
the logic so instead it sends back an -EAGAIN return code, which
signals the state machine to loop under the new state.

Signed-off-by: Bob Peterson <rpeterso at redhat.com>
---
 fs/gfs2/glock.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index b541c4053dd7..8dc98d069afa 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -527,9 +527,11 @@ static int finish_xmote(struct gfs2_glock *gl)
  * @gl: The lock state
  * @target: The target lock state
  *
+ * Returns: 0 if the lock is pending, or
+ *          -EAGAIN if we need to run the state machine again to finish_xmote
  */
 
-static void do_xmote(struct gfs2_glock *gl, unsigned int target)
+static int do_xmote(struct gfs2_glock *gl, unsigned int target)
 __releases(&gl->gl_lockref.lock)
 __acquires(&gl->gl_lockref.lock)
 {
@@ -537,11 +539,11 @@ __acquires(&gl->gl_lockref.lock)
 	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
 	struct gfs2_holder *gh = find_first_waiter(gl);
 	unsigned int lck_flags = (unsigned int)(gh ? gh->gh_flags : 0);
-	int ret;
+	int ret = 0;
 
 	if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) &&
 	    target != LM_ST_UNLOCKED)
-		return;
+		return 0;
 	lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP |
 		      LM_FLAG_PRIORITY);
 	GLOCK_BUG_ON(gl, gl->gl_state == target);
@@ -572,21 +574,23 @@ __acquires(&gl->gl_lockref.lock)
 		    target == LM_ST_UNLOCKED &&
 		    test_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags)) {
 			gl->gl_reply = target;
-			state_machine(gl, GL_ST_FINISH_XMOTE);
+			ret = -EAGAIN;
 			gfs2_glock_queue_work(gl, 0);
 		}
 		else if (ret) {
 			fs_err(sdp, "lm_lock ret %d\n", ret);
 			GLOCK_BUG_ON(gl, !test_bit(SDF_SHUTDOWN,
 						   &sdp->sd_flags));
+			ret = 0;
 		}
 	} else { /* lock_nolock */
 		gl->gl_reply = target;
-		state_machine(gl, GL_ST_FINISH_XMOTE);
+		ret = -EAGAIN;
 		gfs2_glock_queue_work(gl, 0);
 	}
 
 	spin_lock(&gl->gl_lockref.lock);
+	return ret;
 }
 
 /**
@@ -698,13 +702,16 @@ static void __state_machine(struct gfs2_glock *gl, int new_state)
 
 		case GL_ST_DO_XMOTE:
 			gl->gl_mch = GL_ST_IDLE;
-			do_xmote(gl, gl->gl_target);
+			ret = do_xmote(gl, gl->gl_target);
+			if (ret == -EAGAIN)
+				gl->gl_mch = GL_ST_FINISH_XMOTE;
 			break;
 
 		case GL_ST_DO_XMOTE_UNLOCK:
 			gl->gl_mch = GL_ST_IDLE;
-			do_xmote(gl, LM_ST_UNLOCKED);
-			finish_xmote(gl);
+			ret = do_xmote(gl, LM_ST_UNLOCKED);
+			if (ret == -EAGAIN)
+				gl->gl_mch = GL_ST_FINISH_XMOTE;
 			break;
 		}
 	} while (gl->gl_mch != GL_ST_IDLE);
-- 
2.19.1




More information about the Cluster-devel mailing list