Whamcloud - gitweb
LU-6881 update: add lock to protect commit check 90/15690/3
authorwang di <di.wang@intel.com>
Tue, 21 Jul 2015 13:16:21 +0000 (06:16 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 13 Aug 2015 00:01:15 +0000 (00:01 +0000)
In sub_trans_commit_cb(), the commit check should
be protected by lock, otherwise in some racy
scenarios, all committed will never be true,
even though all sub transaction has been committed.

Signed-off-by: wang di <di.wang@intel.com>
Change-Id: I8f43ca8083753ab6eef4f2be56ef77bb8640bb79
Reviewed-on: http://review.whamcloud.com/15690
Reviewed-by: Niu Yawei <yawei.niu@intel.com>
Tested-by: Jenkins
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/include/lustre_update.h
lustre/target/update_trans.c

index f9fd97e..ab81ee6 100644 (file)
@@ -285,6 +285,7 @@ struct top_multiple_thandle {
        atomic_t                tmt_refcount;
        /* Other sub transactions will be listed here. */
        struct list_head        tmt_sub_thandle_list;
+       spinlock_t              tmt_sub_lock;
 
        struct list_head        tmt_commit_list;
        /* All of update records will packed here */
index 998481e..82e67fc 100644 (file)
@@ -468,6 +468,7 @@ static void sub_trans_commit_cb(struct lu_env *env,
        ENTRY;
 
        /* Check if all sub thandles are committed */
+       spin_lock(&tmt->tmt_sub_lock);
        list_for_each_entry(st, &tmt->tmt_sub_thandle_list, st_sub_list) {
                if (st->st_sub_th == sub_th) {
                        st->st_committed = 1;
@@ -476,6 +477,7 @@ static void sub_trans_commit_cb(struct lu_env *env,
                if (!st->st_committed)
                        all_committed = false;
        }
+       spin_unlock(&tmt->tmt_sub_lock);
 
        if (tmt->tmt_result == 0)
                tmt->tmt_result = err;
@@ -1075,8 +1077,9 @@ int top_trans_create_tmt(const struct lu_env *env,
        INIT_LIST_HEAD(&tmt->tmt_sub_thandle_list);
        INIT_LIST_HEAD(&tmt->tmt_commit_list);
        atomic_set(&tmt->tmt_refcount, 1);
-
+       spin_lock_init(&tmt->tmt_sub_lock);
        init_waitqueue_head(&tmt->tmt_stop_waitq);
+
        top_th->tt_multiple_thandle = tmt;
 
        return 0;