コード例 #1
0
ファイル: mdd_device.c プロジェクト: EMSL-MSC/lustre-release
/* Start / stop recording */
static int
mdd_changelog_on(const struct lu_env *env, struct mdd_device *mdd, int on)
{
        int rc = 0;

        if ((on == 1) && ((mdd->mdd_cl.mc_flags & CLM_ON) == 0)) {
                LCONSOLE_INFO("%s: changelog on\n", mdd2obd_dev(mdd)->obd_name);
                if (mdd->mdd_cl.mc_flags & CLM_ERR) {
                        CERROR("Changelogs cannot be enabled due to error "
                               "condition (see %s log).\n",
                               mdd2obd_dev(mdd)->obd_name);
                        rc = -ESRCH;
                } else {
			spin_lock(&mdd->mdd_cl.mc_lock);
			mdd->mdd_cl.mc_flags |= CLM_ON;
			spin_unlock(&mdd->mdd_cl.mc_lock);
			rc = mdd_changelog_write_header(env, mdd, CLM_START);
		}
	} else if ((on == 0) && ((mdd->mdd_cl.mc_flags & CLM_ON) == CLM_ON)) {
		LCONSOLE_INFO("%s: changelog off\n",mdd2obd_dev(mdd)->obd_name);
		rc = mdd_changelog_write_header(env, mdd, CLM_FINI);
		spin_lock(&mdd->mdd_cl.mc_lock);
		mdd->mdd_cl.mc_flags &= ~CLM_ON;
		spin_unlock(&mdd->mdd_cl.mc_lock);
	}
	return rc;
}
コード例 #2
0
ファイル: mdd_lproc.c プロジェクト: rread/lustre
static int mdd_changelog_users_seq_show(struct seq_file *m, void *data)
{
    struct lu_env		 env;
    struct mdd_device	*mdd = m->private;
    struct llog_ctxt	*ctxt;
    __u64			 cur;
    int			 rc;

    ctxt = llog_get_context(mdd2obd_dev(mdd),
                            LLOG_CHANGELOG_USER_ORIG_CTXT);
    if (ctxt == NULL)
        return -ENXIO;
    LASSERT(ctxt->loc_handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT);

    rc = lu_env_init(&env, LCT_LOCAL);
    if (rc) {
        llog_ctxt_put(ctxt);
        return rc;
    }

    spin_lock(&mdd->mdd_cl.mc_lock);
    cur = mdd->mdd_cl.mc_index;
    spin_unlock(&mdd->mdd_cl.mc_lock);

    seq_printf(m, "current index: %llu\n", cur);
    seq_printf(m, "%-5s %s\n", "ID", "index");

    llog_cat_process(&env, ctxt->loc_handle, lprocfs_changelog_users_cb,
                     m, 0, 0);

    lu_env_fini(&env);
    llog_ctxt_put(ctxt);
    return 0;
}
コード例 #3
0
ファイル: mdd_orphans.c プロジェクト: sdsc/lustre-release
/**
 * open the PENDING directory for device \a mdd
 *
 * The PENDING directory persistently tracks files and directories that were
 * unlinked from the namespace (nlink == 0) but are still held open by clients.
 * Those inodes shouldn't be deleted if the MDS crashes, because the clients
 * would not be able to recover and reopen those files.  Instead, these inodes
 * are linked into the PENDING directory on disk, and only deleted if all
 * clients close them, or the MDS finishes client recovery without any client
 * reopening them (i.e. former clients didn't join recovery).
 *  \param d   mdd device being started.
 *
 *  \retval 0  success
 *  \retval  -ve index operation error.
 *
 */
