[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