static inline int mdd_orphan_ref_del(const struct lu_env *env, struct mdd_device *mdd, struct thandle *th) { struct dt_object *dor = mdd->mdd_orphans; return dt_ref_del(env, dor, th); }
static int out_obj_ref_del(const struct lu_env *env, struct dt_object *dt_obj, struct thandle *th) { int rc; dt_write_lock(env, dt_obj, MOR_TGT_CHILD); rc = dt_ref_del(env, dt_obj, th); dt_write_unlock(env, dt_obj); return rc; }
static int out_tx_ref_add_undo(struct mdt_thread_info *info, struct thandle *th, struct tx_arg *arg) { struct dt_object *dt_obj = arg->object; LASSERT(dt_obj != NULL && !IS_ERR(dt_obj)); CDEBUG(D_OTHER, "ref del "DFID"\n", PFID(lu_object_fid(&arg->object->do_lu))); dt_write_lock(info->mti_env, dt_obj, MOR_TGT_CHILD); dt_ref_del(info->mti_env, dt_obj, th); dt_write_unlock(info->mti_env, dt_obj); return 0; }
/** * delete an orphan \a obj from orphan index. * \param obj file or directory. * \param th transaction for index deletion and object destruction. * * \pre obj->mod_count == 0 && ORPHAN_OBJ is set for obj. * * \retval 0 success * \retval -ve index operation error. */ int mdd_orphan_delete(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; struct dt_key *key; int rc = 0; ENTRY; LASSERT(mdd_write_locked(env, obj) != 0); LASSERT(obj->mod_flags & ORPHAN_OBJ); LASSERT(obj->mod_count == 0); LASSERT(dor); key = mdd_orphan_key_fill(env, mdo2fid(obj)); dt_write_lock(env, mdd->mdd_orphans, MOR_TGT_ORPHAN); if (OBD_FAIL_CHECK(OBD_FAIL_MDS_ORPHAN_DELETE)) goto ref_del; rc = dt_delete(env, mdd->mdd_orphans, key, th); if (rc == -ENOENT) { key = mdd_orphan_key_fill_20(env, mdo2fid(obj)); rc = dt_delete(env, mdd->mdd_orphans, key, th); } ref_del: if (!rc) { /* lov objects will be destroyed by caller */ 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); } obj->mod_flags &= ~ORPHAN_OBJ; } else { CERROR("%s: could not delete orphan object "DFID": rc = %d\n", mdd2obd_dev(mdd)->obd_name, PFID(mdo2fid(obj)), rc); } dt_write_unlock(env, mdd->mdd_orphans); RETURN(rc); }
int ofd_object_destroy(const struct lu_env *env, struct ofd_object *fo, int orphan) { struct ofd_device *ofd = ofd_obj2dev(fo); struct thandle *th; int rc = 0; ENTRY; ofd_write_lock(env, fo); if (!ofd_object_exists(fo)) GOTO(unlock, rc = -ENOENT); th = ofd_trans_create(env, ofd); if (IS_ERR(th)) GOTO(unlock, rc = PTR_ERR(th)); dt_declare_ref_del(env, ofd_object_child(fo), th); dt_declare_destroy(env, ofd_object_child(fo), th); if (orphan) rc = dt_trans_start_local(env, ofd->ofd_osd, th); else rc = ofd_trans_start(env, ofd, NULL, th); if (rc) GOTO(stop, rc); ofd_fmd_drop(ofd_info(env)->fti_exp, &fo->ofo_header.loh_fid); dt_ref_del(env, ofd_object_child(fo), th); dt_destroy(env, ofd_object_child(fo), th); stop: ofd_trans_stop(env, ofd, th, rc); unlock: ofd_write_unlock(env, fo); RETURN(rc); }
/** * Implementation of the llog_operations::lop_destroy * * This function destroys the llog and deletes also entry in the * llog directory in case of named llog. Llog should be opened prior that. * Destroy method is not part of external transaction and does everything * inside. * * \param[in] env execution environment * \param[in] loghandle llog handle of the current llog * * \retval 0 on successful destroy * \retval negative value on error */ static int llog_osd_destroy(const struct lu_env *env, struct llog_handle *loghandle) { struct llog_ctxt *ctxt; struct dt_object *o, *llog_dir = NULL; struct dt_device *d; struct thandle *th; char *name = NULL; int rc; ENTRY; ctxt = loghandle->lgh_ctxt; LASSERT(ctxt); o = loghandle->lgh_obj; LASSERT(o); d = lu2dt_dev(o->do_lu.lo_dev); LASSERT(d); LASSERT(d == ctxt->loc_exp->exp_obd->obd_lvfs_ctxt.dt); th = dt_trans_create(env, d); if (IS_ERR(th)) RETURN(PTR_ERR(th)); if (loghandle->lgh_name) { llog_dir = llog_osd_dir_get(env, ctxt); if (IS_ERR(llog_dir)) GOTO(out_trans, rc = PTR_ERR(llog_dir)); name = loghandle->lgh_name; rc = dt_declare_delete(env, llog_dir, (struct dt_key *)name, th); if (rc) GOTO(out_trans, rc); } dt_declare_ref_del(env, o, th); rc = dt_declare_destroy(env, o, th); if (rc) GOTO(out_trans, rc); rc = dt_trans_start_local(env, d, th); if (rc) GOTO(out_trans, rc); dt_write_lock(env, o, 0); if (dt_object_exists(o)) { if (name) { dt_read_lock(env, llog_dir, 0); rc = dt_delete(env, llog_dir, (struct dt_key *) name, th, BYPASS_CAPA); dt_read_unlock(env, llog_dir); if (rc) { CERROR("%s: can't remove llog %s: rc = %d\n", o->do_lu.lo_dev->ld_obd->obd_name, name, rc); GOTO(out_unlock, rc); } } dt_ref_del(env, o, th); rc = dt_destroy(env, o, th); if (rc) GOTO(out_unlock, rc); } out_unlock: dt_write_unlock(env, o); out_trans: dt_trans_stop(env, d, th); if (llog_dir != NULL) lu_object_put(env, &llog_dir->do_lu); RETURN(rc); }
static int llog_osd_destroy(const struct lu_env *env, struct llog_handle *loghandle) { struct llog_thread_info *lgi = llog_info(env); struct llog_ctxt *ctxt; struct dt_object *o, *llog_dir = NULL; struct dt_device *d; struct thandle *th; char *name = NULL; int rc; ENTRY; ctxt = loghandle->lgh_ctxt; LASSERT(ctxt); o = loghandle->lgh_obj; LASSERT(o); d = lu2dt_dev(o->do_lu.lo_dev); LASSERT(d); LASSERT(d == ctxt->loc_exp->exp_obd->obd_lvfs_ctxt.dt); th = dt_trans_create(env, d); if (IS_ERR(th)) RETURN(PTR_ERR(th)); if (loghandle->lgh_name) { llog_dir = llog_osd_dir_get(env, ctxt); if (IS_ERR(llog_dir)) GOTO(out_trans, rc = PTR_ERR(llog_dir)); dt_declare_ref_del(env, o, th); name = loghandle->lgh_name; rc = dt_declare_delete(env, llog_dir, (struct dt_key *)name, th); if (rc) GOTO(out_trans, rc); } dt_declare_ref_del(env, o, th); rc = dt_declare_destroy(env, o, th); if (rc) GOTO(out_trans, rc); rc = dt_trans_start_local(env, d, th); if (rc) GOTO(out_trans, rc); dt_write_lock(env, o, 0); if (dt_object_exists(o)) { if (name) { dt_ref_del(env, o, th); dt_read_lock(env, llog_dir, 0); rc = dt_delete(env, llog_dir, (struct dt_key *) name, th, BYPASS_CAPA); dt_read_unlock(env, llog_dir); if (rc) { CERROR("%s: can't remove llog %s: rc = %d\n", o->do_lu.lo_dev->ld_obd->obd_name, name, rc); GOTO(out_unlock, rc); } } /* * XXX: compatibility bits * on old filesystems llogs are referenced by the name * on the new ones they are referenced by OI and by * the name */ rc = dt_attr_get(env, o, &lgi->lgi_attr, NULL); if (rc) GOTO(out_unlock, rc); LASSERT(lgi->lgi_attr.la_nlink < 2); if (lgi->lgi_attr.la_nlink == 1) dt_ref_del(env, o, th); rc = dt_destroy(env, o, th); if (rc) GOTO(out_unlock, rc); } out_unlock: dt_write_unlock(env, o); out_trans: dt_trans_stop(env, d, th); if (llog_dir != NULL) lu_object_put(env, &llog_dir->do_lu); RETURN(rc); }
static int mdd_orphan_destroy(const struct lu_env *env, struct mdd_object *obj, struct dt_key *key) { struct thandle *th = NULL; struct mdd_device *mdd = mdo2mdd(&obj->mod_obj); bool orphan_exists = true; int rc = 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, MOR_TGT_CHILD); rc = mdd_orphan_declare_delete(env, obj, th); if (rc == -ENOENT) 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, MOR_TGT_ORPHAN); rc = dt_delete(env, mdd->mdd_orphans, key, th); if (rc) { CERROR("%s: could not delete orphan "DFID": rc = %d\n", mdd2obd_dev(mdd)->obd_name, PFID(mdo2fid(obj)), rc); } else 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); } rc = mdo_destroy(env, obj, th); } else { CWARN("%s: orphan %s "DFID" doesn't exist\n", mdd2obd_dev(mdd)->obd_name, (char *)key, PFID(mdo2fid(obj))); } dt_write_unlock(env, mdd->mdd_orphans); } unlock: mdd_write_unlock(env, obj); rc = mdd_trans_stop(env, mdd, 0, th); RETURN(rc); }