int orph_index_init(const struct lu_env *env, struct mdd_device *mdd)
{
	struct lu_fid		 fid;
	struct dt_object	*d;
	int			 rc = 0;

	ENTRY;

	/* create PENDING dir */
	fid_zero(&fid);
	rc = mdd_local_file_create(env, mdd, &mdd->mdd_local_root_fid,
				   orph_index_name, S_IFDIR | S_IRUGO |
				   S_IWUSR | S_IXUGO, &fid);
	if (rc < 0)
		RETURN(rc);

	d = dt_locate(env, mdd->mdd_child, &fid);
	if (IS_ERR(d))
		RETURN(PTR_ERR(d));
	LASSERT(lu_object_exists(&d->do_lu));
	if (!dt_try_as_dir(env, d)) {
		CERROR("%s: \"%s\" is not an index: rc = %d\n",
		       mdd2obd_dev(mdd)->obd_name, orph_index_name, rc);
		lu_object_put(env, &d->do_lu);
		RETURN(-ENOTDIR);
	}
	mdd->mdd_orphans = d;
	RETURN(0);
}
コード例 #4
0
ファイル: mdd_lproc.c プロジェクト: rread/lustre
int mdd_procfs_init(struct mdd_device *mdd, const char *name)
{
    struct obd_device *obd = mdd2obd_dev(mdd);
    struct obd_type   *type;
    int		   rc;
    ENTRY;

    /* at the moment there is no linkage between lu_type
     * and obd_type, so we lookup obd_type this way */
    type = class_search_type(LUSTRE_MDD_NAME);

    LASSERT(name != NULL);
    LASSERT(type != NULL);
    LASSERT(obd  != NULL);

    /* Find the type procroot and add the proc entry for this device */
    obd->obd_vars = lprocfs_mdd_obd_vars;
    mdd->mdd_proc_entry = lprocfs_register(name, type->typ_procroot,
                                           obd->obd_vars, mdd);
    if (IS_ERR(mdd->mdd_proc_entry)) {
        rc = PTR_ERR(mdd->mdd_proc_entry);
        CERROR("Error %d setting up lprocfs for %s\n",
               rc, name);
        mdd->mdd_proc_entry = NULL;
        GOTO(out, rc);
    }
    rc = 0;
    EXIT;
out:
    if (rc)
        mdd_procfs_fini(mdd);
    return rc;
}
コード例 #5
0
ファイル: mdd_compat.c プロジェクト: Lezval/lustre
static int mdd_fill_fldb(const struct lu_env *env, struct mdd_device *mdd)
{
	struct seq_server_site *ss = mdd_seq_site(mdd);
	struct lu_seq_range range;
	int	rc;

	LASSERT(ss->ss_server_seq != NULL);
	LASSERT(ss->ss_server_fld != NULL);

	if (ss->ss_server_seq->lss_space.lsr_end == 0)
		return 0;

	memcpy(&range, &ss->ss_server_seq->lss_space, sizeof(range));

	/* Pre-existing ZFS does not insert any entries to FLDB, we need
	 * to insert it to FLDB during convertion */
	range.lsr_start = FID_SEQ_NORMAL;
	fld_range_set_mdt(&range);

	mutex_lock(&ss->ss_server_fld->lsf_lock);
	rc = fld_insert_entry(env, ss->ss_server_fld, &range);
	mutex_unlock(&ss->ss_server_fld->lsf_lock);

	LCONSOLE_INFO("%s: insert missing range "DRANGE"\n",
		      mdd2obd_dev(mdd)->obd_name, PRANGE(&range));
	return rc;
}
コード例 #6
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;
}
コード例 #7
0
ファイル: mdd_device.c プロジェクト: EMSL-MSC/lustre-release
static int mdd_changelog_user_purge(const struct lu_env *env,
                                    struct mdd_device *mdd, int id,
                                    long long endrec)
{
        struct mdd_changelog_user_data data;
        struct llog_ctxt *ctxt;
        int rc;
        ENTRY;

        CDEBUG(D_IOCTL, "Purge request: id=%d, endrec=%lld\n", id, endrec);

        data.mcud_id = id;
        data.mcud_minid = 0;
        data.mcud_minrec = 0;
        data.mcud_usercount = 0;
        data.mcud_endrec = endrec;
	spin_lock(&mdd->mdd_cl.mc_lock);
	endrec = mdd->mdd_cl.mc_index;
	spin_unlock(&mdd->mdd_cl.mc_lock);
        if ((data.mcud_endrec == 0) ||
            ((data.mcud_endrec > endrec) &&
             (data.mcud_endrec != MCUD_UNREGISTER)))
                data.mcud_endrec = endrec;

        ctxt = llog_get_context(mdd2obd_dev(mdd),
				LLOG_CHANGELOG_USER_ORIG_CTXT);
        if (ctxt == NULL)
                return -ENXIO;

        LASSERT(ctxt->loc_handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT);

	rc = llog_cat_process(env, ctxt->loc_handle,
			      mdd_changelog_user_purge_cb, (void *)&data,
			      0, 0);
        if ((rc >= 0) && (data.mcud_minrec > 0)) {
                CDEBUG(D_IOCTL, "Purging changelog entries up to "LPD64
                       ", referenced by "CHANGELOG_USER_PREFIX"%d\n",
                       data.mcud_minrec, data.mcud_minid);
		rc = mdd_changelog_llog_cancel(env, mdd, data.mcud_minrec);
        } else {
                CWARN("Could not determine changelog records to purge; rc=%d\n",
                      rc);
        }

        llog_ctxt_put(ctxt);

        if (!data.mcud_found) {
                CWARN("No entry for user %d.  Last changelog reference is "
                      LPD64" by changelog user %d\n", data.mcud_id,
                      data.mcud_minrec, data.mcud_minid);
               rc = -ENOENT;
        }

        if (!rc && data.mcud_usercount == 0)
                /* No more users; turn changelogs off */
                rc = mdd_changelog_on(env, mdd, 0);

        RETURN (rc);
}
コード例 #8
0
ファイル: mdd_device.c プロジェクト: EMSL-MSC/lustre-release
/**
 * Lookup method for "fid" object. Only filenames with correct SEQ:OID format
 * are valid. We also check if object with passed fid exists or not.
 */
static int obf_lookup(const struct lu_env *env, struct md_object *p,
                      const struct lu_name *lname, struct lu_fid *f,
                      struct md_op_spec *spec)
{
        char *name = (char *)lname->ln_name;
        struct mdd_device *mdd = mdo2mdd(p);
        struct mdd_object *child;
        int rc = 0;

        while (*name == '[')
                name++;

        sscanf(name, SFID, RFID(f));
        if (!fid_is_sane(f)) {
		CWARN("%s: Trying to lookup invalid FID [%s] in %s/%s, FID "
		      "format should be "DFID"\n", mdd2obd_dev(mdd)->obd_name,
		      lname->ln_name, dot_lustre_name, mdd_obf_dir_name,
		      (__u64)FID_SEQ_NORMAL, 1, 0);
                GOTO(out, rc = -EINVAL);
        }

	if (!fid_is_norm(f) && !fid_is_igif(f) && !fid_is_root(f) &&
	    !fid_seq_is_dot(f->f_seq)) {
		CWARN("%s: Trying to lookup invalid FID "DFID" in %s/%s, "
		      "sequence should be >= "LPX64" or within ["LPX64","
		      ""LPX64"].\n", mdd2obd_dev(mdd)->obd_name, PFID(f),
		      dot_lustre_name, mdd_obf_dir_name, (__u64)FID_SEQ_NORMAL,
		      (__u64)FID_SEQ_IGIF, (__u64)FID_SEQ_IGIF_MAX);
		GOTO(out, rc = -EINVAL);
	}

        /* Check if object with this fid exists */
        child = mdd_object_find(env, mdd, f);
        if (child == NULL)
                GOTO(out, rc = 0);
        if (IS_ERR(child))
                GOTO(out, rc = PTR_ERR(child));

        if (mdd_object_exists(child) == 0)
                rc = -ENOENT;

