From: yangsheng Date: Mon, 1 Mar 2010 13:24:33 +0000 (+0800) Subject: b=21815 Avoid operating lustre-hash internal structures directly. X-Git-Tag: v1_8_2_52~33 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=26898ade04ff92a52b9f8831860bce1977a93c65;p=fs%2Flustre-release.git b=21815 Avoid operating lustre-hash internal structures directly. i=johann i=nathan --- diff --git a/lustre/include/class_hash.h b/lustre/include/class_hash.h index 9d43ac4..06cb691 100644 --- a/lustre/include/class_hash.h +++ b/lustre/include/class_hash.h @@ -252,6 +252,8 @@ void *lustre_hash_findadd_unique(lustre_hash_t *lh, void *key, /* Hash deletion functions */ void *lustre_hash_del(lustre_hash_t *lh, void *key, struct hlist_node *hnode); void *lustre_hash_del_key(lustre_hash_t *lh, void *key); +typedef int (*lh_cond_opt_cb)(void *obj, void *data); +void lustre_hash_cond_del(lustre_hash_t *lh, lh_cond_opt_cb, void *data); /* Hash lookup/for_each functions */ void *lustre_hash_lookup(lustre_hash_t *lh, void *key); diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index c50c71f..fcd7070 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -306,6 +306,26 @@ do { \ #define EXP_COUNTER_INCREMENT(exp, op); #endif +static inline int lprocfs_nid_ldlm_stats_init(struct nid_stat* tmp) { + int rc; + + rc = lprocfs_register_stats(tmp->nid_proc, "stats", + tmp->nid_stats); + if (rc) + return rc; + + /* Always add in ldlm_stats */ + tmp->nid_ldlm_stats = lprocfs_alloc_stats(LDLM_LAST_OPC - LDLM_FIRST_OPC + ,LPROCFS_STATS_FLAG_NOPERCPU); + if (tmp->nid_ldlm_stats == NULL) + return -ENOMEM; + + lprocfs_init_ldlm_stats(tmp->nid_ldlm_stats); + + return lprocfs_register_stats(tmp->nid_proc, "ldlm_stats", + tmp->nid_ldlm_stats); +} + #define OBD_CHECK_OP(obd, op, err) \ do { \ if (!OBT(obd) || !OBP((obd), op)) {\ diff --git a/lustre/mds/mds_fs.c b/lustre/mds/mds_fs.c index d551891..5374670 100644 --- a/lustre/mds/mds_fs.c +++ b/lustre/mds/mds_fs.c @@ -91,24 +91,9 @@ int mds_export_stats_init(struct obd_device *obd, return -ENOMEM; lprocfs_init_ops_stats(LPROC_MDS_LAST, tmp->nid_stats); - rc = lprocfs_register_stats(tmp->nid_proc, "stats", - tmp->nid_stats); - if (rc) - return rc; - mds_stats_counter_init(tmp->nid_stats); - /* Always add in ldlm_stats */ - tmp->nid_ldlm_stats = - lprocfs_alloc_stats(LDLM_LAST_OPC - LDLM_FIRST_OPC, - LPROCFS_STATS_FLAG_NOPERCPU); - if (tmp->nid_ldlm_stats == NULL) - return -ENOMEM; - - lprocfs_init_ldlm_stats(tmp->nid_ldlm_stats); - - rc = lprocfs_register_stats(tmp->nid_proc, "ldlm_stats", - tmp->nid_ldlm_stats); + rc = lprocfs_nid_ldlm_stats_init(tmp); if (rc) return rc; } diff --git a/lustre/mgs/mgs_fs.c b/lustre/mgs/mgs_fs.c index 7ee3eb1..e3b7981 100644 --- a/lustre/mgs/mgs_fs.c +++ b/lustre/mgs/mgs_fs.c @@ -88,22 +88,8 @@ int mgs_export_stats_init(struct obd_device *obd, lprocfs_init_ops_stats(LPROC_MGS_LAST, tmp->nid_stats); mgs_stats_counter_init(tmp->nid_stats); - rc = lprocfs_register_stats(tmp->nid_proc, "stats", - tmp->nid_stats); - if (rc) - return rc; - - /* Always add in ldlm_stats */ - tmp->nid_ldlm_stats = - lprocfs_alloc_stats(LDLM_LAST_OPC - LDLM_FIRST_OPC, - LPROCFS_STATS_FLAG_NOPERCPU); - if (tmp->nid_ldlm_stats == NULL) - return -ENOMEM; - - lprocfs_init_ldlm_stats(tmp->nid_ldlm_stats); - rc = lprocfs_register_stats(tmp->nid_proc, "ldlm_stats", - tmp->nid_ldlm_stats); + rc = lprocfs_nid_ldlm_stats_init(tmp); if (rc) return rc; } diff --git a/lustre/obdclass/class_hash.c b/lustre/obdclass/class_hash.c index 13bf2d6..68aca4f 100644 --- a/lustre/obdclass/class_hash.c +++ b/lustre/obdclass/class_hash.c @@ -362,6 +362,42 @@ lustre_hash_del(lustre_hash_t *lh, void *key, struct hlist_node *hnode) EXPORT_SYMBOL(lustre_hash_del); /** + * Delete item from the lustre hash @lh when @func return true. + * The write lock being hold during loop for each bucket to avoid + * any object be reference. + */ +void +lustre_hash_cond_del(lustre_hash_t *lh, lh_cond_opt_cb func, void *data) +{ + lustre_hash_bucket_t *lhb; + struct hlist_node *hnode; + struct hlist_node *pos; + int i; + ENTRY; + + LASSERT(lh != NULL); + + lh_write_lock(lh); + lh_for_each_bucket(lh, lhb, i) { + if (lhb == NULL) + continue; + + write_lock(&lhb->lhb_rwlock); + hlist_for_each_safe(hnode, pos, &(lhb->lhb_head)) { + __lustre_hash_bucket_validate(lh, lhb, hnode); + if (func(lh_get(lh, hnode), data)) + __lustre_hash_bucket_del(lh, lhb, hnode); + (void)lh_put(lh, hnode); + } + write_unlock(&lhb->lhb_rwlock); + } + lh_write_unlock(lh); + + EXIT; +} +EXPORT_SYMBOL(lustre_hash_cond_del); + +/** * Delete item given @key in lustre hash @lh. The first @key found in * the hash will be removed, if the key exists multiple times in the hash * @lh this function must be called once per key. The removed object diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 36cb078..03ad827 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -1589,7 +1589,7 @@ int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off, } EXPORT_SYMBOL(lprocfs_nid_stats_clear_read); -void lprocfs_nid_stats_clear_write_cb(void *obj, void *data) +int lprocfs_nid_stats_clear_write_cb(void *obj, void *data) { struct nid_stat *stat = obj; int i; @@ -1598,13 +1598,10 @@ void lprocfs_nid_stats_clear_write_cb(void *obj, void *data) * add/delete blocked by hash bucket lock */ CDEBUG(D_INFO,"refcnt %d\n", atomic_read(&stat->nid_exp_ref_count)); if (atomic_read(&stat->nid_exp_ref_count) == 2) { - hlist_del_init(&stat->nid_hash); - nidstat_putref(stat); spin_lock(&stat->nid_obd->obd_nid_lock); list_move(&stat->nid_list, data); spin_unlock(&stat->nid_obd->obd_nid_lock); - EXIT; - return; + RETURN(1); } /* we has reference to object - only clear data*/ if (stat->nid_stats) @@ -1614,8 +1611,7 @@ void lprocfs_nid_stats_clear_write_cb(void *obj, void *data) for (i = 0; i < BRW_LAST; i++) lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]); } - EXIT; - return; + RETURN(0); } int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer, @@ -1625,7 +1621,7 @@ int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer, struct nid_stat *client_stat; CFS_LIST_HEAD(free_list); - lustre_hash_for_each(obd->obd_nid_stats_hash, + lustre_hash_cond_del(obd->obd_nid_stats_hash, lprocfs_nid_stats_clear_write_cb, &free_list); while (!list_empty(&free_list)) { diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index ec22359..210c9ba 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -276,22 +276,9 @@ static int filter_export_stats_init(struct obd_device *obd, if (rc) RETURN(rc); - rc = lprocfs_register_stats(tmp->nid_proc, "stats", - tmp->nid_stats); + rc = lprocfs_nid_ldlm_stats_init(tmp); if (rc) RETURN(rc); - - /* Always add in ldlm_stats */ - tmp->nid_ldlm_stats = - lprocfs_alloc_stats(LDLM_LAST_OPC - LDLM_FIRST_OPC, - LPROCFS_STATS_FLAG_NOPERCPU); - if (tmp->nid_ldlm_stats == NULL) - return -ENOMEM; - - lprocfs_init_ldlm_stats(tmp->nid_ldlm_stats); - - rc = lprocfs_register_stats(tmp->nid_proc, "ldlm_stats", - tmp->nid_ldlm_stats); } RETURN(0);