[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] [PATCH] RHEL fix for bz428751 try 2



Here is a second version of the cluster coherency patch.  It hasn't been
tested heavily, since it relies on 432075, and there's not complete fix
for that yet, but it have been able to run the tests coherency test
from the bugzilla to completion.  This version still has the extra
include file so that it can tested seperately from the kernel.

-Ben
diff -urpN gfs2/glock.c gfs2-patched/glock.c
--- gfs2/glock.c	2008-03-05 07:03:15.000000000 -0600
+++ gfs2-patched/glock.c	2008-03-05 07:02:37.000000000 -0600
@@ -42,6 +42,7 @@
 #include "quota.h"
 #include "super.h"
 #include "util.h"
+#include "lm_deadlk.h"
 
 struct gfs2_gl_hash_bucket {
         struct hlist_head hb_list;
@@ -776,7 +777,6 @@ static void xmote_bh(struct gfs2_glock *
 	struct gfs2_sbd *sdp = gl->gl_sbd;
 	const struct gfs2_glock_operations *glops = gl->gl_ops;
 	struct gfs2_holder *gh = gl->gl_req_gh;
-	int prev_state = gl->gl_state;
 	int op_done = 1;
 
 	gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags));
@@ -785,16 +785,6 @@ static void xmote_bh(struct gfs2_glock *
 
 	state_change(gl, ret & LM_OUT_ST_MASK);
 
-	if (prev_state != LM_ST_UNLOCKED && !(ret & LM_OUT_CACHEABLE)) {
-		if (glops->go_inval)
-			glops->go_inval(gl, DIO_METADATA);
-	} else if (gl->gl_state == LM_ST_DEFERRED) {
-		/* We might not want to do this here.
-		   Look at moving to the inode glops. */
-		if (glops->go_inval)
-			glops->go_inval(gl, 0);
-	}
-
 	/*  Deal with each possible exit condition  */
 
 	if (!gh) {
@@ -815,6 +805,15 @@ static void xmote_bh(struct gfs2_glock *
 		}
 	} else {
 		spin_lock(&gl->gl_spin);
+		if (ret & LM_OUT_CONV_DEADLK) {
+			gh->gh_error = 0;
+			gl->gl_req_bh = NULL;
+			set_bit(GLF_CONV_DEADLK, &gl->gl_flags);
+			spin_unlock(&gl->gl_spin);
+			gfs2_glock_drop_th(gl);
+			gfs2_glock_put(gl);
+			return;
+		}
 		list_del_init(&gh->gh_list);
 		gh->gh_error = -EIO;
 		if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) 
@@ -878,6 +877,8 @@ static void gfs2_glock_xmote_th(struct g
 
 	if (glops->go_xmote_th)
 		glops->go_xmote_th(gl);
+	if (state == LM_ST_DEFERRED && glops->go_inval)
+		glops->go_inval(gl, DIO_METADATA);
 
 	gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags));
 	gfs2_assert_warn(sdp, list_empty(&gl->gl_holders));
@@ -911,7 +912,6 @@ static void gfs2_glock_xmote_th(struct g
 static void drop_bh(struct gfs2_glock *gl, unsigned int ret)
 {
 	struct gfs2_sbd *sdp = gl->gl_sbd;
-	const struct gfs2_glock_operations *glops = gl->gl_ops;
 	struct gfs2_holder *gh = gl->gl_req_gh;
 
 	gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags));