        mdd_object_put(env, child);

out:
        return rc;
}
コード例 #9
0
ファイル: mdd_device.c プロジェクト: EMSL-MSC/lustre-release
static int mdd_llog_ctxt_get(const struct lu_env *env, struct md_device *m,
                             int idx, void **h)
{
        struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev);

        *h = llog_group_get_ctxt(&mdd2obd_dev(mdd)->obd_olg, idx);
        return (*h == NULL ? -ENOENT : 0);
}
コード例 #10
0
ファイル: mdd_trans.c プロジェクト: LLNL/lustre
int mdd_txn_stop_cb(const struct lu_env *env, struct thandle *txn,
                    void *cookie)
{
        struct mdd_device *mdd = cookie;
        struct obd_device *obd = mdd2obd_dev(mdd);

        LASSERT(obd);
        return mds_lov_write_objids(obd);
}
コード例 #11
0
ファイル: mdd_device.c プロジェクト: EMSL-MSC/lustre-release
/** Setup ".lustre" directory object */
static int mdd_dot_lustre_setup(const struct lu_env *env, struct mdd_device *m)
{
	struct md_object	*mdo;
	struct lu_fid		 fid;
	int			 rc;

	ENTRY;
	/* Create ".lustre" directory in ROOT. */
	fid = LU_DOT_LUSTRE_FID;
	rc = mdd_local_file_create(env, m, &m->mdd_root_fid,
				   dot_lustre_name,
				   S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO,
				   &fid);
	if (rc < 0)
		RETURN(rc);
	mdo = mdo_locate(env, &m->mdd_md_dev, &fid);
	if (IS_ERR(mdo))
		RETURN(PTR_ERR(mdo));
	LASSERT(lu_object_exists(&mdo->mo_lu));

	m->mdd_dot_lustre = md2mdd_obj(mdo);

	rc = mdd_obf_setup(env, m);
	if (rc) {
		CERROR("%s: error initializing \"fid\" object: rc = %d.\n",
		       mdd2obd_dev(m)->obd_name, rc);
		GOTO(out, rc);
	}

	rc = mdd_lpf_setup(env, m);
	if (rc != 0) {
		CERROR("%s: error initializing \"lost+found\": rc = %d.\n",
		       mdd2obd_dev(m)->obd_name, rc);
		GOTO(out, rc);
	}

	RETURN(0);

out:
	mdd_dot_lustre_cleanup(env, m);

	return rc;
}
コード例 #12
0
ファイル: mdd_orphans.c プロジェクト: sdsc/lustre-release
/**
 *  Iterate orphan index to cleanup orphan objects after recovery is done.
 *  \param d   mdd device in recovery.
 */
int mdd_orphan_cleanup(const struct lu_env *env, struct mdd_device *d)
{
	int rc = -ENOMEM;
	char *name = NULL;

	OBD_ALLOC(name, MTI_NAME_MAXLEN);
	if (name == NULL)
		goto out;

	snprintf(name, MTI_NAME_MAXLEN, "orph_cleanup_%s",
		 mdd2obd_dev(d)->obd_name);

	rc = mdd_generic_thread_start(&d->mdd_orph_cleanup_thread,
				      __mdd_orphan_cleanup, (void *)d, name);
out:
	if (rc)
		CERROR("%s: start orphan cleanup thread failed:%d\n",
		       mdd2obd_dev(d)->obd_name, rc);
	if (name)
		OBD_FREE(name, MTI_NAME_MAXLEN);
	return rc;
}
コード例 #13
0
ファイル: mdd_compat.c プロジェクト: Lezval/lustre
static int mdd_convert_object(const struct lu_env *env,
			      struct mdd_device *mdd,
			      const struct lu_fid *fid,
			      const struct lu_name *name)
{
	struct mdd_object	*o;
	struct lu_attr		*la = MDD_ENV_VAR(env, cattr);
	int			 rc;
	ENTRY;

	o = mdd_object_find(env, mdd, fid);
	if (IS_ERR(o)) {
		CERROR("%s: can't access the object: rc = %d\n",
		       mdd2obd_dev(mdd)->obd_name, (int)PTR_ERR(o));
		RETURN(PTR_ERR(o));
	}

	rc = mdo_attr_get(env, o, la, BYPASS_CAPA);
	if (rc)
		GOTO(out, rc);

	if (S_ISDIR(la->la_mode)) {
		/* remove "." and ".." if a directory */
		rc = mdd_convert_remove_dots(env, mdd, o);
		if (rc)
			GOTO(out, rc);
	}

	/* update linkEA */
	rc = mdd_convert_linkea(env, mdd, o, name);
	if (rc)
		CERROR("%s: can't convert: rc = %d\n",
		       mdd2obd_dev(mdd)->obd_name, rc);

out:
	mdd_object_put(env, o);
	RETURN(0);
}
コード例 #14
0
ファイル: mdd_device.c プロジェクト: EMSL-MSC/lustre-release
/** Add a CL_MARK record to the changelog
 * \param mdd
 * \param markerflags - CLM_*
 * \retval 0 ok
 */
int mdd_changelog_write_header(const struct lu_env *env,
			       struct mdd_device *mdd, int markerflags)
{
	struct obd_device		*obd = mdd2obd_dev(mdd);
	struct llog_changelog_rec	*rec;
	struct lu_buf			*buf;
	struct llog_ctxt		*ctxt;
	int				 reclen;
	int				 len = strlen(obd->obd_name);
	int				 rc;

	ENTRY;

	if (mdd->mdd_cl.mc_mask & (1 << CL_MARK)) {
		mdd->mdd_cl.mc_starttime = cfs_time_current_64();
		RETURN(0);
	}

	reclen = llog_data_len(sizeof(*rec) + len);
	buf = lu_buf_check_and_alloc(&mdd_env_info(env)->mti_big_buf, reclen);
	if (buf->lb_buf == NULL)
		RETURN(-ENOMEM);
	rec = buf->lb_buf;

