aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/locking/dlm
diff options
context:
space:
mode:
authorBenjamin Marzinski <bmarzins@redhat.com>2008-03-14 14:52:52 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2008-03-31 05:41:44 -0400
commit58e9fee13e579df44922172dbe3c9e3ba3edf7a3 (patch)
tree7b134f28032a3cd498b2d9a18c02ea085c0725e2 /fs/gfs2/locking/dlm
parentf5a8cd020173c455705fc0095b7d299da6f8f87b (diff)
[GFS2] Invalidate cache at correct point
GFS2 wasn't invalidating its cache before it called into the lock manager with a request that could potentially drop a lock. This was leaving a window where the lock could be actually be held by another node, but the file's page cache would still appear valid, causing coherency problems. This patch moves the cache invalidation to before the lock manager call when dropping a lock. It also adds the option to the lock_dlm lock manager to not use conversion mode deadlock avoidance, which, on a conversion from shared to exclusive, could internally drop the lock, and then reacquire in. GFS2 now asks lock_dlm to not do this. Instead, GFS2 manually drops the lock and reacquires it. Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/locking/dlm')
-rw-r--r--fs/gfs2/locking/dlm/lock.c3
-rw-r--r--fs/gfs2/locking/dlm/thread.c10
2 files changed, 11 insertions, 2 deletions
diff --git a/fs/gfs2/locking/dlm/lock.c b/fs/gfs2/locking/dlm/lock.c
index 542a797ac89a..53a6ab3c0919 100644
--- a/fs/gfs2/locking/dlm/lock.c
+++ b/fs/gfs2/locking/dlm/lock.c
@@ -137,7 +137,8 @@ static inline unsigned int make_flags(struct gdlm_lock *lp,
137 137
138 /* Conversion deadlock avoidance by DLM */ 138 /* Conversion deadlock avoidance by DLM */
139 139
140 if (!test_bit(LFL_FORCE_PROMOTE, &lp->flags) && 140 if (!(lp->ls->fsflags & LM_MFLAG_CONV_NODROP) &&
141 !test_bit(LFL_FORCE_PROMOTE, &lp->flags) &&
141 !(lkf & DLM_LKF_NOQUEUE) && 142 !(lkf & DLM_LKF_NOQUEUE) &&
142 cur > DLM_LOCK_NL && req > DLM_LOCK_NL && cur != req) 143 cur > DLM_LOCK_NL && req > DLM_LOCK_NL && cur != req)
143 lkf |= DLM_LKF_CONVDEADLK; 144 lkf |= DLM_LKF_CONVDEADLK;
diff --git a/fs/gfs2/locking/dlm/thread.c b/fs/gfs2/locking/dlm/thread.c
index 521694fc19d6..e53db6fd28ab 100644
--- a/fs/gfs2/locking/dlm/thread.c
+++ b/fs/gfs2/locking/dlm/thread.c
@@ -135,7 +135,15 @@ static void process_complete(struct gdlm_lock *lp)
135 lp->lksb.sb_status, lp->lockname.ln_type, 135 lp->lksb.sb_status, lp->lockname.ln_type,
136 (unsigned long long)lp->lockname.ln_number, 136 (unsigned long long)lp->lockname.ln_number,
137 lp->flags); 137 lp->flags);
138 return; 138 if (lp->lksb.sb_status == -EDEADLOCK &&
139 lp->ls->fsflags & LM_MFLAG_CONV_NODROP) {
140 lp->req = lp->cur;
141 acb.lc_ret |= LM_OUT_CONV_DEADLK;
142 if (lp->cur == DLM_LOCK_IV)
143 lp->lksb.sb_lkid = 0;
144 goto out;
145 } else
146 return;
139 } 147 }
140 148
141 /* 149 /*