+static int mdd_changelog_llog_init(const struct lu_env *env,
+ struct mdd_device *mdd)
+{
+ struct obd_device *obd = mdd2obd_dev(mdd);
+ struct llog_ctxt *ctxt = NULL, *uctxt = NULL;
+ int rc;
+
+ OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt);
+ obd->obd_lvfs_ctxt.dt = mdd->mdd_bottom;
+ rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CHANGELOG_ORIG_CTXT,
+ obd, &changelog_orig_logops);
+ if (rc) {
+ CERROR("%s: changelog llog setup failed: rc = %d\n",
+ obd->obd_name, rc);
+ RETURN(rc);
+ }
+
+ ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT);
+ LASSERT(ctxt);
+
+ rc = llog_open_create(env, ctxt, &ctxt->loc_handle, NULL,
+ CHANGELOG_CATALOG);
+ if (rc)
+ GOTO(out_cleanup, rc);
+
+ rc = llog_cat_init_and_process(env, ctxt->loc_handle);
+ if (rc)
+ GOTO(out_close, rc);
+
+ rc = llog_cat_reverse_process(env, ctxt->loc_handle,
+ changelog_init_cb, mdd);
+
+ if (rc < 0) {
+ CERROR("%s: changelog init failed: rc = %d\n", obd->obd_name,
+ rc);
+ GOTO(out_close, rc);
+ }
+
+ CDEBUG(D_IOCTL, "changelog starting index="LPU64"\n",
+ mdd->mdd_cl.mc_index);
+
+ /* setup user changelog */
+ rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CHANGELOG_USER_ORIG_CTXT,
+ obd, &changelog_orig_logops);
+ if (rc) {
+ CERROR("%s: changelog users llog setup failed: rc = %d\n",
+ obd->obd_name, rc);
+ GOTO(out_close, rc);
+ }
+
+ uctxt = llog_get_context(obd, LLOG_CHANGELOG_USER_ORIG_CTXT);
+ LASSERT(ctxt);
+
+ rc = llog_open_create(env, uctxt, &uctxt->loc_handle, NULL,
+ CHANGELOG_USERS);
+ if (rc)
+ GOTO(out_ucleanup, rc);
+
+ uctxt->loc_handle->lgh_logops->lop_add = llog_cat_add_rec;
+ uctxt->loc_handle->lgh_logops->lop_declare_add = llog_cat_declare_add_rec;
+
+ rc = llog_cat_init_and_process(env, uctxt->loc_handle);
+ if (rc)
+ GOTO(out_uclose, rc);
+
+ rc = llog_cat_reverse_process(env, uctxt->loc_handle,
+ changelog_user_init_cb, mdd);
+ if (rc < 0) {
+ CERROR("%s: changelog user init failed: rc = %d\n",
+ obd->obd_name, rc);
+ GOTO(out_uclose, rc);
+ }
+
+ /* If we have registered users, assume we want changelogs on */
+ if (mdd->mdd_cl.mc_lastuser > 0) {
+ rc = mdd_changelog_on(env, mdd, 1);
+ if (rc < 0)
+ GOTO(out_uclose, rc);
+ }
+ llog_ctxt_put(ctxt);
+ llog_ctxt_put(uctxt);
+ RETURN(0);
+out_uclose:
+ llog_cat_close(env, uctxt->loc_handle);
+out_ucleanup:
+ llog_cleanup(env, uctxt);
+out_close:
+ llog_cat_close(env, ctxt->loc_handle);
+out_cleanup:
+ llog_cleanup(env, ctxt);
+ return rc;
+}