+ LASSERT(mdd_write_locked(env, obj) != 0);
+ LASSERT(!(obj->mod_flags & ORPHAN_OBJ));
+ LASSERT(obj->mod_count > 0);
+
+ mdd_orphan_write_lock(env, mdd);
+
+ rc = mdd_orphan_insert_obj(env, mdd, obj, op, th);
+ if (rc)
+ GOTO(out, rc);
+
+ mdo_ref_add(env, obj, th);
+ if (!S_ISDIR(mdd_object_type(obj)))
+ goto out;
+
+ mdo_ref_add(env, obj, th);
+ mdd_orphan_ref_add(env, mdd, th);
+
+ /* try best to fixup directory, dont return errors
+ * from here */
+ if (!dt_try_as_dir(env, next))
+ goto out;
+ next->do_index_ops->dio_delete(env, next,
+ dotdot, th, BYPASS_CAPA);
+
+ next->do_index_ops->dio_insert(env, next,
+ __mdd_fid_rec(env, lf_dor),
+ dotdot, th, BYPASS_CAPA, 1);
+
+out:
+ if (rc == 0)
+ obj->mod_flags |= ORPHAN_OBJ;
+
+ mdd_orphan_write_unlock(env, mdd);
+
+ RETURN(rc);
+}
+
+/**
+ * destroy osd object on mdd and associated ost objects.
+ *
+ * \param obj orphan object
+ * \param mdd used for sending llog msg to osts
+ *
+ * \retval 0 success
+ * \retval -ve error
+ */
+static int orphan_object_kill(const struct lu_env *env,
+ struct mdd_object *obj,
+ struct mdd_device *mdd,
+ struct thandle *th)
+{
+ struct lu_attr *la = &mdd_env_info(env)->mti_la;
+ int rc = 0;
+ ENTRY;
+
+ /* No need to lock this object as its recovery phase, and
+ * no other thread can access it. But we need to lock it
+ * as its precondition for osd api we using. */
+
+ mdo_ref_del(env, obj, th);
+ if (S_ISDIR(mdd_object_type(obj))) {
+ mdo_ref_del(env, obj, th);
+ mdd_orphan_ref_del(env, mdd, th);
+ } else {
+ /* regular file , cleanup linked ost objects */
+ rc = mdd_la_get(env, obj, la, BYPASS_CAPA);
+ if (rc == 0)
+ rc = mdd_lov_destroy(env, mdd, obj, la);
+ }