@@ -920,8 +920,15 @@ static void drop_bh(struct gfs2_glock *g
 
 	state_change(gl, LM_ST_UNLOCKED);
 
-	if (glops->go_inval)
-		glops->go_inval(gl, DIO_METADATA);
+	if (test_and_clear_bit(GLF_CONV_DEADLK, &gl->gl_flags)) {
+		spin_lock(&gl->gl_spin);
+		gh->gh_error = 0;
+		gl->gl_req_bh = NULL;
+		spin_unlock(&gl->gl_spin);
+		gfs2_glock_xmote_th(gl, gl->gl_req_gh);
+		gfs2_glock_put(gl);
+		return;
+	}
 
 	if (gh) {
 		spin_lock(&gl->gl_spin);
@@ -957,6 +964,8 @@ static void gfs2_glock_drop_th(struct gf
 
 	if (glops->go_drop_th)
 		glops->go_drop_th(gl);
+	if (glops->go_inval)
+		glops->go_inval(gl, DIO_METADATA);
 
 	gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags));
 	gfs2_assert_warn(sdp, list_empty(&gl->gl_holders));
diff -urpN gfs2/incore.h gfs2-patched/incore.h
--- gfs2/incore.h	2008-03-05 07:03:15.000000000 -0600
+++ gfs2-patched/incore.h	2008-03-05 06:59:23.000000000 -0600
@@ -172,6 +172,7 @@ enum {
 	GLF_PENDING_DEMOTE	= 4,
 	GLF_DIRTY		= 5,
 	GLF_DEMOTE_IN_PROGRESS	= 6,
+	GLF_CONV_DEADLK		= 7,
 };
 
 struct gfs2_glock {
diff -urpN gfs2/lm.c gfs2-patched/lm.c
--- gfs2/lm.c	2008-03-05 07:03:15.000000000 -0600
+++ gfs2-patched/lm.c	2008-03-05 06:59:23.000000000 -0600
@@ -21,6 +21,7 @@
 #include "lm.h"
 #include "super.h"
 #include "util.h"
+#include "lm_deadlk.h"
 
 /**
  * gfs2_lm_mount - mount a locking protocol
@@ -35,7 +36,7 @@ int gfs2_lm_mount(struct gfs2_sbd *sdp, 
 {
 	char *proto = sdp->sd_proto_name;
 	char *table = sdp->sd_table_name;
-	int flags = 0;
+	int flags = LM_MFLAG_CONV_NODROP;
 	int error;
 
 	if (sdp->sd_args.ar_spectator)
diff -urpN gfs2/lm_deadlk.h gfs2-patched/lm_deadlk.h
--- gfs2/lm_deadlk.h	1969-12-31 18:00:00.000000000 -0600
+++ gfs2-patched/lm_deadlk.h	2008-03-05 06:59:23.000000000 -0600
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2008 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License version 2.
+ */
+
+#ifndef __LM_DEADLK_DOT_H__
+#define __LM_DEADLK_DOT_H__
+
+/* This is a hack. These flags really belong in lm_interface.h */
+
+/* Do not allow the dlm to internally resolve conversion deadlocks
+ * by demoting the lock to unlocked and then reacquiring it in the
+ * requested mode
+ */
+#define LM_MFLAG_CONV_NODROP	0x00000002
+/* lock request was cancelled do to a conversion deadlock */
+#define LM_OUT_CONV_DEADLK	0x00000200
+
+#endif /* __LM_DEADLK_DOT_H__ */
diff -urpN gfs2/locking/dlm/lock.c gfs2-patched/locking/dlm/lock.c
--- gfs2/locking/dlm/lock.c	2008-03-05 07:03:15.000000000 -0600
+++ gfs2-patched/locking/dlm/lock.c	2008-03-05 06:59:23.000000000 -0600
@@ -8,6 +8,7 @@
  */
 
 #include "lock_dlm.h"
+#include "../../lm_deadlk.h"
 
 static char junk_lvb[GDLM_LVB_SIZE];
 
@@ -137,7 +138,8 @@ static inline unsigned int make_flags(st
 
 		/* Conversion deadlock avoidance by DLM */
 
-		if (!test_bit(LFL_FORCE_PROMOTE, &lp->flags) &&
+		if (!(lp->ls->fsflags & LM_MFLAG_CONV_NODROP) &&
+		    !test_bit(LFL_FORCE_PROMOTE, &lp->flags) &&
 		    !(lkf & DLM_LKF_NOQUEUE) &&
 		    cur > DLM_LOCK_NL && req > DLM_LOCK_NL && cur != req)
 			lkf |= DLM_LKF_CONVDEADLK;
diff -urpN gfs2/locking/dlm/thread.c gfs2-patched/locking/dlm/thread.c
--- gfs2/locking/dlm/thread.c	2008-03-05 07:03:15.000000000 -0600
+++ gfs2-patched/locking/dlm/thread.c	2008-03-05 06:59:23.000000000 -0600
@@ -8,6 +8,7 @@
  */
 
 #include "lock_dlm.h"
+#include "../../lm_deadlk.h"
 
 /* A lock placed on this queue is re-submitted to DLM as soon as the lock_dlm
    thread gets to it. */
@@ -135,7 +136,15 @@ static void process_complete(struct gdlm
 			 lp->lksb.sb_status, lp->lockname.ln_type,
 			 (unsigned long long)lp->lockname.ln_number,
 			 lp->flags);
-		return;
+		if (lp->lksb.sb_status == -EDEADLOCK &&
+		    lp->ls->fsflags & LM_MFLAG_CONV_NODROP) {
+			lp->req = lp->cur;
+			acb.lc_ret |= LM_OUT_CONV_DEADLK;
+			if (lp->cur == DLM_LOCK_IV)
+				lp->lksb.sb_lkid = 0;
+			goto out;
+		} else
+			return;
 	}
 
 	/*

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]