From feb80fe0c440f7790cc3afa53d048370374a81b1 Mon Sep 17 00:00:00 2001 From: bobijam Date: Tue, 16 Sep 2008 03:16:05 +0000 Subject: [PATCH] Branch HEAD b=16788 i=adilger i=nathan.rutman add per-nid statistics on HEAD. --- lustre/include/lprocfs_status.h | 8 ++ lustre/include/lustre_export.h | 8 +- lustre/ldlm/ldlm_lockd.c | 50 ++++++------ lustre/mdt/mdt_handler.c | 23 +++--- lustre/mgs/lproc_mgs.c | 19 ++--- lustre/mgs/mgs_fs.c | 55 ++++++++++++- lustre/mgs/mgs_handler.c | 11 ++- lustre/mgs/mgs_internal.h | 9 ++- lustre/obdclass/lprocfs_status.c | 163 ++++++++++++++++++++++++++++++--------- lustre/obdfilter/filter.c | 54 ++++++------- 10 files changed, 286 insertions(+), 114 deletions(-) diff --git a/lustre/include/lprocfs_status.h b/lustre/include/lprocfs_status.h index 9696a7b..355ece4 100644 --- a/lustre/include/lprocfs_status.h +++ b/lustre/include/lprocfs_status.h @@ -390,8 +390,11 @@ extern void lprocfs_clear_stats(struct lprocfs_stats *stats); extern void lprocfs_free_stats(struct lprocfs_stats **stats); extern void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats); +extern void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats); extern int lprocfs_alloc_obd_stats(struct obd_device *obddev, unsigned int num_private_stats); +extern int lprocfs_alloc_md_stats(struct obd_device *obddev, + unsigned int num_private_stats); extern void lprocfs_counter_init(struct lprocfs_stats *stats, int index, unsigned conf, const char *name, const char *units); @@ -643,9 +646,14 @@ static inline int lprocfs_register_stats(cfs_proc_dir_entry_t *root, static inline void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats) { return; } +static inline void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats) +{ return; } static inline int lprocfs_alloc_obd_stats(struct obd_device *obddev, unsigned int num_private_stats) { return 0; } +static inline int lprocfs_alloc_md_stats(struct obd_device *obddev, + unsigned int num_private_stats) +{ return 0; } static inline void lprocfs_free_obd_stats(struct obd_device *obddev) { return; } diff --git a/lustre/include/lustre_export.h b/lustre/include/lustre_export.h index 55961d1..4851fbc 100644 --- a/lustre/include/lustre_export.h +++ b/lustre/include/lustre_export.h @@ -96,13 +96,20 @@ struct filter_export_data { struct brw_stats fed_brw_stats; }; +typedef struct nid_stat_uuid { + struct list_head ns_uuid_list; + struct obd_uuid ns_uuid; +} nid_stat_uuid_t; + typedef struct nid_stat { lnet_nid_t nid; struct hlist_node nid_hash; struct list_head nid_list; + struct list_head nid_uuid_list; struct obd_device *nid_obd; struct proc_dir_entry *nid_proc; struct lprocfs_stats *nid_stats; + struct lprocfs_stats *nid_ldlm_stats; struct brw_stats *nid_brw_stats; int nid_exp_ref_count; }nid_stat_t; @@ -121,7 +128,6 @@ struct obd_export { struct obd_import *exp_imp_reverse; /* to make RPCs backwards */ struct nid_stat *exp_nid_stats; struct lprocfs_stats *exp_md_stats; - struct lprocfs_stats *exp_ldlm_stats; struct ptlrpc_connection *exp_connection; __u32 exp_conn_cnt; lustre_hash_t *exp_lock_hash; /* existing lock hash */ diff --git a/lustre/ldlm/ldlm_lockd.c b/lustre/ldlm/ldlm_lockd.c index 870ae23..f2965fc 100644 --- a/lustre/ldlm/ldlm_lockd.c +++ b/lustre/ldlm/ldlm_lockd.c @@ -548,16 +548,16 @@ static int ldlm_cb_interpret(struct ptlrpc_request *req, void *data, int rc) lock = req->rq_async_args.pointer_arg[1]; LASSERT(lock != NULL); if (rc != 0) { - /* If client canceled the lock but the cancel has not + /* If client canceled the lock but the cancel has not * been recieved yet, we need to update lvbo to have the * proper attributes cached. */ if (rc == -EINVAL && arg->type == LDLM_BL_CALLBACK) - ldlm_res_lvbo_update(lock->l_resource, NULL, + ldlm_res_lvbo_update(lock->l_resource, NULL, 0, 1); - rc = ldlm_handle_ast_error(lock, req, rc, + rc = ldlm_handle_ast_error(lock, req, rc, arg->type == LDLM_BL_CALLBACK ? "blocking" : "completion"); - } + } LDLM_LOCK_PUT(lock); @@ -585,7 +585,7 @@ static inline int ldlm_bl_and_cp_ast_fini(struct ptlrpc_request *req, } else { LDLM_LOCK_GET(lock); ptlrpc_set_add_req(arg->set, req); - } + } RETURN(rc); } @@ -672,8 +672,9 @@ int ldlm_server_blocking_ast(struct ldlm_lock *lock, if (AT_OFF) req->rq_timeout = ldlm_get_rq_timeout(); - if (lock->l_export && lock->l_export->exp_ldlm_stats) - lprocfs_counter_incr(lock->l_export->exp_ldlm_stats, + if (lock->l_export && lock->l_export->exp_nid_stats && + lock->l_export->exp_nid_stats->nid_ldlm_stats) + lprocfs_counter_incr(lock->l_export->exp_nid_stats->nid_ldlm_stats, LDLM_BL_CALLBACK - LDLM_FIRST_OPC); rc = ldlm_bl_and_cp_ast_fini(req, arg, lock, instant_cancel); @@ -777,8 +778,9 @@ int ldlm_server_completion_ast(struct ldlm_lock *lock, int flags, void *data) } unlock_res_and_lock(lock); - if (lock->l_export && lock->l_export->exp_ldlm_stats) - lprocfs_counter_incr(lock->l_export->exp_ldlm_stats, + if (lock->l_export && lock->l_export->exp_nid_stats && + lock->l_export->exp_nid_stats->nid_ldlm_stats) + lprocfs_counter_incr(lock->l_export->exp_nid_stats->nid_ldlm_stats, LDLM_CP_CALLBACK - LDLM_FIRST_OPC); rc = ldlm_bl_and_cp_ast_fini(req, arg, lock, instant_cancel); @@ -820,8 +822,9 @@ int ldlm_server_glimpse_ast(struct ldlm_lock *lock, void *data) if (AT_OFF) req->rq_timeout = ldlm_get_rq_timeout(); - if (lock->l_export && lock->l_export->exp_ldlm_stats) - lprocfs_counter_incr(lock->l_export->exp_ldlm_stats, + if (lock->l_export && lock->l_export->exp_nid_stats && + lock->l_export->exp_nid_stats->nid_ldlm_stats) + lprocfs_counter_incr(lock->l_export->exp_nid_stats->nid_ldlm_stats, LDLM_GL_CALLBACK - LDLM_FIRST_OPC); rc = ptlrpc_queue_wait(req); @@ -907,8 +910,9 @@ int ldlm_handle_enqueue0(struct ldlm_namespace *ns, ldlm_svc_get_eopc(dlm_req, req->rq_rqbd->rqbd_service->srv_stats); - if (req->rq_export->exp_ldlm_stats) - lprocfs_counter_incr(req->rq_export->exp_ldlm_stats, + if (req->rq_export && req->rq_export->exp_nid_stats && + req->rq_export->exp_nid_stats->nid_ldlm_stats) + lprocfs_counter_incr(req->rq_export->exp_nid_stats->nid_ldlm_stats, LDLM_ENQUEUE - LDLM_FIRST_OPC); if (unlikely(dlm_req->lock_desc.l_resource.lr_type < LDLM_MIN_TYPE || @@ -994,7 +998,7 @@ int ldlm_handle_enqueue0(struct ldlm_namespace *ns, if (lock->l_export->exp_lock_hash) lustre_hash_add(lock->l_export->exp_lock_hash, - &lock->l_remote_handle, + &lock->l_remote_handle, &lock->l_exp_hash); existing_lock: @@ -1172,8 +1176,9 @@ int ldlm_handle_convert0(struct ptlrpc_request *req, int rc; ENTRY; - if (req->rq_export && req->rq_export->exp_ldlm_stats) - lprocfs_counter_incr(req->rq_export->exp_ldlm_stats, + if (req->rq_export && req->rq_export->exp_nid_stats && + req->rq_export->exp_nid_stats->nid_ldlm_stats) + lprocfs_counter_incr(req->rq_export->exp_nid_stats->nid_ldlm_stats, LDLM_CONVERT - LDLM_FIRST_OPC); rc = req_capsule_server_pack(&req->rq_pill); @@ -1296,8 +1301,9 @@ int ldlm_handle_cancel(struct ptlrpc_request *req) RETURN(-EFAULT); } - if (req->rq_export && req->rq_export->exp_ldlm_stats) - lprocfs_counter_incr(req->rq_export->exp_ldlm_stats, + if (req->rq_export && req->rq_export->exp_nid_stats && + req->rq_export->exp_nid_stats->nid_ldlm_stats) + lprocfs_counter_incr(req->rq_export->exp_nid_stats->nid_ldlm_stats, LDLM_CANCEL - LDLM_FIRST_OPC); rc = req_capsule_server_pack(&req->rq_pill); @@ -1394,7 +1400,7 @@ static void ldlm_handle_cp_callback(struct ptlrpc_request *req, &lock->l_resource->lr_name, sizeof(lock->l_resource->lr_name)) != 0) { unlock_res_and_lock(lock); - if (ldlm_lock_change_resource(ns, lock, + if (ldlm_lock_change_resource(ns, lock, &dlm_req->lock_desc.l_resource.lr_name) != 0) { LDLM_ERROR(lock, "Failed to allocate resource"); LDLM_LOCK_PUT(lock); @@ -2024,8 +2030,8 @@ void ldlm_put_ref(void) EXIT; } -/* - * Export handle<->lock hash operations. +/* + * Export handle<->lock hash operations. */ static unsigned ldlm_export_lock_hash(lustre_hash_t *lh, void *key, unsigned mask) @@ -2248,7 +2254,7 @@ static int ldlm_cleanup(void) #endif ENTRY; - if (!list_empty(ldlm_namespace_list(LDLM_NAMESPACE_SERVER)) || + if (!list_empty(ldlm_namespace_list(LDLM_NAMESPACE_SERVER)) || !list_empty(ldlm_namespace_list(LDLM_NAMESPACE_CLIENT))) { CERROR("ldlm still has namespaces; clean these up first.\n"); ldlm_dump_all_namespaces(LDLM_NAMESPACE_SERVER, D_DLMTRACE); diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index bc457d4..545ec84 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -2081,8 +2081,8 @@ static int mdt_req_handle(struct mdt_thread_info *info, LASSERT(current->journal_info == NULL); /* - * Checking for various OBD_FAIL_$PREF_$OPC_NET codes. _Do_ not try - * to put same checks into handlers like mdt_close(), mdt_reint(), + * Checking for various OBD_FAIL_$PREF_$OPC_NET codes. _Do_ not try + * to put same checks into handlers like mdt_close(), mdt_reint(), * etc., without talking to mdt authors first. Checking same thing * there again is useless and returning 0 error wihtout packing reply * is buggy! Handlers either pack reply or return error. @@ -2712,8 +2712,8 @@ int mdt_intent_lock_replace(struct mdt_thread_info *info, RETURN(ELDLM_LOCK_REPLACED); } - /* - * Fixup the lock to be given to the client. + /* + * Fixup the lock to be given to the client. */ lock_res_and_lock(new_lock); new_lock->l_readers = 0; @@ -2726,7 +2726,7 @@ int mdt_intent_lock_replace(struct mdt_thread_info *info, new_lock->l_flags &= ~LDLM_FL_LOCAL; lustre_hash_add(new_lock->l_export->exp_lock_hash, - &new_lock->l_remote_handle, + &new_lock->l_remote_handle, &new_lock->l_exp_hash); unlock_res_and_lock(new_lock); @@ -2912,7 +2912,7 @@ static int mdt_intent_reint(enum mdt_it_code opcode, lhc->mlh_reg_lh.cookie = 0ull; if (rc == -ENOTCONN || rc == -ENODEV) { - /* + /* * If it is the disconnect error (ENODEV & ENOCONN), the error * will be returned by rq_status, and client at ptlrpc layer * will detect this, then disconnect, reconnect the import @@ -2920,15 +2920,15 @@ static int mdt_intent_reint(enum mdt_it_code opcode, */ RETURN(rc); } else { - /* + /* * For other cases, the error will be returned by intent. * and client will retrieve the result from intent. - */ - /* + */ + /* * FIXME: when open lock is finished, that should be * checked here. */ - RETURN(ELDLM_LOCK_ABORTED); + RETURN(ELDLM_LOCK_ABORTED); } } @@ -4446,6 +4446,9 @@ static int mdt_obd_disconnect(struct obd_export *exp) if (mdt->mdt_namespace != NULL || exp->exp_obd->obd_namespace != NULL) ldlm_cancel_locks_for_export(exp); + /* release nid stat refererence */ + lprocfs_exp_cleanup(exp); + /* complete all outstanding replies */ spin_lock(&exp->exp_lock); while (!list_empty(&exp->exp_outstanding_replies)) { diff --git a/lustre/mgs/lproc_mgs.c b/lustre/mgs/lproc_mgs.c index 1d84a12..d3434bf 100644 --- a/lustre/mgs/lproc_mgs.c +++ b/lustre/mgs/lproc_mgs.c @@ -121,7 +121,7 @@ int lproc_mgs_cleanup(struct obd_device *obd) struct mgs_obd *mgs; if (!obd) - RETURN(-EINVAL); + return -EINVAL; mgs = &obd->u.mgs; if (mgs->mgs_proc_live) { @@ -130,6 +130,7 @@ int lproc_mgs_cleanup(struct obd_device *obd) lprocfs_remove(&mgs->mgs_proc_live); mgs->mgs_proc_live = NULL; } + lprocfs_free_per_client_stats(obd); lprocfs_free_obd_stats(obd); return lprocfs_obd_cleanup(obd); @@ -165,22 +166,22 @@ static void seq_show_srpc_rule(struct seq_file *seq, const char *tgtname, } } -static int mgs_live_seq_show(struct seq_file *seq, void *v) +static int mgs_live_seq_show(struct seq_file *seq, void *v) { struct fs_db *fsdb = seq->private; struct mgs_tgt_srpc_conf *srpc_tgt; int i; - + down(&fsdb->fsdb_sem); seq_printf(seq, "fsname: %s\n", fsdb->fsdb_name); - seq_printf(seq, "flags: %#x gen: %d\n", + seq_printf(seq, "flags: %#x gen: %d\n", fsdb->fsdb_flags, fsdb->fsdb_gen); for (i = 0; i < INDEX_MAP_SIZE * 8; i++) - if (test_bit(i, fsdb->fsdb_mdt_index_map)) + if (test_bit(i, fsdb->fsdb_mdt_index_map)) seq_printf(seq, "%s-MDT%04x\n", fsdb->fsdb_name, i); for (i = 0; i < INDEX_MAP_SIZE * 8; i++) - if (test_bit(i, fsdb->fsdb_ost_index_map)) + if (test_bit(i, fsdb->fsdb_ost_index_map)) seq_printf(seq, "%s-OST%04x\n", fsdb->fsdb_name, i); seq_printf(seq, "\nSecure RPC Config Rules:\n"); @@ -206,9 +207,9 @@ int lproc_mgs_add_live(struct obd_device *obd, struct fs_db *fsdb) struct mgs_obd *mgs = &obd->u.mgs; int rc; - if (!mgs->mgs_proc_live) + if (!mgs->mgs_proc_live) return 0; - rc = lprocfs_seq_create(mgs->mgs_proc_live, fsdb->fsdb_name, 0444, + rc = lprocfs_seq_create(mgs->mgs_proc_live, fsdb->fsdb_name, 0444, &mgs_live_fops, fsdb); return 0; @@ -218,7 +219,7 @@ int lproc_mgs_del_live(struct obd_device *obd, struct fs_db *fsdb) { struct mgs_obd *mgs = &obd->u.mgs; - if (!mgs->mgs_proc_live) + if (!mgs->mgs_proc_live) return 0; lprocfs_remove_proc_entry(fsdb->fsdb_name, mgs->mgs_proc_live); diff --git a/lustre/mgs/mgs_fs.c b/lustre/mgs/mgs_fs.c index 78b6675..4b87e84 100644 --- a/lustre/mgs/mgs_fs.c +++ b/lustre/mgs/mgs_fs.c @@ -58,6 +58,55 @@ #include #include "mgs_internal.h" +static int mgs_export_stats_init(struct obd_device *obd, struct obd_export *exp, + void *localdata) +{ + lnet_nid_t *client_nid = localdata; + int rc, newnid; + + rc = lprocfs_exp_setup(exp, client_nid, &newnid); + if (rc) { + /* Mask error for already created + * /proc entries */ + if (rc == -EALREADY) + rc = 0; + return rc; + } + + if (!obd->md_stats && + lprocfs_alloc_md_stats(obd, LPROC_MGS_LAST)) + return rc; + if (newnid) { + /* Always add in ldlm_stats */ + exp->exp_nid_stats->nid_ldlm_stats = + lprocfs_alloc_stats(LDLM_LAST_OPC - LDLM_FIRST_OPC, 0); + if (exp->exp_nid_stats->nid_ldlm_stats == NULL) + return -ENOMEM; + lprocfs_init_ldlm_stats(exp->exp_nid_stats->nid_ldlm_stats); + rc = lprocfs_register_stats(exp->exp_nid_stats->nid_proc, + "ldlm_stats", + exp->exp_nid_stats->nid_ldlm_stats); + } + return rc; +} + +/** + * Add client export data to the MGS. This data is currently NOT stored on + * disk in the last_rcvd file or anywhere else. In the event of a MGS + * crash all connections are treated as new connections. + */ +int mgs_client_add(struct obd_device *obd, struct obd_export *exp, + void *localdata) +{ + return mgs_export_stats_init(obd, exp, localdata); +} + +/* Remove client export data from the MGS */ +int mgs_client_free(struct obd_export *exp) +{ + return 0; +} + /* Same as mds_fid2dentry */ /* Look up an entry by inode number. */ /* this function ONLY returns valid dget'd dentries with an initialized inode @@ -75,9 +124,9 @@ static struct dentry *mgs_fid2dentry(struct mgs_obd *mgs, if (ino == 0) RETURN(ERR_PTR(-ESTALE)); - + snprintf(fid_name, sizeof(fid_name), "0x%lx", (unsigned long)ino); - + /* under ext3 this is neither supposed to return bad inodes nor NULL inodes. */ result = ll_lookup_one_len(fid_name, mgs->mgs_fid_de, strlen(fid_name)); @@ -152,7 +201,7 @@ int mgs_fs_setup(struct obd_device *obd, struct vfsmount *mnt) dentry = simple_mkdir(current->fs->pwd, mnt, MOUNT_CONFIGS_DIR, 0777, 1); if (IS_ERR(dentry)) { rc = PTR_ERR(dentry); - CERROR("cannot create %s directory: rc = %d\n", + CERROR("cannot create %s directory: rc = %d\n", MOUNT_CONFIGS_DIR, rc); GOTO(err_pop, rc); } diff --git a/lustre/mgs/mgs_handler.c b/lustre/mgs/mgs_handler.c index 1bd26d6..40e1275 100644 --- a/lustre/mgs/mgs_handler.c +++ b/lustre/mgs/mgs_handler.c @@ -90,6 +90,8 @@ static int mgs_connect(const struct lu_env *env, data->ocd_version = LUSTRE_VERSION_CODE; } + rc = mgs_client_add(obd, exp, localdata); + if (rc) { class_disconnect(exp); } else { @@ -108,6 +110,8 @@ static int mgs_reconnect(const struct lu_env *env, if (exp == NULL || obd == NULL || cluuid == NULL) RETURN(-EINVAL); + mgs_counter_incr(exp, LPROC_MGS_CONNECT); + if (data != NULL) { data->ocd_connect_flags &= MGS_CONNECT_SUPPORTED; exp->exp_connect_flags = data->ocd_connect_flags; @@ -463,7 +467,7 @@ static int mgs_handle_target_reg(struct ptlrpc_request *req) } mti->mti_flags |= LDD_F_UPDATE; /* Erased logs means start from scratch. */ - mti->mti_flags &= ~LDD_F_UPGRADE14; + mti->mti_flags &= ~LDD_F_UPGRADE14; } /* COMPAT_146 */ @@ -473,7 +477,7 @@ static int mgs_handle_target_reg(struct ptlrpc_request *req) CERROR("Can't upgrade from 1.4 (%d)\n", rc); GOTO(out, rc); } - + /* We're good to go */ mti->mti_flags |= LDD_F_UPDATE; } @@ -709,6 +713,7 @@ static inline int mgs_destroy_export(struct obd_export *exp) ENTRY; target_destroy_export(exp); + mgs_client_free(exp); ldlm_destroy_export(exp); RETURN(0); @@ -732,7 +737,7 @@ static int mgs_extract_fs_pool(char * arg, char *fsname, char *poolname) RETURN(0); } -static int mgs_iocontrol_pool(struct obd_device *obd, +static int mgs_iocontrol_pool(struct obd_device *obd, struct obd_ioctl_data *data) { int rc; diff --git a/lustre/mgs/mgs_internal.h b/lustre/mgs/mgs_internal.h index d5d18bd..99e698f 100644 --- a/lustre/mgs/mgs_internal.h +++ b/lustre/mgs/mgs_internal.h @@ -49,9 +49,9 @@ /* mgs_llog.c */ int class_dentry_readdir(struct obd_device *obd, struct dentry *dir, - struct vfsmount *inmnt, + struct vfsmount *inmnt, struct list_head *dentry_list); - + struct mgs_tgt_srpc_conf { struct mgs_tgt_srpc_conf *mtsc_next; char *mtsc_tgt; @@ -99,6 +99,9 @@ int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd, char *poolname, char *fsname, char *ostname); /* mgs_fs.c */ +int mgs_client_add(struct obd_device *obd, struct obd_export *exp, + void *localdata); +int mgs_client_free(struct obd_export *exp); int mgs_fs_setup(struct obd_device *obd, struct vfsmount *mnt); int mgs_fs_cleanup(struct obd_device *obddev); @@ -110,7 +113,7 @@ int lproc_mgs_add_live(struct obd_device *obd, struct fs_db *fsdb); int lproc_mgs_del_live(struct obd_device *obd, struct fs_db *fsdb); void lprocfs_mgs_init_vars(struct lprocfs_static_vars *lvars); #else -static inline int lproc_mgs_setup(struct obd_device *dev) +static inline int lproc_mgs_setup(struct obd_device *dev) {return 0;} static inline int lproc_mgs_cleanup(struct obd_device *obd) {return 0;} diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 79eb987..82366e4 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -838,6 +838,9 @@ static void lprocfs_free_client_stats(struct nid_stat *client_stat) if (client_stat->nid_brw_stats) OBD_FREE(client_stat->nid_brw_stats, sizeof(struct brw_stats)); + if (client_stat->nid_ldlm_stats) + lprocfs_free_stats(&client_stat->nid_ldlm_stats); + OBD_FREE(client_stat, sizeof(*client_stat)); return; @@ -1284,7 +1287,7 @@ int lprocfs_alloc_md_stats(struct obd_device *obd, LASSERT(obd->obd_proc_entry != NULL); LASSERT(obd->md_cntr_base == 0); - num_stats = 1 + MD_COUNTER_OFFSET(get_remote_perm) + + num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) + num_private_stats; stats = lprocfs_alloc_stats(num_stats, 0); if (stats == NULL) @@ -1349,6 +1352,28 @@ void lprocfs_free_md_stats(struct obd_device *obd) } } +void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats) +{ + lprocfs_counter_init(ldlm_stats, + LDLM_ENQUEUE - LDLM_FIRST_OPC, + 0, "ldlm_enqueue", "reqs"); + lprocfs_counter_init(ldlm_stats, + LDLM_CONVERT - LDLM_FIRST_OPC, + 0, "ldlm_convert", "reqs"); + lprocfs_counter_init(ldlm_stats, + LDLM_CANCEL - LDLM_FIRST_OPC, + 0, "ldlm_cancel", "reqs"); + lprocfs_counter_init(ldlm_stats, + LDLM_BL_CALLBACK - LDLM_FIRST_OPC, + 0, "ldlm_bl_callback", "reqs"); + lprocfs_counter_init(ldlm_stats, + LDLM_CP_CALLBACK - LDLM_FIRST_OPC, + 0, "ldlm_cp_callback", "reqs"); + lprocfs_counter_init(ldlm_stats, + LDLM_GL_CALLBACK - LDLM_FIRST_OPC, + 0, "ldlm_gl_callback", "reqs"); +} + int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -1450,17 +1475,16 @@ void lprocfs_nid_stats_clear_write_cb(void *obj, void *data) { struct nid_stat *stat = obj; int i; - + ENTRY; /* object has only hash + iterate_all references. * add/delete blocked by hash bucket lock */ CDEBUG(D_INFO,"refcnt %d\n", stat->nid_exp_ref_count); - if(stat->nid_exp_ref_count == 2) { + if (stat->nid_exp_ref_count == 2) { hlist_del_init(&stat->nid_hash); stat->nid_exp_ref_count--; spin_lock(&stat->nid_obd->obd_nid_lock); - list_del_init(&stat->nid_list); + list_move(&stat->nid_list, data); spin_unlock(&stat->nid_obd->obd_nid_lock); - list_add(&stat->nid_list, data); EXIT; return; } @@ -1498,10 +1522,11 @@ EXPORT_SYMBOL(lprocfs_nid_stats_clear_write); int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid) { - int rc = 0; - struct nid_stat *tmp = NULL, *tmp1; + struct nid_stat *new_stat, *old_stat; + struct nid_stat_uuid *new_ns_uuid; struct obd_device *obd = NULL; cfs_proc_dir_entry_t *entry; + int rc = 0; ENTRY; *newnid = 0; @@ -1511,8 +1536,8 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid) RETURN(-EINVAL); /* not test against zero because eric say: - * You may only test nid against another nid, or LNET_NID_ANY. Anything else is - * nonsense.*/ + * You may only test nid against another nid, or LNET_NID_ANY. + * Anything else is nonsense.*/ if (!nid || *nid == LNET_NID_ANY) RETURN(0); @@ -1520,75 +1545,139 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid) CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash); - OBD_ALLOC(tmp, sizeof(struct nid_stat)); - if (tmp == NULL) + OBD_ALLOC(new_stat, sizeof(struct nid_stat)); + if (new_stat == NULL) + RETURN(-ENOMEM); + + OBD_ALLOC(new_ns_uuid, sizeof(struct nid_stat_uuid)); + if (new_ns_uuid == NULL) { + OBD_FREE(new_stat, sizeof(struct nid_stat)); RETURN(-ENOMEM); + } + CFS_INIT_LIST_HEAD(&new_ns_uuid->ns_uuid_list); + strncpy(new_ns_uuid->ns_uuid.uuid, exp->exp_client_uuid.uuid, + sizeof(struct obd_uuid)); - tmp->nid = *nid; - tmp->nid_obd = exp->exp_obd; - tmp->nid_exp_ref_count = 1; /* need live in hash after destroy export */ + CFS_INIT_LIST_HEAD(&new_stat->nid_uuid_list); + new_stat->nid = *nid; + new_stat->nid_obd = exp->exp_obd; + new_stat->nid_exp_ref_count = 1; /* live in hash after destroy export */ /* protect competitive add to list, not need locking on destroy */ spin_lock(&obd->obd_nid_lock); - list_add(&tmp->nid_list, &obd->obd_nid_stats); + list_add(&new_stat->nid_list, &obd->obd_nid_stats); spin_unlock(&obd->obd_nid_lock); - tmp1 = lustre_hash_findadd_unique(obd->obd_nid_stats_hash, - nid, &tmp->nid_hash); + old_stat = lustre_hash_findadd_unique(obd->obd_nid_stats_hash, + nid, &new_stat->nid_hash); CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n", - tmp1, libcfs_nid2str(*nid), tmp->nid_exp_ref_count); + old_stat, libcfs_nid2str(*nid), new_stat->nid_exp_ref_count); + + /* Return -EALREADY here so that we know that the /proc + * entry already has been created */ + if (old_stat != new_stat) { + struct nid_stat_uuid *tmp_uuid; + int found = 0; + + exp->exp_nid_stats = old_stat; + /* We need to decrement the refcount if the uuid was + * already in our list */ + spin_lock(&obd->obd_nid_lock); + list_for_each_entry(tmp_uuid, &old_stat->nid_uuid_list, + ns_uuid_list) { + if (tmp_uuid && obd_uuid_equals(&tmp_uuid->ns_uuid, + &exp->exp_client_uuid)){ + found = 1; + --old_stat->nid_exp_ref_count; + break; + } + } + + if (!found) + list_add(&new_ns_uuid->ns_uuid_list, + &old_stat->nid_uuid_list); + else + OBD_FREE(new_ns_uuid, sizeof(struct nid_stat)); - if (tmp1 != tmp) { - exp->exp_nid_stats = tmp1; - GOTO(destroy_new, rc = 0); + spin_unlock(&obd->obd_nid_lock); + + GOTO(destroy_new, rc = -EALREADY); } /* not found - create */ - tmp->nid_proc = lprocfs_register(libcfs_nid2str(*nid), - obd->obd_proc_exports_entry, NULL, NULL); - if (!tmp->nid_proc) { - CERROR("Error making export directory for" - " nid %s\n", libcfs_nid2str(*nid)); - lustre_hash_del(obd->obd_nid_stats_hash, nid, &tmp->nid_hash); + new_stat->nid_proc = lprocfs_register(libcfs_nid2str(*nid), + obd->obd_proc_exports_entry, + NULL, NULL); + if (new_stat->nid_proc == NULL) { + CERROR("Error making export directory for nid %s\n", + libcfs_nid2str(*nid)); + lustre_hash_del(obd->obd_nid_stats_hash, nid, + &new_stat->nid_hash); GOTO(destroy_new, rc = -ENOMEM); } - entry = lprocfs_add_simple(tmp->nid_proc, "uuid", - lprocfs_exp_rd_uuid, NULL, tmp, NULL); + /* Add in uuid to our nid_stats list */ + spin_lock(&obd->obd_nid_lock); + list_add(&new_ns_uuid->ns_uuid_list, &new_stat->nid_uuid_list); + spin_unlock(&obd->obd_nid_lock); + + entry = lprocfs_add_simple(new_stat->nid_proc, "uuid", + lprocfs_exp_rd_uuid, NULL, new_stat, NULL); if (IS_ERR(entry)) { - CWARN("Error adding the uuid file\n"); + CWARN("Error adding the NID stats file\n"); rc = PTR_ERR(entry); } - entry = lprocfs_add_simple(tmp->nid_proc, "hash", - lprocfs_exp_rd_hash, NULL, tmp, NULL); + entry = lprocfs_add_simple(new_stat->nid_proc, "hash", + lprocfs_exp_rd_hash, NULL, new_stat, NULL); if (IS_ERR(entry)) { CWARN("Error adding the hash file\n"); rc = PTR_ERR(entry); } - exp->exp_nid_stats = tmp; + exp->exp_nid_stats = new_stat; *newnid = 1; RETURN(rc); destroy_new: spin_lock(&obd->obd_nid_lock); - list_del(&tmp->nid_list); + list_del(&new_stat->nid_list); spin_unlock(&obd->obd_nid_lock); - OBD_FREE(tmp, sizeof(struct nid_stat)); + OBD_FREE(new_stat, sizeof(struct nid_stat)); RETURN(rc); } int lprocfs_exp_cleanup(struct obd_export *exp) { struct nid_stat *stat = exp->exp_nid_stats; + struct nid_stat_uuid *cursor, *tmp; + int found = 0; - if(!stat) + if(!stat || !exp->exp_obd) RETURN(0); + spin_lock(&exp->exp_obd->obd_nid_lock); + list_for_each_entry_safe(cursor, tmp, + &stat->nid_uuid_list, + ns_uuid_list) { + if (cursor && obd_uuid_equals(&cursor->ns_uuid, + &exp->exp_client_uuid)) { + found = 1; + list_del(&cursor->ns_uuid_list); + OBD_FREE(cursor, sizeof(struct nid_stat_uuid)); + break; + } + } + spin_unlock(&exp->exp_obd->obd_nid_lock); + if (!found) + CERROR("obd_export's client uuid %s are not found in its " + "nid_stats list\n", exp->exp_client_uuid.uuid); + stat->nid_exp_ref_count--; CDEBUG(D_INFO, "Put stat %p - %d\n", stat, stat->nid_exp_ref_count); exp->exp_nid_stats = NULL; + lprocfs_free_md_stats(exp->exp_obd); + return 0; } @@ -1986,7 +2075,9 @@ EXPORT_SYMBOL(lprocfs_free_stats); EXPORT_SYMBOL(lprocfs_clear_stats); EXPORT_SYMBOL(lprocfs_register_stats); EXPORT_SYMBOL(lprocfs_init_ops_stats); +EXPORT_SYMBOL(lprocfs_init_ldlm_stats); EXPORT_SYMBOL(lprocfs_alloc_obd_stats); +EXPORT_SYMBOL(lprocfs_alloc_md_stats); EXPORT_SYMBOL(lprocfs_free_obd_stats); EXPORT_SYMBOL(lprocfs_exp_setup); EXPORT_SYMBOL(lprocfs_exp_cleanup); diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index 3c7c88f..34518f3 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -135,7 +135,7 @@ int filter_finish_transno(struct obd_export *exp, struct obd_trans_info *oti, err = -EINVAL; } else { if (!force_sync) - force_sync = fsfilt_add_journal_cb(exp->exp_obd, + force_sync = fsfilt_add_journal_cb(exp->exp_obd, last_rcvd, oti->oti_handle, filter_commit_cb, @@ -255,7 +255,7 @@ static int filter_client_add(struct obd_device *obd, struct obd_export *exp, struct filter_export_data *fed = &exp->exp_filter_data; unsigned long *bitmap = filter->fo_last_rcvd_slots; int new_client = (cl_idx == -1); - + ENTRY; LASSERT(bitmap != NULL); @@ -987,7 +987,7 @@ static int filter_read_group_internal(struct obd_device *obd, int group, RETURN(PTR_ERR(dentry)); } } else { - dentry = simple_mkdir(filter->fo_dentry_O, filter->fo_vfsmnt, + dentry = simple_mkdir(filter->fo_dentry_O, filter->fo_vfsmnt, name, 0700, 1); if (IS_ERR(dentry)) { CERROR("cannot lookup/create O/%s: rc = %ld\n", name, @@ -1022,7 +1022,7 @@ static int filter_read_group_internal(struct obd_device *obd, int group, char dir[20]; snprintf(dir, sizeof(dir), "d%u", i); - tmp_subdirs->dentry[i] = simple_mkdir(dentry, + tmp_subdirs->dentry[i] = simple_mkdir(dentry, filter->fo_vfsmnt, dir, 0700, 1); if (IS_ERR(tmp_subdirs->dentry[i])) { @@ -1150,7 +1150,7 @@ static int filter_prep_groups(struct obd_device *obd) loff_t off = 0; ENTRY; - O_dentry = simple_mkdir(current->fs->pwd, filter->fo_vfsmnt, + O_dentry = simple_mkdir(current->fs->pwd, filter->fo_vfsmnt, "O", 0700, 1); CDEBUG(D_INODE, "got/created O: %p\n", O_dentry); if (IS_ERR(O_dentry)) { @@ -1764,7 +1764,7 @@ static int filter_intent_policy(struct ldlm_namespace *ns, if (tree->lit_mode == LCK_PR) continue; - interval_iterate_reverse(tree->lit_root, + interval_iterate_reverse(tree->lit_root, filter_intent_cb, &arg); } unlock_res(res); @@ -2195,7 +2195,7 @@ static int filter_olg_fini(struct obd_llog_group *olg) RETURN(rc); } -static int +static int filter_olg_init(struct obd_device *obd, struct obd_llog_group *olg, struct obd_device *tgt) { @@ -2221,7 +2221,7 @@ cleanup: /** * Init the default olg, which is embeded in the obd_device, for filter. */ -static int +static int filter_default_olg_init(struct obd_device *obd, struct obd_llog_group *olg, struct obd_device *tgt) { @@ -2245,7 +2245,7 @@ filter_default_olg_init(struct obd_device *obd, struct obd_llog_group *olg, ctxt = llog_group_get_ctxt(olg, LLOG_MDS_OST_REPL_CTXT); if (!ctxt) { - CERROR("Can't get ctxt for %p:%x\n", olg, + CERROR("Can't get ctxt for %p:%x\n", olg, LLOG_MDS_OST_REPL_CTXT); GOTO(cleanup_olg, rc = -ENODEV); } @@ -2261,8 +2261,8 @@ cleanup_lcm: filter->fo_lcm = NULL; return rc; } - -static int + +static int filter_llog_init(struct obd_device *obd, struct obd_llog_group *olg, struct obd_device *tgt, int count, struct llog_catid *catid, struct obd_uuid *uuid) @@ -2282,7 +2282,7 @@ filter_llog_init(struct obd_device *obd, struct obd_llog_group *olg, RETURN(rc); ctxt = llog_group_get_ctxt(olg, LLOG_MDS_OST_REPL_CTXT); if (!ctxt) { - CERROR("Can't get ctxt for %p:%x\n", olg, + CERROR("Can't get ctxt for %p:%x\n", olg, LLOG_MDS_OST_REPL_CTXT); filter_olg_fini(olg); RETURN(-ENODEV); @@ -2298,7 +2298,7 @@ static int filter_llog_finish(struct obd_device *obd, int count) struct filter_obd *filter = &obd->u.filter; struct llog_ctxt *ctxt; ENTRY; - + ctxt = llog_group_get_ctxt(&obd->obd_olg, LLOG_MDS_OST_REPL_CTXT); LASSERT(ctxt != NULL); mutex_down(&ctxt->loc_sem); @@ -2354,11 +2354,11 @@ struct obd_llog_group *filter_find_olg(struct obd_device *obd, int group) olg = filter_find_olg_internal(filter, group); spin_unlock(&filter->fo_llog_list_lock); - RETURN(olg); + RETURN(olg); } /** * Find the llog_group of the filter according to the group. If it can not - * find, create the llog_group, which only happens when mds is being synced + * find, create the llog_group, which only happens when mds is being synced * with OST. */ struct obd_llog_group *filter_find_create_olg(struct obd_device *obd, int group) @@ -2428,7 +2428,7 @@ static int filter_llog_connect(struct obd_export *exp, olg = filter_find_olg(obd, body->lgdc_logid.lgl_ogr); if (!olg) { CERROR(" %s: can not find olg of group %d\n", - obd->obd_name, (int)body->lgdc_logid.lgl_ogr); + obd->obd_name, (int)body->lgdc_logid.lgl_ogr); RETURN(-ENOENT); } llog_group_set_export(olg, exp); @@ -2469,8 +2469,8 @@ static int filter_llog_preclean(struct obd_device *obd) list_add(&olg->olg_list, &remove_list); } spin_unlock(&filter->fo_llog_list_lock); - - list_for_each_entry_safe(olg, tmp, &remove_list, olg_list) { + + list_for_each_entry_safe(olg, tmp, &remove_list, olg_list) { list_del_init(&olg->olg_list); rc = filter_olg_fini(olg); if (rc) @@ -2943,7 +2943,7 @@ static void filter_sync_llogs(struct obd_device *obd, struct obd_export *dexp) llog_ctxt_put(ctxt); if (err) CERROR("error flushing logs to MDS: rc %d\n", - err); + err); } } while (olg_min != NULL); } @@ -3259,7 +3259,7 @@ int filter_setattr(struct obd_export *exp, struct obd_info *oinfo, /* This would be very bad - accidentally truncating a file when * changing the time or similar - bug 12203. */ - if (oinfo->oi_oa->o_valid & OBD_MD_FLSIZE && + if (oinfo->oi_oa->o_valid & OBD_MD_FLSIZE && oinfo->oi_policy.l_extent.end != OBD_OBJECT_EOF) { static char mdsinum[48]; @@ -3407,7 +3407,7 @@ static int filter_destroy_precreated(struct obd_export *exp, struct obdo *oa, CWARN("%s: deleting orphan objects from "LPU64" to "LPU64"\n", exp->exp_obd->obd_name, oa->o_id + 1, last); - + for (id = last; id > oa->o_id; id--) { doa.o_id = id; rc = filter_destroy(exp, &doa, NULL, NULL, NULL); @@ -3634,7 +3634,7 @@ static int filter_precreate(struct obd_device *obd, struct obdo *oa, rc = -EAGAIN; break; } - + if (recreate_obj) { __u64 last_id; next_id = oa->o_id; @@ -3947,13 +3947,13 @@ cleanup: filter_cancel_cookies_cb, fcc); /* If add_journal_cb failed, then filter_finish_transno - * will commit the handle and we will do a sync - * on commit. then we call callback directly to free - * the fcc. + * will commit the handle and we will do a sync + * on commit. then we call callback directly to free + * the fcc. */ rc = filter_finish_transno(exp, oti, rc, sync); if (sync) { - filter_cancel_cookies_cb(obd, 0, fcc, rc); + filter_cancel_cookies_cb(obd, 0, fcc, rc); fcc = NULL; } rc2 = fsfilt_commit(obd, dparent->d_inode, handle, 0); @@ -4202,7 +4202,7 @@ static int filter_set_info_async(struct obd_export *exp, __u32 keylen, RETURN(PTR_ERR(olg)); llog_group_set_export(olg, exp); - + ctxt = llog_group_get_ctxt(olg, LLOG_MDS_OST_REPL_CTXT); LASSERTF(ctxt != NULL, "ctxt is null\n"), -- 1.8.3.1