-int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
- int *eof, void *data)
-{
- struct obd_export *exp = data;
- LASSERT(exp != NULL);
- *eof = 1;
- return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
-}
-
-struct exp_uuid_cb_data {
- char *page;
- int count;
- int *eof;
- int *len;
-};
-
-static void
-lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
- int count, int *eof, int *len)
-{
- cb_data->page = page;
- cb_data->count = count;
- cb_data->eof = eof;
- cb_data->len = len;
-}
-
-int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
- cfs_hlist_node_t *hnode, void *cb_data)
-
-{
- struct obd_export *exp = cfs_hash_object(hs, hnode);
- struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
-
- if (exp->exp_nid_stats)
- *data->len += snprintf((data->page + *data->len),
- data->count, "%s\n",
- obd_uuid2str(&exp->exp_client_uuid));
- return 0;
-}
-
-int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
- int *eof, void *data)
-{
- struct nid_stat *stats = (struct nid_stat *)data;
- struct exp_uuid_cb_data cb_data;
- struct obd_device *obd = stats->nid_obd;
- int len = 0;
-
- *eof = 1;
- page[0] = '\0';
- lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
- cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
- lprocfs_exp_print_uuid, &cb_data);
- return (*cb_data.len);
-}
-
-int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
- cfs_hlist_node_t *hnode, void *cb_data)
-
-{
- struct exp_uuid_cb_data *data = cb_data;
- struct obd_export *exp = cfs_hash_object(hs, hnode);
-
- if (exp->exp_lock_hash != NULL) {
- if (!*data->len) {
- *data->len += cfs_hash_debug_header(data->page,
- data->count);
- }
- *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
- data->count);
- }
-
- return 0;
-}
-
-int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
- int *eof, void *data)
-{
- struct nid_stat *stats = (struct nid_stat *)data;
- struct exp_uuid_cb_data cb_data;
- struct obd_device *obd = stats->nid_obd;
- int len = 0;
-
- *eof = 1;
- page[0] = '\0';
- lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
-
- cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
- lprocfs_exp_print_hash, &cb_data);
- return (*cb_data.len);
-}
-
-int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- *eof = 1;
- return snprintf(page, count, "%s\n",
- "Write into this file to clear all nid stats and "
- "stale nid entries");
-}
-EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
-
-static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
-{
- struct nid_stat *stat = obj;
- int i;
- ENTRY;
-
- CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
- if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
- /* object has only hash references. */
- spin_lock(&stat->nid_obd->obd_nid_lock);
- cfs_list_move(&stat->nid_list, data);
- spin_unlock(&stat->nid_obd->obd_nid_lock);
- RETURN(1);
- }
- /* we has reference to object - only clear data*/
- if (stat->nid_stats)
- lprocfs_clear_stats(stat->nid_stats);
-
- if (stat->nid_brw_stats) {
- for (i = 0; i < BRW_LAST; i++)
- lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
- }
- RETURN(0);
-}
-
-int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
- unsigned long count, void *data)
-{
- struct obd_device *obd = (struct obd_device *)data;
- struct nid_stat *client_stat;
- CFS_LIST_HEAD(free_list);
-
- cfs_hash_cond_del(obd->obd_nid_stats_hash,
- lprocfs_nid_stats_clear_write_cb, &free_list);
-
- while (!cfs_list_empty(&free_list)) {
- client_stat = cfs_list_entry(free_list.next, struct nid_stat,
- nid_list);
- cfs_list_del_init(&client_stat->nid_list);
- lprocfs_free_client_stats(client_stat);
- }
-
- return count;
-}
-EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
-
-int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
-{
- struct nid_stat *new_stat, *old_stat;
- struct obd_device *obd = NULL;
- cfs_proc_dir_entry_t *entry;
- char *buffer = NULL;
- int rc = 0;
- ENTRY;
-
- *newnid = 0;
-
- if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
- !exp->exp_obd->obd_nid_stats_hash)
- 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.*/
- if (!nid || *nid == LNET_NID_ANY)
- RETURN(0);
-
- obd = exp->exp_obd;
-
- CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
-
- OBD_ALLOC_PTR(new_stat);
- if (new_stat == NULL)
- RETURN(-ENOMEM);
-
- new_stat->nid = *nid;
- new_stat->nid_obd = exp->exp_obd;
- /* we need set default refcount to 1 to balance obd_disconnect */
- cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
-
- old_stat = cfs_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",
- old_stat, libcfs_nid2str(*nid),
- cfs_atomic_read(&new_stat->nid_exp_ref_count));
-
- /* We need to release old stats because lprocfs_exp_cleanup() hasn't
- * been and will never be called. */
- if (exp->exp_nid_stats) {
- nidstat_putref(exp->exp_nid_stats);
- exp->exp_nid_stats = NULL;
- }
-
- /* Return -EALREADY here so that we know that the /proc
- * entry already has been created */
- if (old_stat != new_stat) {
- exp->exp_nid_stats = old_stat;
- GOTO(destroy_new, rc = -EALREADY);
- }
- /* not found - create */
- OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
- if (buffer == NULL)
- GOTO(destroy_new, rc = -ENOMEM);
-
- memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
- new_stat->nid_proc = lprocfs_register(buffer,
- obd->obd_proc_exports_entry,
- NULL, NULL);
- OBD_FREE(buffer, LNET_NIDSTR_SIZE);
-
- if (new_stat->nid_proc == NULL) {
- CERROR("Error making export directory for nid %s\n",
- libcfs_nid2str(*nid));
- GOTO(destroy_new_ns, rc = -ENOMEM);
- }
-
- 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 NID stats file\n");
- rc = PTR_ERR(entry);
- GOTO(destroy_new_ns, rc);
- }
-
- 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);
- GOTO(destroy_new_ns, rc);
- }
-
- exp->exp_nid_stats = new_stat;
- *newnid = 1;
- /* protect competitive add to list, not need locking on destroy */
- spin_lock(&obd->obd_nid_lock);
- cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
- spin_unlock(&obd->obd_nid_lock);
-
- RETURN(rc);
-
-destroy_new_ns:
- if (new_stat->nid_proc != NULL)
- lprocfs_remove(&new_stat->nid_proc);
- cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
-
-destroy_new:
- nidstat_putref(new_stat);
- OBD_FREE_PTR(new_stat);
- RETURN(rc);
-}
-EXPORT_SYMBOL(lprocfs_exp_setup);
-
-int lprocfs_exp_cleanup(struct obd_export *exp)
-{
- struct nid_stat *stat = exp->exp_nid_stats;
-
- if(!stat || !exp->exp_obd)
- RETURN(0);
-
- nidstat_putref(exp->exp_nid_stats);
- exp->exp_nid_stats = NULL;
-
- return 0;
-}
-EXPORT_SYMBOL(lprocfs_exp_cleanup);
-
-int lprocfs_write_helper(const char *buffer, unsigned long count,