- struct thandle *th = NULL;
- struct mdd_device *mdd = mdo2mdd(&obj->mod_obj);
- struct md_attr *ma = &mdd_env_info(env)->mti_ma;
- int rc = 0;
- ENTRY;
-
- /* init ma */
- ma->ma_lmm_size = mdd_lov_mdsize(env, mdd);
- ma->ma_lmm = mdd_max_lmm_get(env, mdd);
- ma->ma_cookie_size = mdd_lov_cookiesize(env, mdd);
- ma->ma_cookie = mdd_max_cookie_get(env, mdd);
- ma->ma_need = MA_INODE | MA_LOV | MA_COOKIE;
- ma->ma_valid = 0;
-
- th = mdd_trans_create(env, mdd);
- if (IS_ERR(th)) {
- CERROR("Cannot get thandle\n");
- RETURN(-ENOMEM);
- }
- rc = orph_declare_index_delete(env, obj, th);
- if (rc)
- GOTO(stop, rc);
-
- rc = mdd_declare_object_kill(env, obj, ma, th);
- if (rc)
- GOTO(stop, rc);
-
- rc = mdd_trans_start(env, mdd, th);
- if (rc)
- GOTO(stop, rc);
-
- mdd_write_lock(env, obj, MOR_TGT_CHILD);
- if (likely(obj->mod_count == 0)) {
- mdd_orphan_write_lock(env, mdd);
- rc = mdd_orphan_delete_obj(env, mdd, key, th);
- if (rc == 0)
- orphan_object_kill(env, obj, mdd, th);
- else
- CERROR("could not delete object: rc = %d\n",rc);
- mdd_orphan_write_unlock(env, mdd);
- }
- mdd_write_unlock(env, obj);
-
-stop:
- mdd_trans_stop(env, mdd, 0, th);
+ struct thandle *th = NULL;
+ struct mdd_device *mdd = mdo2mdd(&obj->mod_obj);
+ bool orphan_exists = true;
+ int rc = 0, rc1 = 0;
+ ENTRY;
+
+ th = mdd_trans_create(env, mdd);
+ if (IS_ERR(th)) {
+ rc = PTR_ERR(th);
+ if (rc != -EINPROGRESS)
+ CERROR("%s: cannot get orphan thandle: rc = %d\n",
+ mdd2obd_dev(mdd)->obd_name, rc);
+ RETURN(rc);
+ }
+
+ mdd_write_lock(env, obj, DT_TGT_CHILD);
+ rc = mdd_orphan_declare_delete(env, obj, th);
+ if (rc == -ENOENT || lu_object_is_dying(obj->mod_obj.mo_lu.lo_header))
+ orphan_exists = false;
+ else if (rc)
+ GOTO(unlock, rc);
+
+ if (orphan_exists) {
+ rc = mdo_declare_destroy(env, obj, th);
+ if (rc)
+ GOTO(unlock, rc);
+ }
+
+ rc = mdd_trans_start(env, mdd, th);
+ if (rc)
+ GOTO(unlock, rc);
+
+ if (likely(obj->mod_count == 0)) {
+ dt_write_lock(env, mdd->mdd_orphans, DT_TGT_ORPHAN);
+ rc = dt_delete(env, mdd->mdd_orphans, key, th);
+ /* We should remove object even dt_delete failed */
+ if (orphan_exists) {
+ mdo_ref_del(env, obj, th);
+ if (S_ISDIR(mdd_object_type(obj))) {
+ mdo_ref_del(env, obj, th);
+ dt_ref_del(env, mdd->mdd_orphans, th);
+ }
+ rc1 = mdo_destroy(env, obj, th);
+ }
+ dt_write_unlock(env, mdd->mdd_orphans);
+ }
+unlock:
+ mdd_write_unlock(env, obj);
+ mdd_trans_stop(env, mdd, 0, th);