Whamcloud - gitweb
LU-1259 mgs: avoid cancelling IR lock twice
authorJinshan Xiong <jinshan.xiong@whamcloud.com>
Tue, 27 Mar 2012 16:28:31 +0000 (09:28 -0700)
committerOleg Drokin <green@whamcloud.com>
Mon, 7 May 2012 18:48:50 +0000 (14:48 -0400)
There is a race that if IR shared lock is revoked fastly the
completion ast can be called twice with the lock granted. The
IR lock should be cancelled only once in this case.

Signed-off-by: Jinshan Xiong <jinshan.xiong@whamcloud.com>
Change-Id: Ie1b2742d436fb6f549cfcb25dc50fbbabcd1f008
Reviewed-on: http://review.whamcloud.com/2390
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: James Simmons <uja.ornl@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/mgs/mgs_handler.c

index 345d26b..4fa10d4 100644 (file)
@@ -358,13 +358,23 @@ static int mgs_completion_ast_ir(struct ldlm_lock *lock, int flags,
 
         if (!(flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED |
                        LDLM_FL_BLOCK_CONV))) {
 
         if (!(flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED |
                        LDLM_FL_BLOCK_CONV))) {
-                struct fs_db *fsdb = (struct fs_db *)lock->l_ast_data;
-                struct lustre_handle lockh;
+                struct fs_db *fsdb;
 
 
-                mgs_ir_notify_complete(fsdb);
+                /* l_ast_data is used as a marker to avoid cancel ldlm lock
+                 * twice. See LU-1259. */
+                lock_res_and_lock(lock);
+                fsdb = (struct fs_db *)lock->l_ast_data;
+                lock->l_ast_data = NULL;
+                unlock_res_and_lock(lock);
 
 
-                ldlm_lock2handle(lock, &lockh);
-                ldlm_lock_decref_and_cancel(&lockh, LCK_EX);
+                if (fsdb != NULL) {
+                        struct lustre_handle lockh;
+
+                        mgs_ir_notify_complete(fsdb);
+
+                        ldlm_lock2handle(lock, &lockh);
+                        ldlm_lock_decref_and_cancel(&lockh, LCK_EX);
+                }
         }
 
         RETURN(ldlm_completion_ast(lock, flags, cbdata));
         }
 
         RETURN(ldlm_completion_ast(lock, flags, cbdata));