Whamcloud - gitweb
LU-2683 lov: release all locks in closure to release sublock
authorJinshan Xiong <jinshan.xiong@intel.com>
Wed, 30 Jan 2013 00:35:49 +0000 (16:35 -0800)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 4 Mar 2013 19:29:05 +0000 (14:29 -0500)
We used to only release current parent lock, this may cause deadlock
if the sublock is shared. See stacktrace of LU-2683 and LU-874 for
details.

Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Change-Id: Ibe5fc364ef22a279f23bb24ad1311a1ad09be369
Reviewed-on: http://review.whamcloud.com/5208
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Bobi Jam <bobijam@gmail.com>
Reviewed-by: Niu Yawei <yawei.niu@intel.com>
Reviewed-by: Prakash Surya <surya1@llnl.gov>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/lov/lov_lock.c

index 1241f5f..de55b2d 100644 (file)
@@ -652,8 +652,19 @@ static int lov_lock_enqueue(const struct lu_env *env,
                                                                    sublock);
                                         break;
                                 case CLS_CACHED:
+                                       cl_lock_get(sublock);
+                                        /* take recursive mutex of sublock */
+                                        cl_lock_mutex_get(env, sublock);
+                                       /* need to release all locks in closure
+                                        * otherwise it may deadlock. LU-2683.*/
+                                        lov_sublock_unlock(env, sub, closure,
+                                                           subenv);
+                                       /* sublock and parent are held. */
                                         rc = lov_sublock_release(env, lck, i,
                                                                  1, rc);
+                                       cl_lock_mutex_put(env, sublock);
+                                       cl_lock_put(env, sublock);
+                                       break;
                                 default:
                                         lov_sublock_unlock(env, sub, closure,
                                                            subenv);