static int orph_index_insert(const struct lu_env *env, struct mdd_object *obj, __u32 op, struct thandle *th) { struct mdd_device *mdd = mdo2mdd(&obj->mod_obj); struct dt_object *dor = mdd->mdd_orphans; const struct lu_fid *lf_dor = lu_object_fid(&dor->do_lu); struct dt_object *next = mdd_object_child(obj); int rc; ENTRY; LASSERT(mdd_write_locked(env, obj) != 0); LASSERT(!(obj->mod_flags & ORPHAN_OBJ)); 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, (const struct dt_key *)dotdot, th, BYPASS_CAPA); next->do_index_ops->dio_insert(env, next, (struct dt_rec *)lf_dor, (const struct dt_key *)dotdot, th, BYPASS_CAPA, 1); out: if (rc == 0) obj->mod_flags |= ORPHAN_OBJ; mdd_orphan_write_unlock(env, mdd); RETURN(rc); }
/** * add an orphan \a obj to the orphan index. * \param obj file or directory. * \param th transaction for index insert. * * \pre obj nlink == 0 && obj->mod_count != 0 * * \retval 0 success * \retval -ve index operation error. */ int mdd_orphan_insert(const struct lu_env *env, struct mdd_object *obj, struct thandle *th) { struct mdd_device *mdd = mdo2mdd(&obj->mod_obj); struct dt_object *dor = mdd->mdd_orphans; const struct lu_fid *lf_dor = lu_object_fid(&dor->do_lu); struct dt_object *next = mdd_object_child(obj); struct dt_insert_rec *rec = &mdd_env_info(env)->mti_dt_rec; int rc; ENTRY; LASSERT(mdd_write_locked(env, obj) != 0); LASSERT(!(obj->mod_flags & ORPHAN_OBJ)); dt_write_lock(env, mdd->mdd_orphans, MOR_TGT_ORPHAN); rc = mdd_orphan_insert_obj(env, mdd, obj, th); if (rc) GOTO(out, rc); mdo_ref_add(env, obj, th); if (!S_ISDIR(mdd_object_type(obj))) GOTO(out, rc = 0); mdo_ref_add(env, obj, th); dt_ref_add(env, mdd->mdd_orphans, th); /* try best to fixup directory, do not return errors from here */ if (!dt_try_as_dir(env, next)) GOTO(out, rc = 0); dt_delete(env, next, (const struct dt_key *)dotdot, th); rec->rec_fid = lf_dor; rec->rec_type = S_IFDIR; dt_insert(env, next, (const struct dt_rec *)rec, (const struct dt_key *)dotdot, th); out: if (rc == 0) obj->mod_flags |= ORPHAN_OBJ; dt_write_unlock(env, mdd->mdd_orphans); RETURN(rc); }