        rec->cr.cr_flags = CLF_VERSION;
        rec->cr.cr_type = CL_MARK;
        rec->cr.cr_namelen = len;
	memcpy(changelog_rec_name(&rec->cr), obd->obd_name, rec->cr.cr_namelen);
        /* Status and action flags */
	rec->cr.cr_markerflags = mdd->mdd_cl.mc_flags | markerflags;
	rec->cr_hdr.lrh_len = llog_data_len(changelog_rec_size(&rec->cr) +
					    rec->cr.cr_namelen);
	rec->cr_hdr.lrh_type = CHANGELOG_REC;
	rec->cr.cr_time = cl_time();
	spin_lock(&mdd->mdd_cl.mc_lock);
	rec->cr.cr_index = ++mdd->mdd_cl.mc_index;
	spin_unlock(&mdd->mdd_cl.mc_lock);

	ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT);
	LASSERT(ctxt);

	rc = llog_cat_add(env, ctxt->loc_handle, &rec->cr_hdr, NULL);
	if (rc > 0)
		rc = 0;
	llog_ctxt_put(ctxt);

	/* assume on or off event; reset repeat-access time */
	mdd->mdd_cl.mc_starttime = cfs_time_current_64();
	RETURN(rc);
}
コード例 #15
0
ファイル: mdd_device.c プロジェクト: EMSL-MSC/lustre-release
/**
 * cleanup the context created by llog_setup_named()
 */
static int mdd_hsm_actions_llog_fini(const struct lu_env *env,
				     struct mdd_device *m)
{
	struct obd_device	*obd = mdd2obd_dev(m);
	struct llog_ctxt	*lctxt;
	ENTRY;

	lctxt = llog_get_context(obd, LLOG_AGENT_ORIG_CTXT);
	if (lctxt) {
		llog_cat_close(env, lctxt->loc_handle);
		lctxt->loc_handle = NULL;
		llog_cleanup(env, lctxt);
	}

	RETURN(0);
}
コード例 #16
0
ファイル: mdd_lproc.c プロジェクト: hejin/lustre-stable
static int lprocfs_rd_changelog_users(char *page, char **start, off_t off,
                                      int count, int *eof, void *data)
{
	struct lu_env		 env;
	struct mdd_device	*mdd = data;
	struct llog_ctxt	*ctxt;
	struct cucb_data	 cucb;
	__u64			 cur;
	int			 rc;

        *eof = 1;

        ctxt = llog_get_context(mdd2obd_dev(mdd),
				LLOG_CHANGELOG_USER_ORIG_CTXT);
        if (ctxt == NULL)
                return -ENXIO;
        LASSERT(ctxt->loc_handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT);

	rc = lu_env_init(&env, LCT_LOCAL);
	if (rc) {
		llog_ctxt_put(ctxt);
		return rc;
	}

	spin_lock(&mdd->mdd_cl.mc_lock);
	cur = mdd->mdd_cl.mc_index;
	spin_unlock(&mdd->mdd_cl.mc_lock);

        cucb.count = count;
        cucb.page = page;
        cucb.idx = 0;

        cucb.idx += snprintf(cucb.page + cucb.idx, cucb.count - cucb.idx,
                              "current index: "LPU64"\n", cur);

        cucb.idx += snprintf(cucb.page + cucb.idx, cucb.count - cucb.idx,
                              "%-5s %s\n", "ID", "index");

	llog_cat_process(&env, ctxt->loc_handle, lprocfs_changelog_users_cb,
			 &cucb, 0, 0);

	lu_env_fini(&env);
	llog_ctxt_put(ctxt);
	return cucb.idx;
}
コード例 #17
0
ファイル: mdd_device.c プロジェクト: EMSL-MSC/lustre-release
/**
 * set llog methods and create LLOG_AGENT_ORIG_CTXT llog
 * object in obd_device
 */
static int mdd_hsm_actions_llog_init(const struct lu_env *env,
				     struct mdd_device *m)
{
	struct obd_device	*obd = mdd2obd_dev(m);
	struct llog_ctxt	*ctxt = NULL;
	int			 rc;
	ENTRY;

	OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt);
	obd->obd_lvfs_ctxt.dt = m->mdd_bottom;

	rc = llog_setup(env, obd, &obd->obd_olg, LLOG_AGENT_ORIG_CTXT,
			obd, &hsm_actions_logops);
	if (rc) {
		CERROR("%s: hsm actions llog setup failed: rc = %d\n",
			obd->obd_name, rc);
		RETURN(rc);
	}

	ctxt = llog_get_context(obd, LLOG_AGENT_ORIG_CTXT);
	LASSERT(ctxt);

	rc = llog_open_create(env, ctxt, &ctxt->loc_handle, NULL,
			      HSM_ACTIONS);
	if (rc) {
		CERROR("%s: hsm actions llog open_create failed: rc = %d\n",
			obd->obd_name, rc);
		GOTO(out_cleanup, rc);
	}

	rc = llog_cat_init_and_process(env, ctxt->loc_handle);
	if (rc)
		GOTO(out_close, rc);

	llog_ctxt_put(ctxt);
	RETURN(0);

out_close:
	llog_cat_close(env, ctxt->loc_handle);
	ctxt->loc_handle = NULL;
