aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunil Mushran <sunil.mushran@oracle.com>2010-02-03 13:16:54 -0500
committerJoel Becker <joel.becker@oracle.com>2010-02-03 20:26:03 -0500
commit079b805782f94f4b278132286a8c9bc4655d1c51 (patch)
tree8ace4c9aa726593d85fd2b80cea87d6170251ff7
parentdb0f6ce69776370232431eb8be85a5b18b0019c0 (diff)
ocfs2: Plugs race between the dc thread and an unlock ast message
This patch plugs a race between the downconvert thread and an unlock ast message. Specifically, after the downconvert worker has done its task, the dc thread needs to check whether an unlock ast made the downconvert moot. Reported-by: David Teigland <teigland@redhat.com> Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com> Acked-by: Mark Fasheh <mfasheh@sus.com> Signed-off-by: Joel Becker <joel.becker@oracle.com>
-rw-r--r--fs/ocfs2/dlmglue.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index ce8e061c9a22..e044019cb3b1 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -3384,6 +3384,7 @@ static int ocfs2_unblock_lock(struct ocfs2_super *osb,
3384 unsigned long flags; 3384 unsigned long flags;
3385 int blocking; 3385 int blocking;
3386 int new_level; 3386 int new_level;
3387 int level;
3387 int ret = 0; 3388 int ret = 0;
3388 int set_lvb = 0; 3389 int set_lvb = 0;
3389 unsigned int gen; 3390 unsigned int gen;
@@ -3503,6 +3504,7 @@ recheck:
3503 * may sleep, so we save off a copy of what we're blocking as 3504 * may sleep, so we save off a copy of what we're blocking as
3504 * it may change while we're not holding the spin lock. */ 3505 * it may change while we're not holding the spin lock. */
3505 blocking = lockres->l_blocking; 3506 blocking = lockres->l_blocking;
3507 level = lockres->l_level;
3506 spin_unlock_irqrestore(&lockres->l_lock, flags); 3508 spin_unlock_irqrestore(&lockres->l_lock, flags);
3507 3509
3508 ctl->unblock_action = lockres->l_ops->downconvert_worker(lockres, blocking); 3510 ctl->unblock_action = lockres->l_ops->downconvert_worker(lockres, blocking);
@@ -3511,7 +3513,7 @@ recheck:
3511 goto leave; 3513 goto leave;
3512 3514
3513 spin_lock_irqsave(&lockres->l_lock, flags); 3515 spin_lock_irqsave(&lockres->l_lock, flags);
3514 if (blocking != lockres->l_blocking) { 3516 if ((blocking != lockres->l_blocking) || (level != lockres->l_level)) {
3515 /* If this changed underneath us, then we can't drop 3517 /* If this changed underneath us, then we can't drop
3516 * it just yet. */ 3518 * it just yet. */
3517 goto recheck; 3519 goto recheck;