struct thandle ot_super;
handle_t *ot_handle;
struct journal_callback ot_jcb;
+ cfs_list_t ot_dcb_list;
/* Link to the device, for debugging. */
struct lu_ref_link *ot_dev_link;
{
struct osd_thandle *oh = container_of0(jcb, struct osd_thandle, ot_jcb);
struct thandle *th = &oh->ot_super;
- struct dt_device *dev = th->th_dev;
- struct lu_device *lud = &dev->dd_lu_dev;
+ struct lu_device *lud = &th->th_dev->dd_lu_dev;
+ struct dt_txn_commit_cb *dcb, *tmp;
- LASSERT(dev != NULL);
LASSERT(oh->ot_handle == NULL);
- if (error) {
+ if (error)
CERROR("transaction @0x%p commit error: %d\n", th, error);
- } else {
- struct lu_env *env = &osd_dt_dev(dev)->od_env_for_commit;
- /*
- * This od_env_for_commit is only for commit usage. see
- * "struct dt_device"
- */
- lu_context_enter(&env->le_ctx);
- dt_txn_hook_commit(env, th);
- lu_context_exit(&env->le_ctx);
- }
+
+ dt_txn_hook_commit(th);
+
+ /* call per-transaction callbacks if any */
+ cfs_list_for_each_entry_safe(dcb, tmp, &oh->ot_dcb_list, dcb_linkage)
+ dcb->dcb_func(NULL, th, dcb, error);
lu_ref_del_at(&lud->ld_reference, oh->ot_dev_link, "osd-tx", th);
lu_device_put(lud);
* be used.
*/
oti->oti_dev = dev;
+ CFS_INIT_LIST_HEAD(&oh->ot_dcb_list);
osd_th_alloced(oh);
jh = ldiskfs_journal_start_sb(osd_sb(dev), p->tp_credits);
osd_th_started(oh);
th = &oh->ot_super;
th->th_dev = d;
th->th_result = 0;
- jh->h_sync = p->tp_sync;
+ th->th_sync = 0;
lu_device_get(&d->dd_lu_dev);
oh->ot_dev_link = lu_ref_add
(&d->dd_lu_dev.ld_reference,
/* add commit callback */
lu_context_init(&th->th_ctx, LCT_TX_HANDLE);
lu_context_enter(&th->th_ctx);
- osd_journal_callback_set(jh,osd_trans_commit_cb,
- &oh->ot_jcb);
LASSERT(oti->oti_txns == 0);
LASSERT(oti->oti_r_locks == 0);
LASSERT(oti->oti_w_locks == 0);
if (oh->ot_handle != NULL) {
handle_t *hdl = oh->ot_handle;
+ hdl->h_sync = th->th_sync;
+ /*
+ * add commit callback
+ * notice we don't do this in osd_trans_start()
+ * as underlying transaction can change during truncate
+ */
+ osd_journal_callback_set(hdl, osd_trans_commit_cb,
+ &oh->ot_jcb);
+
LASSERT(oti->oti_txns == 1);
oti->oti_txns--;
LASSERT(oti->oti_r_locks == 0);
result = ldiskfs_journal_stop(hdl));
if (result != 0)
CERROR("Failure to stop transaction: %d\n", result);
+ } else {
+ OBD_FREE_PTR(oh);
}
EXIT;
}
+static int osd_trans_cb_add(struct thandle *th, struct dt_txn_commit_cb *dcb)
+{
+ struct osd_thandle *oh = container_of0(th, struct osd_thandle,
+ ot_super);
+
+ cfs_list_add(&dcb->dcb_linkage, &oh->ot_dcb_list);
+
+ return 0;
+}
+
/*
* Concurrency: no concurrent access is possible that late in object
* life-cycle.
.dt_statfs = osd_statfs,
.dt_trans_start = osd_trans_start,
.dt_trans_stop = osd_trans_stop,
+ .dt_trans_cb_add = osd_trans_cb_add,
.dt_conf_get = osd_conf_get,
.dt_sync = osd_sync,
.dt_ro = osd_ro,
static int osd_device_init(const struct lu_env *env, struct lu_device *d,
const char *name, struct lu_device *next)
{
- int rc;
- struct lu_context *ctx;
-
- /* context for commit hooks */
- ctx = &osd_dev(d)->od_env_for_commit.le_ctx;
- rc = lu_context_init(ctx, LCT_MD_THREAD|LCT_REMEMBER|LCT_NOREF);
- if (rc == 0) {
- rc = osd_procfs_init(osd_dev(d), name);
- ctx->lc_cookie = 0x3;
- }
- return rc;
+ return osd_procfs_init(osd_dev(d), name);
}
static int osd_shutdown(const struct lu_env *env, struct osd_device *o)
osd_dev(d)->od_mount->lmi_mnt);
osd_dev(d)->od_mount = NULL;
- lu_context_fini(&osd_dev(d)->od_env_for_commit.le_ctx);
RETURN(NULL);
}