[Cluster-devel] [GFS2 PATCH 1/3] gfs2: cancel timed-out glock requests

Bob Peterson rpeterso at redhat.com
Mon Jan 24 17:23:55 UTC 2022


From: Andreas Gruenbacher <agruenba at redhat.com>

In the gfs2 evict code it tries to upgrade the iopen glock from SH to
EX. If the attempt to upgrade times out, gfs2 needs to tell dlm to
cancel the lock request or it can deadlock. We also need to wake up
the process waiting for the lock when dlm sends its AST back to gfs2.

Signed-off-by: Andreas Gruenbacher <agruenba at redhat.com>
Signed-off-by: Bob Peterson <rpeterso at redhat.com>
---
 fs/gfs2/glock.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index b7ab8430333c..78b0dc04c38a 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -672,6 +672,8 @@ static void finish_xmote(struct gfs2_glock *gl, unsigned int ret)
 
 	/* Check for state != intended state */
 	if (unlikely(state != gl->gl_target)) {
+		if (gh && (ret & LM_OUT_CANCELED))
+			gfs2_holder_wake(gh);
 		if (gh && !test_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags)) {
 			/* move to back of queue and try next entry */
 			if (ret & LM_OUT_CANCELED) {
@@ -1281,6 +1283,7 @@ void gfs2_holder_reinit(unsigned int state, u16 flags, struct gfs2_holder *gh)
 {
 	gh->gh_state = state;
 	gh->gh_flags = flags;
+	gh->gh_error = 0;
 	gh->gh_iflags = 0;
 	gh->gh_ip = _RET_IP_;
 	put_pid(gh->gh_owner_pid);
@@ -1694,6 +1697,14 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
 	struct gfs2_glock *gl = gh->gh_gl;
 
 	spin_lock(&gl->gl_lockref.lock);
+	if (list_is_first(&gh->gh_list, &gl->gl_holders) &&
+	    !test_bit(HIF_HOLDER, &gh->gh_iflags)) {
+		spin_unlock(&gl->gl_lockref.lock);
+		gl->gl_name.ln_sbd->sd_lockstruct.ls_ops->lm_cancel(gl);
+		wait_on_bit(&gh->gh_iflags, HIF_WAIT, TASK_UNINTERRUPTIBLE);
+		spin_lock(&gl->gl_lockref.lock);
+	}
+
 	__gfs2_glock_dq(gh);
 	spin_unlock(&gl->gl_lockref.lock);
 }
-- 
2.34.1




More information about the Cluster-devel mailing list