Beispiel #1
0
/**
 * Delete unused orphan with FID \a lf from PENDING directory
 *
 * \param mdd  MDD device finishing recovery
 * \param lf   FID of file or directory to delete
 * \param key  cookie for this entry in index iterator
 *
 * \retval 0   success
 * \retval -ve error
 */
static int orph_key_test_and_del(const struct lu_env *env,
                                 struct mdd_device *mdd,
                                 struct lu_fid *lf,
                                 struct dt_key *key)
{
        struct mdd_object *mdo;
        int rc;

        mdo = mdd_object_find(env, mdd, lf);

        if (IS_ERR(mdo))
                return PTR_ERR(mdo);

        rc = -EBUSY;
        if (mdo->mod_count == 0) {
                CDEBUG(D_HA, "Found orphan "DFID", delete it\n", PFID(lf));
                rc = orphan_object_destroy(env, mdo, key);
                if (rc) /* so replay-single.sh test_37 works */
                        CERROR("%s: error unlinking orphan "DFID" from "
                               "PENDING: rc = %d\n",
			       mdd2obd_dev(mdd)->obd_name, PFID(lf), rc);
        } else {
                mdd_write_lock(env, mdo, MOR_TGT_CHILD);
                if (likely(mdo->mod_count > 0)) {
                        CDEBUG(D_HA, "Found orphan "DFID" count %d, skip it\n",
                               PFID(lf), mdo->mod_count);
                        mdo->mod_flags |= ORPHAN_OBJ;
                }
                mdd_write_unlock(env, mdo);
        }

        mdd_object_put(env, mdo);
        return rc;
}
Beispiel #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;

        mdd_txn_param_build(env, mdd, MDD_TXN_UNLINK_OP);
        th = mdd_trans_start(env, mdd);
        if (IS_ERR(th)) {
                CERROR("Cannot get thandle\n");
                RETURN(-ENOMEM);
        }

        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)
                        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);
        mdd_trans_stop(env, mdd, 0, th);

        RETURN(rc);
}
Beispiel #3
0
static int orph_key_test_and_del(const struct lu_env *env,
                                 struct mdd_device *mdd,
                                 struct lu_fid *lf,
                                 struct dt_key *key)
{
        struct mdd_object *mdo;
        int rc;

        mdo = mdd_object_find(env, mdd, lf);

        if (IS_ERR(mdo))
                return PTR_ERR(mdo);

        rc = -EBUSY;
        if (mdo->mod_count == 0) {
                CWARN("Found orphan! Delete it\n");
                rc = orphan_object_destroy(env, mdo, key);
        } else {
                mdd_write_lock(env, mdo, MOR_TGT_CHILD);
                if (likely(mdo->mod_count > 0)) {
                        CDEBUG(D_HA, "Found orphan, open count = %d\n",
                               mdo->mod_count);
                        mdo->mod_flags |= ORPHAN_OBJ;
                }
                mdd_write_unlock(env, mdo);
        }

        mdd_object_put(env, mdo);
        return rc;
}
Beispiel #4
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);
}
Beispiel #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);
}