ocfs2_dlm: Fix migrate lockres handler queue scanning
authorKurt Hackel <kurt.hackel@oracle.com>
Fri, 5 Jan 2007 23:04:49 +0000 (15:04 -0800)
committerMark Fasheh <mark.fasheh@oracle.com>
Wed, 7 Feb 2007 20:02:40 +0000 (12:02 -0800)
The migrate lockres handler was only searching for its lock on
migrated lockres on the expected queue. This could be problematic
as the new master could have also issued a convert request
during the migration and thus moved the lock to the convert queue.
We now search for the lock on all three queues.

Signed-off-by: Kurt Hackel <kurt.hackel@oracle.com>
Signed-off-by: Sunil Mushran <Sunil.Mushran@oracle.com>
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
fs/ocfs2/dlm/dlmrecovery.c

index 3057b65a4b8b2aaa486f5900f268d6cd1e06ed20..f93315c9887101b2897e9fea31c8cb462757a07b 100644 (file)
@@ -1708,10 +1708,11 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm,
 {
        struct dlm_migratable_lock *ml;
        struct list_head *queue;
+       struct list_head *tmpq = NULL;
        struct dlm_lock *newlock = NULL;
        struct dlm_lockstatus *lksb = NULL;
        int ret = 0;
-       int i, bad;
+       int i, j, bad;
        struct list_head *iter;
        struct dlm_lock *lock = NULL;
        u8 from = O2NM_MAX_NODES;
@@ -1738,6 +1739,7 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm,
                lksb = NULL;
 
                queue = dlm_list_num_to_pointer(res, ml->list);
+               tmpq = NULL;
 
                /* if the lock is for the local node it needs to
                 * be moved to the proper location within the queue.
@@ -1747,11 +1749,16 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm,
                        BUG_ON(!(mres->flags & DLM_MRES_MIGRATION));
 
                        spin_lock(&res->spinlock);
-                       list_for_each(iter, queue) {
-                               lock = list_entry (iter, struct dlm_lock, list);
-                               if (lock->ml.cookie != ml->cookie)
-                                       lock = NULL;
-                               else
+                       for (j = DLM_GRANTED_LIST; j <= DLM_BLOCKED_LIST; j++) {
+                               tmpq = dlm_list_idx_to_ptr(res, j);
+                               list_for_each(iter, tmpq) {
+                                       lock = list_entry (iter, struct dlm_lock, list);
+                                       if (lock->ml.cookie != ml->cookie)
+                                               lock = NULL;
+                                       else
+                                               break;
+                               }
+                               if (lock)
                                        break;
                        }
 
@@ -1768,6 +1775,13 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm,
                        }
                        BUG_ON(lock->ml.node != ml->node);
 
+                       if (tmpq != queue) {
+                               mlog(0, "lock was on %u instead of %u for %.*s\n",
+                                    j, ml->list, res->lockname.len, res->lockname.name);
+                               spin_unlock(&res->spinlock);
+                               continue;
+                       }
+
                        /* see NOTE above about why we do not update
                         * to match the master here */