Ejemplo n.º 1
0
/**
 * 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);
        }
        RETURN(rc);
}
Ejemplo n.º 2
0
static int orphan_object_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);
	int rc = 0;
	ENTRY;

	th = mdd_trans_create(env, mdd);
	if (IS_ERR(th)) {
		CERROR("Cannot get thandle\n");
		RETURN(PTR_ERR(th));
	}

	rc = orph_declare_index_delete(env, obj, th);
	if (rc)
		GOTO(stop, rc);

	rc = mdo_declare_destroy(env, obj, 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) {
			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);
			}
			rc = mdo_destroy(env, obj, th);
		} else
			CERROR("could not delete object: rc = %d\n", rc);
		mdd_orphan_write_unlock(env, mdd);
	}
	mdd_write_unlock(env, obj);

stop:
	rc = mdd_trans_stop(env, mdd, 0, th);

	RETURN(rc);
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
0
static int orph_index_delete(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;
        struct dt_key *key;
        int rc;

        ENTRY;

        LASSERT(mdd_write_locked(env, obj) != 0);
        LASSERT(obj->mod_flags & ORPHAN_OBJ);
        LASSERT(obj->mod_count == 0);

        LASSERT(dor);

        key = orph_key_fill(env, mdo2fid(obj), op);
        mdd_orphan_write_lock(env, mdd);

        rc = mdd_orphan_delete_obj(env, mdd, key, th);

        if (rc == -ENOENT) {
                key = orph_key_fill_18(env, mdo2fid(obj));
                rc = mdd_orphan_delete_obj(env, mdd, key, th);
        }

        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);
                        mdd_orphan_ref_del(env, mdd, th);
                }
                obj->mod_flags &= ~ORPHAN_OBJ;
        } else {
                CERROR("could not delete object: rc = %d\n",rc);
        }

        mdd_orphan_write_unlock(env, mdd);
        RETURN(rc);
}
Ejemplo n.º 5
0
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);
}