- get rid of second attr_get() in cmm_split_check().
MODULES := cmm
-cmm-objs := cmm_device.o cmm_object.o mdc_device.o mdc_object.o
+cmm-objs := cmm_device.o cmm_object.o cmm_lproc.o mdc_device.o mdc_object.o
@SPLIT_TRUE@cmm-objs += cmm_split.o
/* Assign site's fld client ref, needed for asserts in osd. */
ls = cmm2lu_dev(m)->ld_site;
ls->ls_client_fld = m->cmm_fld;
-
+ err = cmm_procfs_init(m, name);
+
RETURN(err);
}
fld_client_fini(cm->cmm_fld);
ls = cmm2lu_dev(cm)->ld_site;
ls->ls_client_fld = NULL;
+ cmm_procfs_fini(cm);
RETURN (md2lu_dev(cm->cmm_child));
}
struct cmm_device {
- struct md_device cmm_md_dev;
+ struct md_device cmm_md_dev;
/* device flags, taken from enum cmm_flags */
- __u32 cmm_flags;
+ __u32 cmm_flags;
/* underlaying device in MDS stack, usually MDD */
- struct md_device *cmm_child;
+ struct md_device *cmm_child;
/* FLD client to talk to FLD */
- struct lu_client_fld *cmm_fld;
+ struct lu_client_fld *cmm_fld;
/* other MD servers in cluster */
- mdsno_t cmm_local_num;
- __u32 cmm_tgt_count;
- struct list_head cmm_targets;
- spinlock_t cmm_tgt_guard;
+ mdsno_t cmm_local_num;
+ __u32 cmm_tgt_count;
+ struct list_head cmm_targets;
+ spinlock_t cmm_tgt_guard;
+ cfs_proc_dir_entry_t *cmm_proc_entry;
+ struct lprocfs_stats *cmm_stats;
};
enum cmm_flags {
int cmm_upcall(const struct lu_env *env, struct md_device *md,
enum md_upcall_event ev);
+
#ifdef HAVE_SPLIT_SUPPORT
+#define CMM_MD_SIZE(stripes) (sizeof(struct lmv_stripe_md) + \
+ (stripes) * sizeof(struct lu_fid))
+
/* cmm_split.c */
static inline struct lu_buf *cmm_buf_get(const struct lu_env *env,
void *area, ssize_t len)
int cmm_fld_lookup(struct cmm_device *cm, const struct lu_fid *fid,
mdsno_t *mds, const struct lu_env *env);
+int cmm_procfs_init(struct cmm_device *cmm, const char *name);
+int cmm_procfs_fini(struct cmm_device *cmm);
+
+void cmm_lprocfs_time_start(struct cmm_device *cmm,
+ struct timeval *start, int op);
+
+void cmm_lprocfs_time_end(struct cmm_device *cmm,
+ struct timeval *start, int op);
+
+enum {
+ LPROC_CMM_SPLIT_CHECK = 0,
+ LPROC_CMM_SPLIT_EXEC,
+ LPROC_CMM_LAST
+};
+
#endif /* __KERNEL__ */
#endif /* _CMM_INTERNAL_H */
--- /dev/null
+/* -*- MODE: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * cmm/cmm_lproc.c
+ * CMM lprocfs stuff
+ *
+ * Copyright (C) 2006 Cluster File Systems, Inc.
+ * Author: Wang Di <wangdi@clusterfs.com>
+ * Author: Yury Umanets <umka@clusterfs.com>
+ *
+ * This file is part of the Lustre file system, http://www.lustre.org
+ * Lustre is a trademark of Cluster File Systems, Inc.
+ *
+ * You may have signed or agreed to another license before downloading
+ * this software. If so, you are bound by the terms and conditions
+ * of that agreement, and the following does not apply to you. See the
+ * LICENSE file included with this distribution for more information.
+ *
+ * If you did not agree to a different license, then this copy of Lustre
+ * is open source software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In either case, Lustre is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * license text for more details.
+ */
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+#define DEBUG_SUBSYSTEM S_MDS
+
+#include <linux/module.h>
+#include <obd.h>
+#include <obd_class.h>
+#include <lustre_ver.h>
+#include <obd_support.h>
+#include <lprocfs_status.h>
+
+#include <lustre/lustre_idl.h>
+
+#include "cmm_internal.h"
+
+static int cmm_procfs_init_stats(struct cmm_device *cmm, int num_stats)
+{
+ struct lprocfs_stats *stats;
+ int rc;
+ ENTRY;
+
+ stats = lprocfs_alloc_stats(num_stats);
+ if (!stats)
+ RETURN(-ENOMEM);
+
+ rc = lprocfs_register_stats(cmm->cmm_proc_entry, "stats", stats);
+ if (rc != 0)
+ GOTO(cleanup, rc);
+
+ cmm->cmm_stats = stats;
+
+ lprocfs_counter_init(cmm->cmm_stats, LPROC_CMM_SPLIT_CHECK,
+ LPROCFS_CNTR_AVGMINMAX, "split_check", "time");
+ lprocfs_counter_init(cmm->cmm_stats, LPROC_CMM_SPLIT_EXEC,
+ LPROCFS_CNTR_AVGMINMAX, "split_exec", "time");
+ EXIT;
+cleanup:
+ if (rc) {
+ lprocfs_free_stats(stats);
+ cmm->cmm_stats = NULL;
+ }
+ return rc;
+}
+
+int cmm_procfs_init(struct cmm_device *cmm, const char *name)
+{
+ struct lu_device *ld = &cmm->cmm_md_dev.md_lu_dev;
+ struct obd_type *type;
+ int rc;
+ ENTRY;
+
+ type = ld->ld_type->ldt_obd_type;
+
+ LASSERT(name != NULL);
+ LASSERT(type != NULL);
+
+ /* Find the type procroot and add the proc entry for this device. */
+ cmm->cmm_proc_entry = lprocfs_register(name, type->typ_procroot,
+ NULL, NULL);
+ if (IS_ERR(cmm->cmm_proc_entry)) {
+ rc = PTR_ERR(cmm->cmm_proc_entry);
+ CERROR("Error %d setting up lprocfs for %s\n",
+ rc, name);
+ cmm->cmm_proc_entry = NULL;
+ GOTO(out, rc);
+ }
+
+ rc = cmm_procfs_init_stats(cmm, LPROC_CMM_LAST);
+ EXIT;
+out:
+ if (rc)
+ cmm_procfs_fini(cmm);
+ return rc;
+}
+
+int cmm_procfs_fini(struct cmm_device *cmm)
+{
+ if (cmm->cmm_stats) {
+ lprocfs_free_stats(cmm->cmm_stats);
+ cmm->cmm_stats = NULL;
+ }
+ if (cmm->cmm_proc_entry) {
+ lprocfs_remove(cmm->cmm_proc_entry);
+ cmm->cmm_proc_entry = NULL;
+ }
+ RETURN(0);
+}
+
+void cmm_lprocfs_time_start(struct cmm_device *cmm,
+ struct timeval *start, int op)
+{
+ do_gettimeofday(start);
+}
+
+void cmm_lprocfs_time_end(struct cmm_device *cmm,
+ struct timeval *start, int op)
+{
+ struct timeval end;
+ long timediff;
+
+ do_gettimeofday(&end);
+ timediff = cfs_timeval_sub(&end, start, NULL);
+
+ if (cmm->cmm_stats)
+ lprocfs_counter_add(cmm->cmm_stats, op, timediff);
+ return;
+}
RETURN(rc);
}
-static int cml_create(const struct lu_env *env,
- struct md_object *mo_p, const char *child_name,
- struct md_object *mo_c, struct md_create_spec *spec,
- struct md_attr *ma)
+static int cml_create(const struct lu_env *env, struct md_object *mo_p,
+ const char *name, struct md_object *mo_c,
+ struct md_create_spec *spec, struct md_attr *ma)
{
int rc;
ENTRY;
* tell client that directory is split and operation should repeat to
* correct MDT.
*/
- rc = cmm_split_check(env, mo_p, child_name);
+ rc = cmm_split_check(env, mo_p, name);
if (rc)
RETURN(rc);
#endif
- rc = mdo_create(env, md_object_next(mo_p), child_name,
- md_object_next(mo_c), spec, ma);
+ rc = mdo_create(env, md_object_next(mo_p), name, md_object_next(mo_c),
+ spec, ma);
RETURN(rc);
}
int cmm_split_check(const struct lu_env *env, struct md_object *mp,
const char *name)
{
+ struct cmm_device *cmm = cmm_obj2dev(md2cmm_obj(mp));
struct md_attr *ma = &cmm_env_info(env)->cmi_ma;
struct cml_object *clo = md2cml_obj(mp);
+ struct timeval start;
int rc;
ENTRY;
- /* not split yet */
+ cmm_lprocfs_time_start(cmm, &start, LPROC_CMM_SPLIT_CHECK);
+
+ /* Not split yet */
if (clo->clo_split == CMM_SPLIT_NONE ||
clo->clo_split == CMM_SPLIT_DENIED)
- RETURN(0);
+ GOTO(out, rc = 0);
- /* Try to get the LMV EA size */
+ /* Try to get the LMV EA */
memset(ma, 0, sizeof(*ma));
+
ma->ma_need = MA_LMV;
+ ma->ma_lmv_size = CMM_MD_SIZE(cmm->cmm_tgt_count + 1);
+ OBD_ALLOC(ma->ma_lmv, ma->ma_lmv_size);
+ if (ma->ma_lmv == NULL)
+ GOTO(out, rc = -ENOMEM);
+
+ /* Get LMV EA, Note: refresh valid here for getting LMV_EA */
rc = mo_attr_get(env, mp, ma);
if (rc)
- RETURN(rc);
+ GOTO(cleanup, rc);
/* No LMV just return */
if (!(ma->ma_valid & MA_LMV)) {
/* update split state if unknown */
if (clo->clo_split == CMM_SPLIT_UNKNOWN)
clo->clo_split = CMM_SPLIT_NONE;
- RETURN(0);
+ GOTO(cleanup, rc = 0);
}
- LASSERT(ma->ma_lmv_size > 0);
- OBD_ALLOC(ma->ma_lmv, ma->ma_lmv_size);
- if (ma->ma_lmv == NULL)
- RETURN(-ENOMEM);
-
- /* Get LMV EA, Note: refresh valid here for getting LMV_EA */
- ma->ma_valid &= ~MA_LMV;
- ma->ma_need = MA_LMV;
- rc = mo_attr_get(env, mp, ma);
- if (rc)
- GOTO(cleanup, rc);
-
/* Skip checking the slave dirs (mea_count is 0) */
if (ma->ma_lmv->mea_count != 0) {
int idx;
EXIT;
cleanup:
OBD_FREE(ma->ma_lmv, ma->ma_lmv_size);
+out:
+ cmm_lprocfs_time_end(cmm, &start, LPROC_CMM_SPLIT_CHECK);
return rc;
}
return rc;
}
-#define CMM_MD_SIZE(stripes) (sizeof(struct lmv_stripe_md) + \
- (stripes) * sizeof(struct lu_fid))
-
int cmm_split_try(const struct lu_env *env, struct md_object *mo)
{
struct cmm_device *cmm = cmm_obj2dev(md2cmm_obj(mo));
struct md_attr *ma = &cmm_env_info(env)->cmi_ma;
int rc = 0, split;
struct lu_buf *buf;
+ struct timeval start;
ENTRY;
+ cmm_lprocfs_time_start(cmm, &start, LPROC_CMM_SPLIT_EXEC);
+
LASSERT(S_ISDIR(lu_object_attr(&mo->mo_lu)));
memset(ma, 0, sizeof(*ma));
/* Step1: Checking whether the dir needs to be split. */
rc = cmm_split_expect(env, mo, ma, &split);
if (rc)
- RETURN(rc);
+ GOTO(out, rc);
if (split != CMM_SPLIT_NEEDED) {
/* No split is needed, caller may proceed with create. */
- RETURN(0);
+ GOTO(out, rc = 0);
}
/* Split should be done now, let's do it. */
rc = cmm_upcall(env, &cmm->cmm_md_dev, MD_NO_TRANS);
if (rc) {
CERROR("Can't disable trans for split, rc %d\n", rc);
- RETURN(rc);
+ GOTO(out, rc);
}
/* Step2: Prepare the md memory */
ma->ma_lmv_size = CMM_MD_SIZE(cmm->cmm_tgt_count + 1);
OBD_ALLOC(ma->ma_lmv, ma->ma_lmv_size);
if (ma->ma_lmv == NULL)
- RETURN(-ENOMEM);
+ GOTO(out, rc = -ENOMEM);
/* Step3: Create slave objects and fill the ma->ma_lmv */
rc = cmm_split_slaves_create(env, mo, ma);
EXIT;
cleanup:
OBD_FREE(ma->ma_lmv, ma->ma_lmv_size);
+out:
+ cmm_lprocfs_time_end(cmm, &start, LPROC_CMM_SPLIT_EXEC);
return rc;
}
int (*moo_close)(const struct lu_env *env, struct md_object *obj,
struct md_attr *ma);
+
int (*moo_capa_get)(const struct lu_env *, struct md_object *,
struct lustre_capa *, int renewal);
};
int rc;
ENTRY;
- mdd_lproc_time_start(mdo2mdd(&pobj->mod_obj), &start,
- LPROC_MDD_INDEX_INSERT);
+ mdd_lprocfs_time_start(mdo2mdd(&pobj->mod_obj), &start,
+ LPROC_MDD_INDEX_INSERT);
if (dt_try_as_dir(env, next)) {
rc = next->do_index_ops->dio_insert(env, next,
__mdd_fid_rec(env, lf),
mdd_write_unlock(env, pobj);
}
}
- mdd_lproc_time_end(mdo2mdd(&pobj->mod_obj), &start,
- LPROC_MDD_INDEX_INSERT);
+ mdd_lprocfs_time_end(mdo2mdd(&pobj->mod_obj), &start,
+ LPROC_MDD_INDEX_INSERT);
RETURN(rc);
}
int rc;
ENTRY;
- mdd_lproc_time_start(mdo2mdd(&pobj->mod_obj), &start,
- LPROC_MDD_INDEX_DELETE);
+ mdd_lprocfs_time_start(mdo2mdd(&pobj->mod_obj), &start,
+ LPROC_MDD_INDEX_DELETE);
if (dt_try_as_dir(env, next)) {
rc = next->do_index_ops->dio_delete(env, next,
} else
rc = -ENOTDIR;
- mdd_lproc_time_end(mdo2mdd(&pobj->mod_obj), &start,
- LPROC_MDD_INDEX_DELETE);
+ mdd_lprocfs_time_end(mdo2mdd(&pobj->mod_obj), &start,
+ LPROC_MDD_INDEX_DELETE);
RETURN(rc);
}
int rc;
ENTRY;
- mdd_lproc_time_start(mdo2mdd(pobj), &start, LPROC_MDD_LOOKUP);
+ mdd_lprocfs_time_start(mdo2mdd(pobj), &start, LPROC_MDD_LOOKUP);
if (mdd_is_dead_obj(mdd_obj))
RETURN(-ESTALE);
} else
rc = -ENOTDIR;
- mdd_lproc_time_end(mdo2mdd(pobj), &start, LPROC_MDD_LOOKUP);
+ mdd_lprocfs_time_end(mdo2mdd(pobj), &start, LPROC_MDD_LOOKUP);
RETURN(rc);
}
struct timeval start;
ENTRY;
- mdd_lproc_time_start(mdd, &start, LPROC_MDD_CREATE);
+ mdd_lprocfs_time_start(mdd, &start, LPROC_MDD_CREATE);
/*
* Two operations have to be performed:
OBD_FREE(lmm, lmm_size);
/* Finish mdd_lov_create() stuff */
mdd_lov_create_finish(env, mdd, rc);
- mdd_lproc_time_end(mdd, &start, LPROC_MDD_CREATE);
+ mdd_lprocfs_time_end(mdd, &start, LPROC_MDD_CREATE);
return rc;
}
int mdd_procfs_init(struct mdd_device *mdd, const char *name);
int mdd_procfs_fini(struct mdd_device *mdd);
-void mdd_lproc_time_start(struct mdd_device *mdd, struct timeval *start,
+void mdd_lprocfs_time_start(struct mdd_device *mdd, struct timeval *start,
+ int op);
+void mdd_lprocfs_time_end(struct mdd_device *mdd, struct timeval *start,
int op);
-void mdd_lproc_time_end(struct mdd_device *mdd, struct timeval *start, int op);
int mdd_get_flags(const struct lu_env *env, struct mdd_object *obj);
LPROC_MDD_LOOKUP,
LPROC_MDD_LAST
};
+
#endif
int rc;
ENTRY;
- mdd_lproc_time_start(mdd, &start, LPROC_MDD_GET_MD);
+ mdd_lprocfs_time_start(mdd, &start, LPROC_MDD_GET_MD);
next = mdd_object_child(obj);
rc = next->do_ops->do_xattr_get(env, next,
mdd_buf_get(env, md, *md_size), name,
*md_size = rc;
}
- mdd_lproc_time_end(mdd, &start, LPROC_MDD_GET_MD);
+ mdd_lprocfs_time_end(mdd, &start, LPROC_MDD_GET_MD);
RETURN(rc);
}
int rc = 0;
ENTRY;
- mdd_lproc_time_start(mdd, &start, LPROC_MDD_SET_MD);
+ mdd_lprocfs_time_start(mdd, &start, LPROC_MDD_SET_MD);
buf = mdd_buf_get(env, lmmp, lmm_size);
mode = mdd_object_type(child);
if (S_ISREG(mode) && lmm_size > 0) {
}
CDEBUG(D_INFO, "Set lov md %p size %d for fid "DFID" rc %d\n",
lmmp, lmm_size, PFID(mdo2fid(child)), rc);
- mdd_lproc_time_end(mdd, &start, LPROC_MDD_SET_MD);
+ mdd_lprocfs_time_end(mdd, &start, LPROC_MDD_SET_MD);
RETURN(rc);
}
!(create_flags & FMODE_WRITE))
RETURN(0);
- mdd_lproc_time_start(mdd, &start, LPROC_MDD_LOV_CREATE);
+ mdd_lprocfs_time_start(mdd, &start, LPROC_MDD_LOV_CREATE);
oti_init(oti, NULL);
rc = mdd_lov_objid_alloc(env, mdd);
if (rc != 0)
mdd_lov_objid_free(env, mdd);
- mdd_lproc_time_end(mdd, &start, LPROC_MDD_LOV_CREATE);
+ mdd_lprocfs_time_end(mdd, &start, LPROC_MDD_LOV_CREATE);
return rc;
}
struct obd_device *obd = mdd2obd_dev(mdd);
struct timeval start;
- mdd_lproc_time_start(mdd, &start, LPROC_MDD_UNLINK_LOG);
+ mdd_lprocfs_time_start(mdd, &start, LPROC_MDD_UNLINK_LOG);
LASSERT(ma->ma_valid & MA_LOV);
if ((ma->ma_cookie_size > 0) &&
ma->ma_cookie, ma->ma_cookie_size) > 0)) {
ma->ma_valid |= MA_COOKIE;
}
- mdd_lproc_time_end(mdd, &start, LPROC_MDD_UNLINK_LOG);
+ mdd_lprocfs_time_end(mdd, &start, LPROC_MDD_UNLINK_LOG);
return 0;
}
/* -*- MODE: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
- * mdd/mdd_handler.c
+ * mdd/mdd_lproc.c
* Lustre Metadata Server (mdd) routines
*
* Copyright (C) 2006 Cluster File Systems, Inc.
lprocfs_counter_init(mdd->mdd_stats, LPROC_MDD_GET_MD,
LPROCFS_CNTR_AVGMINMAX, "get_md", "time");
lprocfs_counter_init(mdd->mdd_stats, LPROC_MDD_LOOKUP,
- LPROCFS_CNTR_AVGMINMAX, "lookup", "lookup");
+ LPROCFS_CNTR_AVGMINMAX, "lookup", "time");
EXIT;
cleanup:
if (rc) {
return rc;
}
-int mdd_procfs_fini(struct mdd_device *mdd)
-{
- if (mdd->mdd_stats) {
- lprocfs_free_stats(mdd->mdd_stats);
- mdd->mdd_stats = NULL;
- }
- if (mdd->mdd_proc_entry) {
- lprocfs_remove(mdd->mdd_proc_entry);
- mdd->mdd_proc_entry = NULL;
- }
- RETURN(0);
-}
-
int mdd_procfs_init(struct mdd_device *mdd, const char *name)
{
struct lu_device *ld = &mdd->mdd_md_dev.md_lu_dev;
return rc;
}
-void mdd_lproc_time_start(struct mdd_device *mdd, struct timeval *start, int op)
+int mdd_procfs_fini(struct mdd_device *mdd)
+{
+ if (mdd->mdd_stats) {
+ lprocfs_free_stats(mdd->mdd_stats);
+ mdd->mdd_stats = NULL;
+ }
+ if (mdd->mdd_proc_entry) {
+ lprocfs_remove(mdd->mdd_proc_entry);
+ mdd->mdd_proc_entry = NULL;
+ }
+ RETURN(0);
+}
+
+void mdd_lprocfs_time_start(struct mdd_device *mdd,
+ struct timeval *start, int op)
{
do_gettimeofday(start);
}
-void mdd_lproc_time_end(struct mdd_device *mdd, struct timeval *start, int op)
+void mdd_lprocfs_time_end(struct mdd_device *mdd,
+ struct timeval *start, int op)
{
struct timeval end;
long timediff;
int created,
struct ldlm_reply *rep)
{
- struct ptlrpc_request *req = mdt_info_req(info);
- struct mdt_export_data *med = &req->rq_export->exp_mdt_data;
- struct mdt_device *mdt = info->mti_mdt;
- struct md_attr *ma = &info->mti_attr;
- struct lu_attr *la = &ma->ma_attr;
- struct mdt_file_data *mfd;
- struct mdt_body *repbody;
- int rc = 0;
- int isreg, isdir, islnk;
- struct list_head *t;
+ struct ptlrpc_request *req = mdt_info_req(info);
+ struct mdt_export_data *med = &req->rq_export->exp_mdt_data;
+ struct mdt_device *mdt = info->mti_mdt;
+ struct md_attr *ma = &info->mti_attr;
+ struct lu_attr *la = &ma->ma_attr;
+ struct mdt_file_data *mfd;
+ struct mdt_body *repbody;
+ int rc = 0;
+ int isreg, isdir, islnk;
+ struct list_head *t;
ENTRY;
LASSERT(ma->ma_valid & MA_INODE);
mfd = mdt_mfd_new();
if (mfd != NULL) {
-
/*
* Keep a reference on this object for this open, and is
* released by mdt_mfd_close().
struct mdt_reint_record *rr = &info->mti_rr;
struct md_attr *ma = &info->mti_attr;
struct mdt_object *o;
- int rc;
+ int rc;
ENTRY;
o = mdt_object_find(info->mti_env, info->mti_mdt, rr->rr_fid2);
* capability check for this kind of request. Security hole?
*/
if (mdt->mdt_opts.mo_mds_capa)
- mdt->mdt_child->md_ops->mdo_init_capa_ctxt(env, next, 0, 0, 0,
- 0);
+ mdt->mdt_child->md_ops->mdo_init_capa_ctxt(env, next, 0, 0,
+ 0, 0);
rc = mdt_object_exists(o);
if (rc > 0) {
rc = mdt_mfd_open(info, NULL, o, flags, 0, rep);
} else if (rc == 0) {
/*
- * FIXME: something wrong here, lookup was positive but there is
- * no object!
+ * XX: Something wrong here, lookup was positive but there is no
+ * object!
*/
CERROR("Cross-ref object doesn't exist!\n");
rc = -EFAULT;
} else {
- /* FIXME: something wrong here, the object is on another MDS! */
+ /* XXX: Something wrong here, the object is on another MDS! */
CERROR("The object isn't on this server! FLD error?\n");
rc = -EFAULT;
}