out_cleanup:
	llog_cleanup(env, ctxt);

	return rc;
}
コード例 #18
0
ファイル: mdd_orphans.c プロジェクト: Xyratex/lustre-stable
/**
 *  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);
}
コード例 #19
0
ファイル: mdd_device.c プロジェクト: EMSL-MSC/lustre-release
static int mdd_changelog_user_register(const struct lu_env *env,
				       struct mdd_device *mdd, int *id)
{
        struct llog_ctxt *ctxt;
        struct llog_changelog_user_rec *rec;
        int rc;
        ENTRY;

        ctxt = llog_get_context(mdd2obd_dev(mdd),
				LLOG_CHANGELOG_USER_ORIG_CTXT);
        if (ctxt == NULL)
                RETURN(-ENXIO);

        OBD_ALLOC_PTR(rec);
        if (rec == NULL) {
                llog_ctxt_put(ctxt);
                RETURN(-ENOMEM);
        }

        /* Assume we want it on since somebody registered */
        rc = mdd_changelog_on(env, mdd, 1);
        if (rc)
                GOTO(out, rc);

        rec->cur_hdr.lrh_len = sizeof(*rec);
        rec->cur_hdr.lrh_type = CHANGELOG_USER_REC;
	spin_lock(&mdd->mdd_cl.mc_user_lock);
	if (mdd->mdd_cl.mc_lastuser == (unsigned int)(-1)) {
		spin_unlock(&mdd->mdd_cl.mc_user_lock);
		CERROR("Maximum number of changelog users exceeded!\n");
		GOTO(out, rc = -EOVERFLOW);
	}
	*id = rec->cur_id = ++mdd->mdd_cl.mc_lastuser;
	rec->cur_endrec = mdd->mdd_cl.mc_index;
	spin_unlock(&mdd->mdd_cl.mc_user_lock);

	rc = llog_cat_add(env, ctxt->loc_handle, &rec->cur_hdr, NULL);

        CDEBUG(D_IOCTL, "Registered changelog user %d\n", *id);
out:
        OBD_FREE_PTR(rec);
        llog_ctxt_put(ctxt);
        RETURN(rc);
}
コード例 #20
0
ファイル: mdd_device.c プロジェクト: EMSL-MSC/lustre-release
/** Remove entries with indicies up to and including \a endrec from the
 *  changelog
 * \param mdd
 * \param endrec
 * \retval 0 ok
 */
static int
mdd_changelog_llog_cancel(const struct lu_env *env, struct mdd_device *mdd,
			  long long endrec)
{
        struct obd_device *obd = mdd2obd_dev(mdd);
        struct llog_ctxt *ctxt;
        long long unsigned cur;
        int rc;

        ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT);
        if (ctxt == NULL)
                return -ENXIO;

	spin_lock(&mdd->mdd_cl.mc_lock);
	cur = (long long)mdd->mdd_cl.mc_index;
	spin_unlock(&mdd->mdd_cl.mc_lock);
        if (endrec > cur)
                endrec = cur;

        /* purge to "0" is shorthand for everything */
        if (endrec == 0)
                endrec = cur;

        /* If purging all records, write a header entry so we don't have an
           empty catalog and we're sure to have a valid starting index next
           time.  In case of crash, we just restart with old log so we're
           allright. */
        if (endrec == cur) {
                /* XXX: transaction is started by llog itself */
                rc = mdd_changelog_write_header(env, mdd, CLM_PURGE);
                if (rc)
                      goto out;
        }

        /* Some records were purged, so reset repeat-access time (so we
           record new mtime update records, so users can see a file has been
           changed since the last purge) */
        mdd->mdd_cl.mc_starttime = cfs_time_current_64();

	rc = llog_cancel(env, ctxt, (struct llog_cookie *)&endrec, 0);
out:
        llog_ctxt_put(ctxt);
        return rc;
}
コード例 #21
0
ファイル: mdd_device.c プロジェクト: EMSL-MSC/lustre-release
static void mdd_changelog_fini(const struct lu_env *env,
			       struct mdd_device *mdd)
{
	struct obd_device	*obd = mdd2obd_dev(mdd);
	struct llog_ctxt	*ctxt;

	mdd->mdd_cl.mc_flags = 0;

	ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT);
	if (ctxt) {
		llog_cat_close(env, ctxt->loc_handle);
		llog_cleanup(env, ctxt);
	}
	ctxt = llog_get_context(obd, LLOG_CHANGELOG_USER_ORIG_CTXT);
	if (ctxt) {
		llog_cat_close(env, ctxt->loc_handle);
		llog_cleanup(env, ctxt);
	}
}
コード例 #22
0
ファイル: mdd_device.c プロジェクト: EMSL-MSC/lustre-release
static int mdd_changelog_init(const struct lu_env *env, struct mdd_device *mdd)
{
	struct obd_device	*obd = mdd2obd_dev(mdd);
	int			 rc;

	mdd->mdd_cl.mc_index = 0;
	spin_lock_init(&mdd->mdd_cl.mc_lock);
	mdd->mdd_cl.mc_starttime = cfs_time_current_64();
	mdd->mdd_cl.mc_flags = 0; /* off by default */
	mdd->mdd_cl.mc_mask = CHANGELOG_DEFMASK;
	spin_lock_init(&mdd->mdd_cl.mc_user_lock);
	mdd->mdd_cl.mc_lastuser = 0;

	rc = mdd_changelog_llog_init(env, mdd);
	if (rc) {
		CERROR("%s: changelog setup during init failed: rc = %d\n",
		       obd->obd_name, rc);
		mdd->mdd_cl.mc_flags |= CLM_ERR;
	}

	return rc;
}
コード例 #23
0
ファイル: mdd_device.c プロジェクト: EMSL-MSC/lustre-release
static int mdd_process_config(const struct lu_env *env,
                              struct lu_device *d, struct lustre_cfg *cfg)
{
        struct mdd_device *m    = lu2mdd_dev(d);
        struct dt_device  *dt   = m->mdd_child;
        struct lu_device  *next = &dt->dd_lu_dev;
        int rc;
        ENTRY;

