+
+static void echo_ed_los_fini(const struct lu_env *env, struct echo_device *ed)
+{
+ ENTRY;
+
+ if (ed != NULL && ed->ed_next_ismd && ed->ed_los != NULL) {
+ local_oid_storage_fini(env, ed->ed_los);
+ ed->ed_los = NULL;
+ }
+}
+
+static int
+echo_md_local_file_create(const struct lu_env *env, struct echo_md_device *emd,
+ struct local_oid_storage *los,
+ const struct lu_fid *pfid, const char *name,
+ __u32 mode, struct lu_fid *fid)
+{
+ struct dt_object *parent = NULL;
+ struct dt_object *dto = NULL;
+ int rc = 0;
+ ENTRY;
+
+ LASSERT(!fid_is_zero(pfid));
+ parent = dt_locate(env, emd->emd_bottom, pfid);
+ if (unlikely(IS_ERR(parent)))
+ RETURN(PTR_ERR(parent));
+
+ /* create local file with @fid */
+ dto = local_file_find_or_create_with_fid(env, emd->emd_bottom, fid,
+ parent, name, mode);
+ if (IS_ERR(dto))
+ GOTO(out_put, rc = PTR_ERR(dto));
+
+ *fid = *lu_object_fid(&dto->do_lu);
+ /* since stack is not fully set up the local_storage uses own stack
+ * and we should drop its object from cache */
+ lu_object_put_nocache(env, &dto->do_lu);
+
+ EXIT;
+out_put:
+ lu_object_put(env, &parent->do_lu);
+ RETURN(rc);
+}
+
+static int
+echo_md_root_get(const struct lu_env *env, struct echo_md_device *emd,
+ struct echo_device *ed)
+{
+ struct lu_fid fid;
+ int rc = 0;
+ ENTRY;
+
+ /* Setup local dirs */
+ fid.f_seq = FID_SEQ_LOCAL_NAME;
+ fid.f_oid = 1;
+ fid.f_ver = 0;
+ rc = local_oid_storage_init(env, emd->emd_bottom, &fid, &ed->ed_los);
+ if (rc != 0)
+ RETURN(rc);
+
+ lu_echo_root_fid(&fid);
+ if (echo_md_seq_site(emd)->ss_node_id == 0) {
+ rc = echo_md_local_file_create(env, emd, ed->ed_los,
+ &emd->emd_local_root_fid,
+ echo_md_root_dir_name, S_IFDIR |
+ S_IRUGO | S_IWUSR | S_IXUGO,
+ &fid);
+ if (rc != 0) {
+ CERROR("%s: create md echo root fid failed: rc = %d\n",
+ emd2obd_dev(emd)->obd_name, rc);
+ GOTO(out_los, rc);
+ }
+ }
+ ed->ed_root_fid = fid;
+
+ RETURN(0);
+out_los:
+ echo_ed_los_fini(env, ed);
+
+ RETURN(rc);
+}