*/
atomic_t lcm_count;
/**
+ * The refcount for lcm
+ */
+ atomic_t lcm_refcount;
+ /**
* Thread control structure. Used for control commit thread.
*/
struct ptlrpcd_ctl lcm_pc;
char lcm_name[LCM_NAME_SIZE];
};
+static inline struct llog_commit_master
+*lcm_get(struct llog_commit_master *lcm)
+{
+ LASSERT(atomic_read(&lcm->lcm_refcount) > 0);
+ atomic_inc(&lcm->lcm_refcount);
+ return lcm;
+}
+
+static inline void
+lcm_put(struct llog_commit_master *lcm)
+{
+ if (!atomic_dec_and_test(&lcm->lcm_refcount)) {
+ return ;
+ }
+ OBD_FREE_PTR(lcm);
+}
+
struct llog_canceld_ctxt {
/**
* Llog context this llcd is attached to. Used for accessing
}
olg->olg_ctxts[ctxt->loc_idx] = NULL;
spin_unlock(&olg->olg_lock);
-
+
+ if (ctxt->loc_lcm)
+ lcm_put(ctxt->loc_lcm);
+
obd = ctxt->loc_obd;
spin_lock(&obd->obd_dev_lock);
spin_unlock(&obd->obd_dev_lock); /* sync with llog ctxt user thread */
LLOG_MDS_OST_REPL_CTXT);
GOTO(cleanup_olg, rc = -ENODEV);
}
- ctxt->loc_lcm = filter->fo_lcm;
+ ctxt->loc_lcm = lcm_get(filter->fo_lcm);
ctxt->llog_proc_cb = filter_recov_log_mds_ost_cb;
llog_ctxt_put(ctxt);
RETURN(-ENODEV);
}
ctxt->llog_proc_cb = filter_recov_log_mds_ost_cb;
- ctxt->loc_lcm = filter->fo_lcm;
+ ctxt->loc_lcm = lcm_get(filter->fo_lcm);
llog_ctxt_put(ctxt);
RETURN(rc);
}
}
if (filter->fo_lcm) {
+ mutex_down(&ctxt->loc_sem);
llog_recov_thread_fini(filter->fo_lcm, obd->obd_force);
filter->fo_lcm = NULL;
+ mutex_up(&ctxt->loc_sem);
}
RETURN(filter_olg_fini(&obd->obd_olg));
}
#test race llog recovery thread vs llog cleanup
test_61a() { # was test_61
remote_ost_nodsh && skip "remote OST with nodsh" && return 0
-
- mkdir $DIR/$tdir
+
+ mkdir -p $DIR/$tdir
createmany -o $DIR/$tdir/$tfile-%d 800
replay_barrier ost1
# OBD_FAIL_OST_LLOG_RECOVERY_TIMEOUT 0x221