        switch (cfg->lcfg_command) {
	case LCFG_PARAM: {
		struct obd_device *obd = mdd2obd_dev(m);

		rc = class_process_proc_param(PARAM_MDD, obd->obd_vars, cfg, m);
		if (rc > 0 || rc == -ENOSYS)
			/* we don't understand; pass it on */
			rc = next->ld_ops->ldo_process_config(env, next, cfg);
		break;
	}
        case LCFG_SETUP:
                rc = next->ld_ops->ldo_process_config(env, next, cfg);
                if (rc)
                        GOTO(out, rc);
		dt_conf_get(env, dt, &m->mdd_dt_conf);
                break;
        case LCFG_CLEANUP:
		rc = next->ld_ops->ldo_process_config(env, next, cfg);
		lu_dev_del_linkage(d->ld_site, d);
		mdd_device_shutdown(env, m, cfg);
		break;
        default:
                rc = next->ld_ops->ldo_process_config(env, next, cfg);
                break;
        }
out:
        RETURN(rc);
}
コード例 #24
0
ファイル: mdd_lproc.c プロジェクト: rread/lustre
static int mdd_changelog_size_ctxt(const struct lu_env *env,
                                   struct mdd_device *mdd,
                                   int index, __u64 *val)
{
    struct llog_ctxt	*ctxt;

    ctxt = llog_get_context(mdd2obd_dev(mdd),
                            index);
    if (ctxt == NULL)
        return -ENXIO;

    if (!(ctxt->loc_handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT)) {
        CERROR("%s: ChangeLog has wrong flags: rc = %d\n",
               ctxt->loc_obd->obd_name, -EINVAL);
        llog_ctxt_put(ctxt);
        return -EINVAL;
    }

    *val += llog_cat_size(env, ctxt->loc_handle);

    llog_ctxt_put(ctxt);

    return 0;
}
コード例 #25
0
/**
 * delete unreferenced files and directories in the PENDING directory
 *
 * Files that remain in PENDING after client->MDS recovery has completed
 * have to be referenced (opened) by some client during recovery, or they
 * will be deleted here (for clients that did not complete recovery).
 *
 * \param mdd  MDD device finishing recovery
 *
 * \retval 0   success
 * \retval -ve error
 */
static int orph_index_iterate(const struct lu_env *env,
			      struct mdd_device *mdd)
{
	struct dt_object *dor = mdd->mdd_orphans;
	struct lu_dirent *ent = &mdd_env_info(env)->mti_ent;
	const struct dt_it_ops *iops;
	struct dt_it     *it;
	struct lu_fid     fid;
        int               key_sz = 0;
        int               rc;
        __u64             cookie;
        ENTRY;

        /* In recovery phase, do not need for any lock here */
        iops = &dor->do_index_ops->dio_it;
        it = iops->init(env, dor, LUDA_64BITHASH, BYPASS_CAPA);
        if (IS_ERR(it)) {
                rc = PTR_ERR(it);
                CERROR("%s: cannot clean PENDING: rc = %d\n",
		       mdd2obd_dev(mdd)->obd_name, rc);
                GOTO(out, rc);
        }

        rc = iops->load(env, it, 0);
        if (rc < 0)
                GOTO(out_put, rc);
        if (rc == 0) {
                CERROR("%s: error loading iterator to clean PENDING\n",
		       mdd2obd_dev(mdd)->obd_name);
                /* Index contains no zero key? */
                GOTO(out_put, rc = -EIO);
        }

	do {
		key_sz = iops->key_size(env, it);
		/* filter out "." and ".." entries from PENDING dir. */
		if (key_sz < 8)
			goto next;

		rc = iops->rec(env, it, (struct dt_rec *)ent, LUDA_64BITHASH);
		if (rc != 0) {
			CERROR("%s: fail to get FID for orphan it: rc = %d\n",
			       mdd2obd_dev(mdd)->obd_name, rc);
			goto next;
		}

		fid_le_to_cpu(&fid, &ent->lde_fid);
		if (!fid_is_sane(&fid)) {
			CERROR("%s: bad FID "DFID" cleaning PENDING\n",
			       mdd2obd_dev(mdd)->obd_name, PFID(&fid));
			goto next;
		}

		/* kill orphan object */
		cookie = iops->store(env, it);
		iops->put(env, it);
		rc = orph_key_test_and_del(env, mdd, &fid,
					   (struct dt_key *)ent->lde_name);

		/* after index delete reset iterator */
		if (rc == 0)
			rc = iops->get(env, it, (const void *)"");
		else
			rc = iops->load(env, it, cookie);
next:
		rc = iops->next(env, it);
	} while (rc == 0);

	GOTO(out_put, rc = 0);
out_put:
	iops->put(env, it);
	iops->fini(env, it);

out:
	return rc;
}
コード例 #26
0
ファイル: mdd_compat.c プロジェクト: Lezval/lustre
static int mdd_fix_children(const struct lu_env *env,
			    struct mdd_device *mdd,
			    struct dt_object *o)
{
	struct mdd_thread_info *info = mdd_env_info(env);
	const struct dt_it_ops *iops;
	struct lu_name		name;
	struct dt_it	       *it;
	struct lu_dirent       *ent;
	int			rc;
	ENTRY;

	/* scan /ROOT and update all ".." and linkEAs */
	ent = (struct lu_dirent *)&info->mti_xattr_buf;
	iops = &o->do_index_ops->dio_it;

	it = iops->init(env, o, LUDA_64BITHASH, BYPASS_CAPA);
	if (IS_ERR(it)) {
		rc = PTR_ERR(it);
		CERROR("%s: can't initialize the iterator: rc = %d\n",
		       mdd2obd_dev(mdd)->obd_name, rc);
		GOTO(out, rc);
	}

	rc = iops->load(env, it, 0);
	if (rc <= 0)
		GOTO(out_put, rc);

