+
+int lod_sub_prep_llog(const struct lu_env *env, struct lod_device *lod,
+ struct dt_device *dt, int index)
+{
+ struct lod_thread_info *lti = lod_env_info(env);
+ struct llog_ctxt *ctxt;
+ struct llog_handle *lgh;
+ struct llog_catid *cid = <i->lti_cid;
+ struct lu_fid *fid = <i->lti_fid;
+ struct obd_device *obd;
+ int rc;
+ bool need_put = false;
+ ENTRY;
+
+ lu_update_log_fid(fid, index);
+
+ rc = lodname2mdt_index(lod2obd(lod)->obd_name, (__u32 *)&index);
+ if (rc < 0)
+ RETURN(rc);
+
+ rc = llog_osd_get_cat_list(env, dt, index, 1, cid, fid);
+ if (rc != 0) {
+ CERROR("%s: can't get id from catalogs: rc = %d\n",
+ lod2obd(lod)->obd_name, rc);
+ RETURN(rc);
+ }
+
+ obd = dt->dd_lu_dev.ld_obd;
+ ctxt = llog_get_context(obd, LLOG_UPDATELOG_ORIG_CTXT);
+ LASSERT(ctxt != NULL);
+ ctxt->loc_flags |= LLOG_CTXT_FLAG_NORMAL_FID;
+ ctxt->loc_chunk_size = LLOG_MIN_CHUNK_SIZE * 4;
+ if (likely(logid_id(&cid->lci_logid) != 0)) {
+ rc = llog_open(env, ctxt, &lgh, &cid->lci_logid, NULL,
+ LLOG_OPEN_EXISTS);
+
+ /* re-create llog if it is missing */
+ if (rc == -ENOENT)
+ logid_set_id(&cid->lci_logid, 0);
+ else if (rc < 0)
+ GOTO(out_put, rc);
+ }
+
+ if (unlikely(logid_id(&cid->lci_logid) == 0)) {
+ rc = llog_open_create(env, ctxt, &lgh, NULL, NULL);
+ if (rc < 0)
+ GOTO(out_put, rc);
+ cid->lci_logid = lgh->lgh_id;
+ need_put = true;
+ }
+
+ LASSERT(lgh != NULL);
+
+ rc = llog_init_handle(env, lgh, LLOG_F_IS_CAT, NULL);
+ if (rc != 0)
+ GOTO(out_close, rc);
+
+ if (need_put) {
+ rc = llog_osd_put_cat_list(env, dt, index, 1, cid, fid);
+ if (rc != 0)
+ GOTO(out_close, rc);
+ }
+
+ ctxt->loc_handle = lgh;
+
+ CDEBUG(D_INFO, "%s: Init llog for %d - catid "DOSTID":%x\n",
+ obd->obd_name, index, POSTID(&cid->lci_logid.lgl_oi),
+ cid->lci_logid.lgl_ogen);
+out_close:
+ if (rc != 0)
+ llog_cat_close(env, lgh);
+out_put:
+ llog_ctxt_put(ctxt);
+ RETURN(rc);
+}