	do {
		rc = iops->key_size(env, it);
		if (rc == 0)
			goto next;

		/* calculate max space required for lu_dirent */
		rc = lu_dirent_calc_size(rc, 0);
		LASSERT(rc <= sizeof(info->mti_xattr_buf));

		rc = iops->rec(env, it, (struct dt_rec *)ent, LUDA_TYPE);
		if (rc == 0) {
			CDEBUG(D_OTHER, "convert %*s -> "DFID"\n",
			       ent->lde_namelen, ent->lde_name,
			       PFID(&ent->lde_fid));
			name.ln_namelen = ent->lde_namelen;
			name.ln_name = ent->lde_name;
			rc = mdd_convert_object(env, mdd, &ent->lde_fid, &name);
			if (rc) {
				CERROR("%s: can't convert "DFID": rc = %d\n",
				       mdd2obd_dev(mdd)->obd_name,
				       PFID(&ent->lde_fid), rc);
				break;
			}
		}

next:
		rc = iops->next(env, it);
	} while (rc == 0);
	if (rc > 0)
		rc = 0;

out_put:
	iops->put(env, it);
	iops->fini(env, it);
out:
	RETURN(rc);
}
コード例 #27
0
ファイル: mdd_compat.c プロジェクト: Lezval/lustre
int mdd_compat_fixes(const struct lu_env *env, struct mdd_device *mdd)
{
	struct mdd_thread_info	*info = mdd_env_info(env);
	struct mdd_object	*root;
	struct dt_object	*o;
	struct lustre_mdt_attrs	*lma;
	struct lu_buf		 buf;
	int			 rc;
	ENTRY;

	/* IGIF FIDS are valid for old 1.8 and 2.[123] ROOT and are kept.
	 * Normal FIDs used by Xyratex 1.8->2.1 upgrade tool are also kept. */
	if (fid_is_igif(&mdd->mdd_root_fid) || fid_is_norm(&mdd->mdd_root_fid))
		RETURN(0);

	/*
	 * FID is supposed to be FID_SEQ_ROOT for:
	 *  - new ldiskfs fs
	 *  - new ZFS fs
	 *  - old ZFS fs, by now processed with osd_convert_root_to_new_seq()
	 */
	if (fid_seq(&mdd->mdd_root_fid) != FID_SEQ_ROOT) {
		CERROR("%s: wrong FID "DFID" is used for /ROOT\n",
		       mdd2obd_dev(mdd)->obd_name,
		       PFID(&mdd->mdd_root_fid));
		RETURN(-EINVAL);
	}

	root = mdd_object_find(env, mdd, &mdd->mdd_root_fid);
	if (IS_ERR(root))
		RETURN(PTR_ERR(root));
	o = mdd_object_child(root);

	CDEBUG(D_OTHER, "/ROOT = "DFID"\n", PFID(&mdd->mdd_root_fid));

	if (dt_try_as_dir(env, o) == 0) {
		CERROR("%s: not a directory\n", mdd2obd_dev(mdd)->obd_name);
		GOTO(out, rc = -ENOTDIR);
	}

	lma = (struct lustre_mdt_attrs *)&info->mti_xattr_buf;
	CLASSERT(sizeof(info->mti_xattr_buf) >= LMA_OLD_SIZE);
	buf.lb_len = LMA_OLD_SIZE;
	buf.lb_buf = lma;
	rc = mdo_xattr_get(env, root, &buf, XATTR_NAME_LMA, BYPASS_CAPA);
	if (rc < 0 && rc != -ENODATA) {
		CERROR("%s: can't fetch LMA: rc = %d\n",
		       mdd2obd_dev(mdd)->obd_name, rc);
		GOTO(out, rc);
	}

	lustre_lma_swab(lma);
	if (lu_fid_eq(&lma->lma_self_fid, &mdd->mdd_root_fid)) {
		/* /ROOT has been converted already
		 * or was correct from the beginning */
		CDEBUG(D_OTHER, "%s: converted already\n",
		       mdd2obd_dev(mdd)->obd_name);
		GOTO(out, rc = 0);
	}

	/* this is supposed to happen only on pre-production ZFS backend */
	if (strcmp(mdd->mdd_bottom->dd_lu_dev.ld_type->ldt_name,
		   LUSTRE_OSD_ZFS_NAME) != 0) {
		CERROR("%s: "DFID" is used on ldiskfs?!\n",
		       mdd2obd_dev(mdd)->obd_name, PFID(&mdd->mdd_root_fid));
		GOTO(out, rc = -ENOTSUPP);
	}

	LCONSOLE_INFO("%s: FID of /ROOT has been changed. "
		      "Please remount the clients.\n",
		      mdd2obd_dev(mdd)->obd_name);

	/* Fill FLDB first */
	rc = mdd_fill_fldb(env, mdd);
	if (rc)
		GOTO(out, rc);

	/* remove ./.. from /ROOT */
	rc = mdd_convert_remove_dots(env, mdd, root);
	if (rc)
		GOTO(out, rc);

	/* go over the directory, fix all the objects */
	rc = mdd_fix_children(env, mdd, o);
	if (rc)
		GOTO(out, rc);

	/* Update LMA on /ROOT.  Done for simplicity in MDD, not in osd-zfs.
	 * Correct LMA will imply the whole directory has been coverted
	 * successfully, otherwise it will be retried on next mount. */
	rc = mdd_convert_lma(env, mdd, root);

out:
	mdd_object_put(env, root);
	RETURN(rc);
}
コード例 #28
0
ファイル: mdd_device.c プロジェクト: EMSL-MSC/lustre-release
static int mdd_changelog_llog_init(const struct lu_env *env,
				   struct mdd_device *mdd)
{
	struct obd_device	*obd = mdd2obd_dev(mdd);
	struct llog_ctxt	*ctxt = NULL, *uctxt = NULL;
	int			 rc;

	ENTRY;

	/* LU-2844 mdd setup failure should not cause umount oops */
	if (OBD_FAIL_CHECK(OBD_FAIL_MDS_CHANGELOG_INIT))
		RETURN(-EIO);

	OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt);
	obd->obd_lvfs_ctxt.dt = mdd->mdd_bottom;
	rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CHANGELOG_ORIG_CTXT,
			obd, &changelog_orig_logops);
	if (rc) {
		CERROR("%s: changelog llog setup failed: rc = %d\n",
		       obd->obd_name, rc);
		RETURN(rc);
	}

	ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT);
	LASSERT(ctxt);

	rc = llog_open_create(env, ctxt, &ctxt->loc_handle, NULL,
			      CHANGELOG_CATALOG);
	if (rc)
		GOTO(out_cleanup, rc);

	rc = llog_cat_init_and_process(env, ctxt->loc_handle);
	if (rc)
		GOTO(out_close, rc);

	rc = llog_cat_reverse_process(env, ctxt->loc_handle,
				      changelog_init_cb, mdd);

	if (rc < 0) {
		CERROR("%s: changelog init failed: rc = %d\n", obd->obd_name,
		       rc);
		GOTO(out_close, rc);
	}

	CDEBUG(D_IOCTL, "changelog starting index="LPU64"\n",
	       mdd->mdd_cl.mc_index);

	/* setup user changelog */
	rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CHANGELOG_USER_ORIG_CTXT,
			obd, &changelog_orig_logops);
	if (rc) {
		CERROR("%s: changelog users llog setup failed: rc = %d\n",
		       obd->obd_name, rc);
		GOTO(out_close, rc);
	}

	uctxt = llog_get_context(obd, LLOG_CHANGELOG_USER_ORIG_CTXT);
	LASSERT(ctxt);

	rc = llog_open_create(env, uctxt, &uctxt->loc_handle, NULL,
			      CHANGELOG_USERS);
	if (rc)
		GOTO(out_ucleanup, rc);

	uctxt->loc_handle->lgh_logops->lop_add = llog_cat_add_rec;
	uctxt->loc_handle->lgh_logops->lop_declare_add = llog_cat_declare_add_rec;

	rc = llog_cat_init_and_process(env, uctxt->loc_handle);
	if (rc)
		GOTO(out_uclose, rc);

	rc = llog_cat_reverse_process(env, uctxt->loc_handle,
				      changelog_user_init_cb, mdd);
	if (rc < 0) {
		CERROR("%s: changelog user init failed: rc = %d\n",
		       obd->obd_name, rc);
		GOTO(out_uclose, rc);
	}

	/* If we have registered users, assume we want changelogs on */
	if (mdd->mdd_cl.mc_lastuser > 0) {
		rc = mdd_changelog_on(env, mdd, 1);
		if (rc < 0)
			GOTO(out_uclose, rc);
	}
	llog_ctxt_put(ctxt);
	llog_ctxt_put(uctxt);
	RETURN(0);
out_uclose:
	llog_cat_close(env, uctxt->loc_handle);
out_ucleanup:
	llog_cleanup(env, uctxt);
out_close:
	llog_cat_close(env, ctxt->loc_handle);
out_cleanup:
	llog_cleanup(env, ctxt);
	return rc;
}
コード例 #29
0
ファイル: mdd_device.c プロジェクト: EMSL-MSC/lustre-release
static int mdd_prepare(const struct lu_env *env,
                       struct lu_device *pdev,
                       struct lu_device *cdev)
{
	struct mdd_device	*mdd = lu2mdd_dev(cdev);
	struct lu_device	*next = &mdd->mdd_child->dd_lu_dev;
	struct lu_fid		 fid;
	int			 rc;

	ENTRY;

	rc = next->ld_ops->ldo_prepare(env, cdev, next);
	if (rc)
		RETURN(rc);

	/* Setup local dirs */
	fid.f_seq = FID_SEQ_LOCAL_NAME;
	fid.f_oid = 1;
	fid.f_ver = 0;
	rc = local_oid_storage_init(env, mdd->mdd_bottom, &fid,
				    &mdd->mdd_los);
	if (rc)
		RETURN(rc);

	rc = dt_root_get(env, mdd->mdd_child, &mdd->mdd_local_root_fid);
	if (rc < 0)
		GOTO(out_los, rc);

	lu_root_fid(&fid);
	if (mdd_seq_site(mdd)->ss_node_id == 0) {
		rc = mdd_local_file_create(env, mdd, &mdd->mdd_local_root_fid,
					   mdd_root_dir_name, S_IFDIR |
					   S_IRUGO | S_IWUSR | S_IXUGO, &fid);
		if (rc != 0) {
			CERROR("%s: create root fid failed: rc = %d\n",
			       mdd2obd_dev(mdd)->obd_name, rc);
			GOTO(out_los, rc);
		}

		mdd->mdd_root_fid = fid;
		rc = mdd_dot_lustre_setup(env, mdd);
		if (rc != 0) {
			CERROR("%s: initializing .lustre failed: rc = %d\n",
			       mdd2obd_dev(mdd)->obd_name, rc);
			GOTO(out_los, rc);
		}

		rc = mdd_compat_fixes(env, mdd);
		if (rc != 0)
			GOTO(out_dot, rc);
	} else {
		/* Normal client usually send root access to MDT0 directly,
		 * the root FID on non-MDT0 will only be used by echo client. */
		mdd->mdd_root_fid = fid;
	}

	rc = orph_index_init(env, mdd);
	if (rc < 0)
		GOTO(out_dot, rc);

	rc = mdd_changelog_init(env, mdd);
	if (rc != 0) {
		CERROR("%s: failed to initialize changelog: rc = %d\n",
		       mdd2obd_dev(mdd)->obd_name, rc);
		GOTO(out_orph, rc);
	}

	rc = mdd_hsm_actions_llog_init(env, mdd);
	if (rc != 0)
		GOTO(out_changelog, rc);

	rc = lfsck_register(env, mdd->mdd_bottom, mdd->mdd_child,
			    mdd2obd_dev(mdd), mdd_lfsck_out_notify,
			    mdd, true);
	if (rc != 0) {
		CERROR("%s: failed to initialize lfsck: rc = %d\n",
		       mdd2obd_dev(mdd)->obd_name, rc);
		GOTO(out_hsm, rc);
	}
	RETURN(0);
out_hsm:
	mdd_hsm_actions_llog_fini(env, mdd);
out_changelog:
	mdd_changelog_fini(env, mdd);
out_orph:
	orph_index_fini(env, mdd);
out_dot:
	if (mdd_seq_site(mdd)->ss_node_id == 0)
		mdd_dot_lustre_cleanup(env, mdd);
out_los:
	local_oid_storage_fini(env, mdd->mdd_los);
	mdd->mdd_los = NULL;

	return rc;
}
コード例 #30
0
ファイル: mdd_orphans.c プロジェクト: Xyratex/lustre-stable
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);
}