1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/obdclass/lprocfs_status.c
38 * Author: Hariharan Thantry <thantry@users.sourceforge.net>
42 # define EXPORT_SYMTAB
44 #define DEBUG_SUBSYSTEM S_CLASS
47 # include <liblustre.h>
50 #include <obd_class.h>
51 #include <lprocfs_status.h>
52 #include <lustre_fsfilt.h>
53 #include <lustre_log.h>
54 #include <lustre/lustre_idl.h>
58 #define MAX_STRING_SIZE 128
60 /* for bug 10866, global variable */
61 CFS_DECLARE_RWSEM(_lprocfs_lock);
62 EXPORT_SYMBOL(_lprocfs_lock);
64 int lprocfs_seq_release(struct inode *inode, struct file *file)
67 return seq_release(inode, file);
69 EXPORT_SYMBOL(lprocfs_seq_release);
71 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
74 struct proc_dir_entry *temp;
81 while (temp != NULL) {
82 if (strcmp(temp->name, name) == 0) {
93 /* lprocfs API calls */
95 /* Function that emulates snprintf but also has the side effect of advancing
96 the page pointer for the next write into the buffer, incrementing the total
97 length written to the buffer, and decrementing the size left in the
99 static int lprocfs_obd_snprintf(char **page, int end, int *len,
100 const char *format, ...)
108 va_start(list, format);
109 n = vsnprintf(*page, end - *len, format, list);
112 *page += n; *len += n;
116 cfs_proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
118 read_proc_t *read_proc,
119 write_proc_t *write_proc,
121 struct file_operations *fops)
123 cfs_proc_dir_entry_t *proc;
126 if (root == NULL || name == NULL)
127 return ERR_PTR(-EINVAL);
134 proc = create_proc_entry(name, mode, root);
136 CERROR("LprocFS: No memory to create /proc entry %s", name);
137 return ERR_PTR(-ENOMEM);
139 proc->read_proc = read_proc;
140 proc->write_proc = write_proc;
143 proc->proc_fops = fops;
147 struct proc_dir_entry *lprocfs_add_symlink(const char *name,
148 struct proc_dir_entry *parent, const char *format, ...)
150 struct proc_dir_entry *entry;
154 if (parent == NULL || format == NULL)
157 OBD_ALLOC_WAIT(dest, MAX_STRING_SIZE + 1);
161 va_start(ap, format);
162 vsnprintf(dest, MAX_STRING_SIZE, format, ap);
165 entry = proc_symlink(name, parent, dest);
167 CERROR("LprocFS: Could not create symbolic link from %s to %s",
170 OBD_FREE(dest, MAX_STRING_SIZE + 1);
174 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
175 size_t size, loff_t *ppos)
177 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
178 char *page, *start = NULL;
179 int rc = 0, eof = 1, count;
181 if (*ppos >= CFS_PAGE_SIZE)
184 page = (char *)__get_free_page(GFP_KERNEL);
188 if (LPROCFS_ENTRY_AND_CHECK(dp))
191 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
193 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
199 /* for lustre proc read, the read count must be less than PAGE_SIZE */
208 start = page + *ppos;
209 } else if (start < page) {
213 count = (rc < size) ? rc : size;
214 if (cfs_copy_to_user(buf, start, count)) {
221 free_page((unsigned long)page);
225 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
226 size_t size, loff_t *ppos)
228 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
231 if (LPROCFS_ENTRY_AND_CHECK(dp))
234 rc = dp->write_proc(f, buf, size, dp->data);
239 static struct file_operations lprocfs_generic_fops = {
240 .owner = THIS_MODULE,
241 .read = lprocfs_fops_read,
242 .write = lprocfs_fops_write,
245 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
247 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
248 struct obd_device *obd = dp->data;
250 cfs_atomic_inc(&obd->obd_evict_inprogress);
255 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
257 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
258 struct obd_device *obd = dp->data;
260 cfs_atomic_dec(&obd->obd_evict_inprogress);
261 cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
266 struct file_operations lprocfs_evict_client_fops = {
267 .owner = THIS_MODULE,
268 .read = lprocfs_fops_read,
269 .write = lprocfs_fops_write,
270 .open = lprocfs_evict_client_open,
271 .release = lprocfs_evict_client_release,
273 EXPORT_SYMBOL(lprocfs_evict_client_fops);
278 * \param root [in] The parent proc entry on which new entry will be added.
279 * \param list [in] Array of proc entries to be added.
280 * \param data [in] The argument to be passed when entries read/write routines
281 * are called through /proc file.
283 * \retval 0 on success
286 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
289 if (root == NULL || list == NULL)
292 while (list->name != NULL) {
293 struct proc_dir_entry *cur_root, *proc;
294 char *pathcopy, *cur, *next, pathbuf[64];
295 int pathsize = strlen(list->name) + 1;
300 /* need copy of path for strsep */
301 if (strlen(list->name) > sizeof(pathbuf) - 1) {
302 OBD_ALLOC(pathcopy, pathsize);
303 if (pathcopy == NULL)
310 strcpy(pathcopy, list->name);
312 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
313 if (*cur =='\0') /* skip double/trailing "/" */
316 proc = lprocfs_srch(cur_root, cur);
317 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
318 cur_root->name, cur, next,
319 (proc ? "exists" : "new"));
321 cur_root = (proc ? proc :
322 proc_mkdir(cur, cur_root));
323 } else if (proc == NULL) {
325 if (list->proc_mode != 0000) {
326 mode = list->proc_mode;
330 if (list->write_fptr)
333 proc = create_proc_entry(cur, mode, cur_root);
337 if (pathcopy != pathbuf)
338 OBD_FREE(pathcopy, pathsize);
340 if (cur_root == NULL || proc == NULL) {
341 CERROR("LprocFS: No memory to create /proc entry %s",
347 proc->proc_fops = list->fops;
349 proc->proc_fops = &lprocfs_generic_fops;
350 proc->read_proc = list->read_fptr;
351 proc->write_proc = list->write_fptr;
352 proc->data = (list->data ? list->data : data);
358 void lprocfs_remove(struct proc_dir_entry **rooth)
360 struct proc_dir_entry *root = *rooth;
361 struct proc_dir_entry *temp = root;
362 struct proc_dir_entry *rm_entry;
363 struct proc_dir_entry *parent;
369 parent = root->parent;
370 LASSERT(parent != NULL);
371 LPROCFS_WRITE_ENTRY(); /* search vs remove race */
374 while (temp->subdir != NULL)
380 /* Memory corruption once caused this to fail, and
381 without this LASSERT we would loop here forever. */
382 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
383 "0x%p %s/%s len %d\n", rm_entry, temp->name,
384 rm_entry->name, (int)strlen(rm_entry->name));
386 /* Now, the rm_entry->deleted flags is protected
387 * by _lprocfs_lock. */
388 rm_entry->data = NULL;
389 remove_proc_entry(rm_entry->name, temp);
393 LPROCFS_WRITE_EXIT();
396 void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
398 LASSERT(parent != NULL);
399 remove_proc_entry(name, parent);
402 struct proc_dir_entry *lprocfs_register(const char *name,
403 struct proc_dir_entry *parent,
404 struct lprocfs_vars *list, void *data)
406 struct proc_dir_entry *newchild;
408 newchild = lprocfs_srch(parent, name);
409 if (newchild != NULL) {
410 CERROR(" Lproc: Attempting to register %s more than once \n",
412 return ERR_PTR(-EALREADY);
415 newchild = proc_mkdir(name, parent);
416 if (newchild != NULL && list != NULL) {
417 int rc = lprocfs_add_vars(newchild, list, data);
419 lprocfs_remove(&newchild);
426 /* Generic callbacks */
427 int lprocfs_rd_uint(char *page, char **start, off_t off,
428 int count, int *eof, void *data)
430 unsigned int *temp = data;
431 return snprintf(page, count, "%u\n", *temp);
434 int lprocfs_wr_uint(struct file *file, const char *buffer,
435 unsigned long count, void *data)
438 char dummy[MAX_STRING_SIZE + 1], *end;
441 dummy[MAX_STRING_SIZE] = '\0';
442 if (cfs_copy_from_user(dummy, buffer, MAX_STRING_SIZE))
445 tmp = simple_strtoul(dummy, &end, 0);
449 *p = (unsigned int)tmp;
453 int lprocfs_rd_u64(char *page, char **start, off_t off,
454 int count, int *eof, void *data)
456 LASSERT(data != NULL);
458 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
461 int lprocfs_rd_atomic(char *page, char **start, off_t off,
462 int count, int *eof, void *data)
464 cfs_atomic_t *atom = data;
465 LASSERT(atom != NULL);
467 return snprintf(page, count, "%d\n", cfs_atomic_read(atom));
470 int lprocfs_wr_atomic(struct file *file, const char *buffer,
471 unsigned long count, void *data)
473 cfs_atomic_t *atm = data;
477 rc = lprocfs_write_helper(buffer, count, &val);
484 cfs_atomic_set(atm, val);
488 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
489 int *eof, void *data)
491 struct obd_device *obd = data;
493 LASSERT(obd != NULL);
495 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
498 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
499 int *eof, void *data)
501 struct obd_device *dev = data;
503 LASSERT(dev != NULL);
504 LASSERT(dev->obd_name != NULL);
506 return snprintf(page, count, "%s\n", dev->obd_name);
509 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
512 struct obd_device *obd = data;
514 LASSERT(obd != NULL);
515 LASSERT(obd->obd_fsops != NULL);
516 LASSERT(obd->obd_fsops->fs_type != NULL);
517 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
520 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
521 int *eof, void *data)
523 struct obd_statfs osfs;
524 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - CFS_HZ,
528 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
533 int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
534 int *eof, void *data)
536 struct obd_statfs osfs;
537 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - CFS_HZ,
540 __u32 blk_size = osfs.os_bsize >> 10;
541 __u64 result = osfs.os_blocks;
543 while (blk_size >>= 1)
547 rc = snprintf(page, count, LPU64"\n", result);
552 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
553 int *eof, void *data)
555 struct obd_statfs osfs;
556 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - CFS_HZ,
559 __u32 blk_size = osfs.os_bsize >> 10;
560 __u64 result = osfs.os_bfree;
562 while (blk_size >>= 1)
566 rc = snprintf(page, count, LPU64"\n", result);
571 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
572 int *eof, void *data)
574 struct obd_statfs osfs;
575 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - CFS_HZ,
578 __u32 blk_size = osfs.os_bsize >> 10;
579 __u64 result = osfs.os_bavail;
581 while (blk_size >>= 1)
585 rc = snprintf(page, count, LPU64"\n", result);
590 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
591 int *eof, void *data)
593 struct obd_statfs osfs;
594 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - CFS_HZ,
598 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
604 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
605 int *eof, void *data)
607 struct obd_statfs osfs;
608 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - CFS_HZ,
612 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
617 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
618 int *eof, void *data)
620 struct obd_device *obd = data;
621 struct obd_import *imp;
622 char *imp_state_name = NULL;
625 LASSERT(obd != NULL);
626 LPROCFS_CLIMP_CHECK(obd);
627 imp = obd->u.cli.cl_import;
628 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
630 rc = snprintf(page, count, "%s\t%s%s\n",
631 obd2cli_tgt(obd), imp_state_name,
632 imp->imp_deactive ? "\tDEACTIVATED" : "");
634 LPROCFS_CLIMP_EXIT(obd);
638 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
639 int *eof, void *data)
641 struct obd_device *obd = data;
642 struct ptlrpc_connection *conn;
645 LASSERT(obd != NULL);
647 LPROCFS_CLIMP_CHECK(obd);
648 conn = obd->u.cli.cl_import->imp_connection;
650 if (conn && obd->u.cli.cl_import) {
651 rc = snprintf(page, count, "%s\n",
652 conn->c_remote_uuid.uuid);
654 rc = snprintf(page, count, "%s\n", "<none>");
657 LPROCFS_CLIMP_EXIT(obd);
661 /** add up per-cpu counters */
662 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
663 struct lprocfs_counter *cnt)
665 unsigned int num_cpu;
666 struct lprocfs_counter t;
667 struct lprocfs_counter *percpu_cntr;
670 memset(cnt, 0, sizeof(*cnt));
673 /* set count to 1 to avoid divide-by-zero errs in callers */
678 cnt->lc_min = LC_MIN_INIT;
680 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
683 num_cpu = cfs_num_possible_cpus();
685 for (i = 0; i < num_cpu; i++) {
686 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
689 centry = cfs_atomic_read(&percpu_cntr-> \
691 t.lc_count = percpu_cntr->lc_count;
692 t.lc_sum = percpu_cntr->lc_sum;
693 t.lc_min = percpu_cntr->lc_min;
694 t.lc_max = percpu_cntr->lc_max;
695 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
696 } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
698 centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
700 cnt->lc_count += t.lc_count;
701 cnt->lc_sum += t.lc_sum;
702 if (t.lc_min < cnt->lc_min)
703 cnt->lc_min = t.lc_min;
704 if (t.lc_max > cnt->lc_max)
705 cnt->lc_max = t.lc_max;
706 cnt->lc_sumsquare += t.lc_sumsquare;
709 cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
713 * Append a space separated list of current set flags to str.
715 #define flag2str(flag) \
716 if (imp->imp_##flag && max - len > 0) \
717 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
718 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
722 if (imp->imp_obd->obd_no_recov)
723 len += snprintf(str, max - len, "no_recov");
727 flag2str(replayable);
730 flag2str(last_recon);
735 static const char *obd_connect_names[] = {
749 "join_file(obsolete)",
753 "remote_client_by_force",
762 "mds_mds_connection",
765 "alt_checksum_algorithm",
775 static int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
780 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
782 ret += snprintf(page + ret, count - ret, "%s%s",
783 ret ? sep : "", obd_connect_names[i]);
785 if (flags & ~(mask - 1))
786 ret += snprintf(page + ret, count - ret,
787 "%sunknown flags "LPX64,
788 ret ? sep : "", flags & ~(mask - 1));
792 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
793 int *eof, void *data)
795 struct lprocfs_counter ret;
796 struct obd_device *obd = (struct obd_device *)data;
797 struct obd_import *imp;
800 LASSERT(obd != NULL);
801 LPROCFS_CLIMP_CHECK(obd);
802 imp = obd->u.cli.cl_import;
805 i = snprintf(page, count,
809 " current_connection: %s\n"
814 imp->imp_connection->c_remote_uuid.uuid,
815 ptlrpc_import_state_name(imp->imp_state));
816 i += obd_connect_flags2str(page + i, count - i,
817 imp->imp_connect_data.ocd_connect_flags,
819 i += snprintf(page + i, count - i,
822 i += obd_import_flags2str(imp, page + i, count - i);
824 i += snprintf(page + i, count - i,
827 " connection_attempts: %u\n"
829 " in-progress_invalidations: %u\n",
832 cfs_atomic_read(&imp->imp_inval_count));
834 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
835 if (ret.lc_count != 0)
836 do_div(ret.lc_sum, ret.lc_count);
839 i += snprintf(page + i, count - i,
842 " unregistering: %u\n"
844 " avg_waittime: "LPU64" %s\n",
845 cfs_atomic_read(&imp->imp_inflight),
846 cfs_atomic_read(&imp->imp_unregistering),
847 cfs_atomic_read(&imp->imp_timeouts),
848 ret.lc_sum, ret.lc_units);
851 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
852 if (imp->imp_at.iat_portal[j] == 0)
854 k = max_t(unsigned int, k,
855 at_get(&imp->imp_at.iat_service_estimate[j]));
857 i += snprintf(page + i, count - i,
858 " service_estimates:\n"
859 " services: %u sec\n"
860 " network: %u sec\n",
862 at_get(&imp->imp_at.iat_net_latency));
864 i += snprintf(page + i, count - i,
866 " last_replay: "LPU64"\n"
867 " peer_committed: "LPU64"\n"
868 " last_checked: "LPU64"\n",
869 imp->imp_last_replay_transno,
870 imp->imp_peer_committed_transno,
871 imp->imp_last_transno_checked);
874 for (rw = 0; rw <= 1; rw++) {
875 lprocfs_stats_collect(obd->obd_svc_stats,
876 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
878 if (ret.lc_sum > 0 && ret.lc_count > 0) {
879 do_div(ret.lc_sum, ret.lc_count);
880 i += snprintf(page + i, count - i,
881 " %s_data_averages:\n"
882 " bytes_per_rpc: "LPU64"\n",
883 rw ? "write" : "read",
887 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
888 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
889 if (ret.lc_sum > 0 && ret.lc_count != 0) {
890 do_div(ret.lc_sum, ret.lc_count);
891 i += snprintf(page + i, count - i,
892 " %s_per_rpc: "LPU64"\n",
893 ret.lc_units, ret.lc_sum);
896 i += snprintf(page + i, count - i,
897 " MB_per_sec: %u.%.02u\n",
898 k / j, (100 * k / j) % 100);
902 LPROCFS_CLIMP_EXIT(obd);
906 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
907 int *eof, void *data)
909 struct obd_device *obd = (struct obd_device *)data;
910 struct obd_import *imp;
913 LASSERT(obd != NULL);
914 LPROCFS_CLIMP_CHECK(obd);
915 imp = obd->u.cli.cl_import;
918 i = snprintf(page, count, "current_state: %s\n",
919 ptlrpc_import_state_name(imp->imp_state));
920 i += snprintf(page + i, count - i,
922 k = imp->imp_state_hist_idx;
923 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
924 struct import_state_hist *ish =
925 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
926 if (ish->ish_state == 0)
928 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
930 ptlrpc_import_state_name(ish->ish_state));
933 LPROCFS_CLIMP_EXIT(obd);
937 int lprocfs_at_hist_helper(char *page, int count, int rc,
938 struct adaptive_timeout *at)
941 for (i = 0; i < AT_BINS; i++)
942 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
943 rc += snprintf(page + rc, count - rc, "\n");
947 /* See also ptlrpc_lprocfs_rd_timeouts */
948 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
949 int *eof, void *data)
951 struct obd_device *obd = (struct obd_device *)data;
952 struct obd_import *imp;
953 unsigned int cur, worst;
958 LASSERT(obd != NULL);
959 LPROCFS_CLIMP_CHECK(obd);
960 imp = obd->u.cli.cl_import;
963 now = cfs_time_current_sec();
965 /* Some network health info for kicks */
966 s2dhms(&ts, now - imp->imp_last_reply_time);
967 rc += snprintf(page + rc, count - rc,
968 "%-10s : %ld, "DHMS_FMT" ago\n",
969 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
971 cur = at_get(&imp->imp_at.iat_net_latency);
972 worst = imp->imp_at.iat_net_latency.at_worst_ever;
973 worstt = imp->imp_at.iat_net_latency.at_worst_time;
974 s2dhms(&ts, now - worstt);
975 rc += snprintf(page + rc, count - rc,
976 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
977 "network", cur, worst, worstt, DHMS_VARS(&ts));
978 rc = lprocfs_at_hist_helper(page, count, rc,
979 &imp->imp_at.iat_net_latency);
981 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
982 if (imp->imp_at.iat_portal[i] == 0)
984 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
985 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
986 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
987 s2dhms(&ts, now - worstt);
988 rc += snprintf(page + rc, count - rc,
989 "portal %-2d : cur %3u worst %3u (at %ld, "
990 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
991 cur, worst, worstt, DHMS_VARS(&ts));
992 rc = lprocfs_at_hist_helper(page, count, rc,
993 &imp->imp_at.iat_service_estimate[i]);
996 LPROCFS_CLIMP_EXIT(obd);
1000 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1001 int count, int *eof, void *data)
1003 struct obd_device *obd = data;
1007 LPROCFS_CLIMP_CHECK(obd);
1008 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1009 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1010 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1011 ret += snprintf(page + ret, count - ret, "\n");
1012 LPROCFS_CLIMP_EXIT(obd);
1015 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1017 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1018 int *eof, void *data)
1020 struct obd_device *obd = data;
1022 LASSERT(obd != NULL);
1024 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1027 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1028 int *eof, void *data)
1030 struct obd_type *class = (struct obd_type*) data;
1032 LASSERT(class != NULL);
1034 return snprintf(page, count, "%d\n", class->typ_refcnt);
1037 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1041 LASSERT(obd != NULL);
1042 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1043 LASSERT(obd->obd_type->typ_procroot != NULL);
1045 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1046 obd->obd_type->typ_procroot,
1048 if (IS_ERR(obd->obd_proc_entry)) {
1049 rc = PTR_ERR(obd->obd_proc_entry);
1050 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1051 obd->obd_proc_entry = NULL;
1056 int lprocfs_obd_cleanup(struct obd_device *obd)
1060 if (obd->obd_proc_exports_entry) {
1061 /* Should be no exports left */
1062 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1063 lprocfs_remove(&obd->obd_proc_exports_entry);
1064 obd->obd_proc_exports_entry = NULL;
1066 if (obd->obd_proc_entry) {
1067 lprocfs_remove(&obd->obd_proc_entry);
1068 obd->obd_proc_entry = NULL;
1073 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1075 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1076 client_stat->nid_proc, client_stat->nid_stats,
1077 client_stat->nid_brw_stats);
1079 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1081 cfs_atomic_read(&client_stat->nid_exp_ref_count));
1083 cfs_hlist_del_init(&client_stat->nid_hash);
1085 if (client_stat->nid_proc)
1086 lprocfs_remove(&client_stat->nid_proc);
1088 if (client_stat->nid_stats)
1089 lprocfs_free_stats(&client_stat->nid_stats);
1091 if (client_stat->nid_brw_stats)
1092 OBD_FREE_PTR(client_stat->nid_brw_stats);
1094 if (client_stat->nid_ldlm_stats)
1095 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1097 OBD_FREE_PTR(client_stat);
1102 void lprocfs_free_per_client_stats(struct obd_device *obd)
1104 struct nid_stat *stat;
1107 /* we need extra list - because hash_exit called to early */
1108 /* not need locking because all clients is died */
1109 while(!cfs_list_empty(&obd->obd_nid_stats)) {
1110 stat = cfs_list_entry(obd->obd_nid_stats.next,
1111 struct nid_stat, nid_list);
1112 cfs_list_del_init(&stat->nid_list);
1113 lprocfs_free_client_stats(stat);
1119 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1120 enum lprocfs_stats_flags flags)
1122 struct lprocfs_stats *stats;
1123 unsigned int percpusize;
1125 unsigned int num_cpu;
1130 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1133 num_cpu = cfs_num_possible_cpus();
1135 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1139 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1140 stats->ls_flags = flags;
1141 cfs_spin_lock_init(&stats->ls_lock);
1142 /* Use this lock only if there are no percpu areas */
1144 stats->ls_flags = 0;
1147 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1149 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1151 for (i = 0; i < num_cpu; i++) {
1152 OBD_ALLOC(stats->ls_percpu[i], percpusize);
1153 if (stats->ls_percpu[i] == NULL) {
1154 for (j = 0; j < i; j++) {
1155 OBD_FREE(stats->ls_percpu[j], percpusize);
1156 stats->ls_percpu[j] = NULL;
1161 if (stats->ls_percpu[0] == NULL) {
1162 OBD_FREE(stats, offsetof(typeof(*stats),
1163 ls_percpu[num_cpu]));
1167 stats->ls_num = num;
1171 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1173 struct lprocfs_stats *stats = *statsh;
1174 unsigned int num_cpu;
1175 unsigned int percpusize;
1178 if (stats == NULL || stats->ls_num == 0)
1182 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1185 num_cpu = cfs_num_possible_cpus();
1187 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1189 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1190 for (i = 0; i < num_cpu; i++)
1191 OBD_FREE(stats->ls_percpu[i], percpusize);
1192 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1195 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1197 struct lprocfs_counter *percpu_cntr;
1199 unsigned int num_cpu;
1201 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1203 for (i = 0; i < num_cpu; i++) {
1204 for (j = 0; j < stats->ls_num; j++) {
1205 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1206 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1207 percpu_cntr->lc_count = 0;
1208 percpu_cntr->lc_sum = 0;
1209 percpu_cntr->lc_min = LC_MIN_INIT;
1210 percpu_cntr->lc_max = 0;
1211 percpu_cntr->lc_sumsquare = 0;
1212 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1216 lprocfs_stats_unlock(stats);
1219 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1220 size_t len, loff_t *off)
1222 struct seq_file *seq = file->private_data;
1223 struct lprocfs_stats *stats = seq->private;
1225 lprocfs_clear_stats(stats);
1230 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1232 struct lprocfs_stats *stats = p->private;
1233 /* return 1st cpu location */
1234 return (*pos >= stats->ls_num) ? NULL :
1235 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1238 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1242 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1244 struct lprocfs_stats *stats = p->private;
1246 return (*pos >= stats->ls_num) ? NULL :
1247 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1250 /* seq file export of one lprocfs counter */
1251 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1253 struct lprocfs_stats *stats = p->private;
1254 struct lprocfs_counter *cntr = v;
1255 struct lprocfs_counter ret;
1258 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1260 cfs_gettimeofday(&now);
1261 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1262 "snapshot_time", now.tv_sec, now.tv_usec);
1266 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1268 lprocfs_stats_collect(stats, idx, &ret);
1270 if (ret.lc_count == 0)
1273 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1274 ret.lc_count, cntr->lc_units);
1279 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1280 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1281 ret.lc_min, ret.lc_max, ret.lc_sum);
1284 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1285 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1289 rc = seq_printf(p, "\n");
1291 return (rc < 0) ? rc : 0;
1294 struct seq_operations lprocfs_stats_seq_sops = {
1295 start: lprocfs_stats_seq_start,
1296 stop: lprocfs_stats_seq_stop,
1297 next: lprocfs_stats_seq_next,
1298 show: lprocfs_stats_seq_show,
1301 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1303 struct proc_dir_entry *dp = PDE(inode);
1304 struct seq_file *seq;
1307 if (LPROCFS_ENTRY_AND_CHECK(dp))
1310 rc = seq_open(file, &lprocfs_stats_seq_sops);
1315 seq = file->private_data;
1316 seq->private = dp->data;
1320 struct file_operations lprocfs_stats_seq_fops = {
1321 .owner = THIS_MODULE,
1322 .open = lprocfs_stats_seq_open,
1324 .write = lprocfs_stats_seq_write,
1325 .llseek = seq_lseek,
1326 .release = lprocfs_seq_release,
1329 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1330 struct lprocfs_stats *stats)
1332 struct proc_dir_entry *entry;
1333 LASSERT(root != NULL);
1335 entry = create_proc_entry(name, 0644, root);
1338 entry->proc_fops = &lprocfs_stats_seq_fops;
1339 entry->data = stats;
1343 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1344 unsigned conf, const char *name, const char *units)
1346 struct lprocfs_counter *c;
1348 unsigned int num_cpu;
1350 LASSERT(stats != NULL);
1352 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1354 for (i = 0; i < num_cpu; i++) {
1355 c = &(stats->ls_percpu[i]->lp_cntr[index]);
1356 c->lc_config = conf;
1359 c->lc_min = LC_MIN_INIT;
1362 c->lc_units = units;
1365 lprocfs_stats_unlock(stats);
1367 EXPORT_SYMBOL(lprocfs_counter_init);
1369 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1371 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1372 LASSERT(coffset < stats->ls_num); \
1373 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1376 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1378 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1379 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1380 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1381 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1382 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1383 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1384 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1385 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1386 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1387 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1388 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1389 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1390 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1391 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1392 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1393 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1394 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1395 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1396 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1397 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1398 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1399 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1400 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1401 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1402 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1403 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1404 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1405 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1406 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1407 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1408 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1409 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1410 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1411 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1412 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1413 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1414 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1415 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1416 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1417 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1418 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1419 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1420 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1421 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1422 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1423 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1424 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1425 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1426 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1427 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1428 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1429 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1430 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1431 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1432 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1433 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1434 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1435 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1436 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1437 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1438 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1439 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1440 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1441 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1442 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1443 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1444 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1445 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1446 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1449 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1451 struct lprocfs_stats *stats;
1452 unsigned int num_stats;
1455 LASSERT(obd->obd_stats == NULL);
1456 LASSERT(obd->obd_proc_entry != NULL);
1457 LASSERT(obd->obd_cntr_base == 0);
1459 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1460 num_private_stats - 1 /* o_owner */;
1461 stats = lprocfs_alloc_stats(num_stats, 0);
1465 lprocfs_init_ops_stats(num_private_stats, stats);
1467 for (i = num_private_stats; i < num_stats; i++) {
1468 /* If this LBUGs, it is likely that an obd
1469 * operation was added to struct obd_ops in
1470 * <obd.h>, and that the corresponding line item
1471 * LPROCFS_OBD_OP_INIT(.., .., opname)
1472 * is missing from the list above. */
1473 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1474 "Missing obd_stat initializer obd_op "
1475 "operation at offset %d.\n", i - num_private_stats);
1477 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1479 lprocfs_free_stats(&stats);
1481 obd->obd_stats = stats;
1482 obd->obd_cntr_base = num_private_stats;
1487 void lprocfs_free_obd_stats(struct obd_device *obd)
1490 lprocfs_free_stats(&obd->obd_stats);
1493 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1495 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1496 LASSERT(coffset < stats->ls_num); \
1497 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1500 int lprocfs_alloc_md_stats(struct obd_device *obd,
1501 unsigned num_private_stats)
1503 struct lprocfs_stats *stats;
1504 unsigned int num_stats;
1507 LASSERT(obd->md_stats == NULL);
1508 LASSERT(obd->obd_proc_entry != NULL);
1509 LASSERT(obd->md_cntr_base == 0);
1511 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1513 stats = lprocfs_alloc_stats(num_stats, 0);
1517 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1518 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1519 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1520 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1521 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1522 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1523 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1524 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1525 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1526 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1527 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1528 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1529 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1530 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1531 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1532 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1533 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1534 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1535 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1536 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1537 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1538 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1539 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1540 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1541 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1542 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1543 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1544 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1545 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1546 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1547 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1548 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1550 for (i = num_private_stats; i < num_stats; i++) {
1551 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1552 CERROR("Missing md_stat initializer md_op "
1553 "operation at offset %d. Aborting.\n",
1554 i - num_private_stats);
1558 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1560 lprocfs_free_stats(&stats);
1562 obd->md_stats = stats;
1563 obd->md_cntr_base = num_private_stats;
1568 void lprocfs_free_md_stats(struct obd_device *obd)
1570 struct lprocfs_stats *stats = obd->md_stats;
1572 if (stats != NULL) {
1573 obd->md_stats = NULL;
1574 obd->md_cntr_base = 0;
1575 lprocfs_free_stats(&stats);
1579 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1581 lprocfs_counter_init(ldlm_stats,
1582 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1583 0, "ldlm_enqueue", "reqs");
1584 lprocfs_counter_init(ldlm_stats,
1585 LDLM_CONVERT - LDLM_FIRST_OPC,
1586 0, "ldlm_convert", "reqs");
1587 lprocfs_counter_init(ldlm_stats,
1588 LDLM_CANCEL - LDLM_FIRST_OPC,
1589 0, "ldlm_cancel", "reqs");
1590 lprocfs_counter_init(ldlm_stats,
1591 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1592 0, "ldlm_bl_callback", "reqs");
1593 lprocfs_counter_init(ldlm_stats,
1594 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1595 0, "ldlm_cp_callback", "reqs");
1596 lprocfs_counter_init(ldlm_stats,
1597 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1598 0, "ldlm_gl_callback", "reqs");
1601 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1602 int *eof, void *data)
1604 struct obd_export *exp = data;
1605 LASSERT(exp != NULL);
1607 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1610 struct exp_uuid_cb_data {
1618 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1619 int count, int *eof, int *len)
1621 cb_data->page = page;
1622 cb_data->count = count;
1627 void lprocfs_exp_print_uuid(void *obj, void *cb_data)
1629 struct obd_export *exp = (struct obd_export *)obj;
1630 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1632 if (exp->exp_nid_stats)
1633 *data->len += snprintf((data->page + *data->len),
1634 data->count, "%s\n",
1635 obd_uuid2str(&exp->exp_client_uuid));
1638 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1639 int *eof, void *data)
1641 struct nid_stat *stats = (struct nid_stat *)data;
1642 struct exp_uuid_cb_data cb_data;
1643 struct obd_device *obd = stats->nid_obd;
1648 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1649 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1650 lprocfs_exp_print_uuid, &cb_data);
1651 return (*cb_data.len);
1654 void lprocfs_exp_print_hash(void *obj, void *cb_data)
1656 struct exp_uuid_cb_data *data = cb_data;
1657 struct obd_export *exp = obj;
1660 hs = exp->exp_lock_hash;
1663 *data->len += cfs_hash_debug_header(data->page,
1666 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1671 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1672 int *eof, void *data)
1674 struct nid_stat *stats = (struct nid_stat *)data;
1675 struct exp_uuid_cb_data cb_data;
1676 struct obd_device *obd = stats->nid_obd;
1681 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1683 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1684 lprocfs_exp_print_hash, &cb_data);
1685 return (*cb_data.len);
1688 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1689 int count, int *eof, void *data)
1692 return snprintf(page, count, "%s\n",
1693 "Write into this file to clear all nid stats and "
1694 "stale nid entries");
1696 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1698 void lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1700 struct nid_stat *stat = obj;
1703 /* object has only hash + iterate_all references.
1704 * add/delete blocked by hash bucket lock */
1705 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1706 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 2) {
1707 cfs_hlist_del_init(&stat->nid_hash);
1708 nidstat_putref(stat);
1709 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1710 cfs_list_move(&stat->nid_list, data);
1711 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1715 /* we has reference to object - only clear data*/
1716 if (stat->nid_stats)
1717 lprocfs_clear_stats(stat->nid_stats);
1719 if (stat->nid_brw_stats) {
1720 for (i = 0; i < BRW_LAST; i++)
1721 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1727 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1728 unsigned long count, void *data)
1730 struct obd_device *obd = (struct obd_device *)data;
1731 struct nid_stat *client_stat;
1732 CFS_LIST_HEAD(free_list);
1734 cfs_hash_for_each(obd->obd_nid_stats_hash,
1735 lprocfs_nid_stats_clear_write_cb, &free_list);
1737 while (!cfs_list_empty(&free_list)) {
1738 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1740 cfs_list_del_init(&client_stat->nid_list);
1741 lprocfs_free_client_stats(client_stat);
1746 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1748 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1750 struct nid_stat *new_stat, *old_stat;
1751 struct obd_device *obd = NULL;
1752 cfs_proc_dir_entry_t *entry;
1753 char *buffer = NULL;
1759 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1760 !exp->exp_obd->obd_nid_stats_hash)
1763 /* not test against zero because eric say:
1764 * You may only test nid against another nid, or LNET_NID_ANY.
1765 * Anything else is nonsense.*/
1766 if (!nid || *nid == LNET_NID_ANY)
1771 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1773 OBD_ALLOC_PTR(new_stat);
1774 if (new_stat == NULL)
1777 new_stat->nid = *nid;
1778 new_stat->nid_obd = exp->exp_obd;
1779 cfs_atomic_set(&new_stat->nid_exp_ref_count, 0);
1781 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1782 nid, &new_stat->nid_hash);
1783 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1784 old_stat, libcfs_nid2str(*nid),
1785 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1787 /* Return -EALREADY here so that we know that the /proc
1788 * entry already has been created */
1789 if (old_stat != new_stat) {
1790 cfs_spin_lock(&obd->obd_nid_lock);
1791 if (exp->exp_nid_stats != old_stat) {
1792 if (exp->exp_nid_stats)
1793 nidstat_putref(exp->exp_nid_stats);
1794 exp->exp_nid_stats = old_stat;
1796 /* cfs_hash_findadd_unique() has added
1797 * old_stat's refcount */
1798 nidstat_putref(old_stat);
1801 cfs_spin_unlock(&obd->obd_nid_lock);
1803 GOTO(destroy_new, rc = -EALREADY);
1805 /* not found - create */
1806 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1808 GOTO(destroy_new, rc = -ENOMEM);
1810 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1811 new_stat->nid_proc = lprocfs_register(buffer,
1812 obd->obd_proc_exports_entry,
1814 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1816 if (new_stat->nid_proc == NULL) {
1817 CERROR("Error making export directory for nid %s\n",
1818 libcfs_nid2str(*nid));
1819 GOTO(destroy_new_ns, rc = -ENOMEM);
1822 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1823 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1824 if (IS_ERR(entry)) {
1825 CWARN("Error adding the NID stats file\n");
1826 rc = PTR_ERR(entry);
1827 GOTO(destroy_new_ns, rc);
1830 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1831 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1832 if (IS_ERR(entry)) {
1833 CWARN("Error adding the hash file\n");
1834 rc = PTR_ERR(entry);
1835 GOTO(destroy_new_ns, rc);
1838 if (exp->exp_nid_stats)
1839 nidstat_putref(exp->exp_nid_stats);
1840 nidstat_getref(new_stat);
1841 exp->exp_nid_stats = new_stat;
1843 /* protect competitive add to list, not need locking on destroy */
1844 cfs_spin_lock(&obd->obd_nid_lock);
1845 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1846 cfs_spin_unlock(&obd->obd_nid_lock);
1851 if (new_stat->nid_proc != NULL)
1852 lprocfs_remove(&new_stat->nid_proc);
1853 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1856 OBD_FREE_PTR(new_stat);
1860 int lprocfs_exp_cleanup(struct obd_export *exp)
1862 struct nid_stat *stat = exp->exp_nid_stats;
1864 if(!stat || !exp->exp_obd)
1867 nidstat_putref(exp->exp_nid_stats);
1868 exp->exp_nid_stats = NULL;
1873 int lprocfs_write_helper(const char *buffer, unsigned long count,
1876 return lprocfs_write_frac_helper(buffer, count, val, 1);
1879 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1882 char kernbuf[20], *end, *pbuf;
1884 if (count > (sizeof(kernbuf) - 1))
1887 if (cfs_copy_from_user(kernbuf, buffer, count))
1890 kernbuf[count] = '\0';
1897 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1901 if (end != NULL && *end == '.') {
1902 int temp_val, pow = 1;
1906 if (strlen(pbuf) > 5)
1907 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1909 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1912 for (i = 0; i < (end - pbuf); i++)
1915 *val += temp_val / pow;
1921 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
1924 long decimal_val, frac_val;
1930 decimal_val = val / mult;
1931 prtn = snprintf(buffer, count, "%ld", decimal_val);
1932 frac_val = val % mult;
1934 if (prtn < (count - 4) && frac_val > 0) {
1936 int i, temp_mult = 1, frac_bits = 0;
1938 temp_frac = frac_val * 10;
1939 buffer[prtn++] = '.';
1940 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
1941 /* only reserved 2 bits fraction */
1942 buffer[prtn++] ='0';
1947 * Need to think these cases :
1948 * 1. #echo x.00 > /proc/xxx output result : x
1949 * 2. #echo x.0x > /proc/xxx output result : x.0x
1950 * 3. #echo x.x0 > /proc/xxx output result : x.x
1951 * 4. #echo x.xx > /proc/xxx output result : x.xx
1952 * Only reserved 2 bits fraction.
1954 for (i = 0; i < (5 - prtn); i++)
1957 frac_bits = min((int)count - prtn, 3 - frac_bits);
1958 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
1959 frac_val * temp_mult / mult);
1962 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
1964 if (buffer[prtn] == '.') {
1971 buffer[prtn++] ='\n';
1975 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
1977 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
1980 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
1981 __u64 *val, int mult)
1983 char kernbuf[22], *end, *pbuf;
1984 __u64 whole, frac = 0, units;
1985 unsigned frac_d = 1;
1987 if (count > (sizeof(kernbuf) - 1))
1990 if (cfs_copy_from_user(kernbuf, buffer, count))
1993 kernbuf[count] = '\0';
2000 whole = simple_strtoull(pbuf, &end, 10);
2004 if (end != NULL && *end == '.') {
2008 /* need to limit frac_d to a __u32 */
2009 if (strlen(pbuf) > 10)
2012 frac = simple_strtoull(pbuf, &end, 10);
2013 /* count decimal places */
2014 for (i = 0; i < (end - pbuf); i++)
2031 /* Specified units override the multiplier */
2033 mult = mult < 0 ? -units : units;
2036 do_div(frac, frac_d);
2037 *val = whole * mult + frac;
2041 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2042 struct file_operations *seq_fops, void *data)
2044 struct proc_dir_entry *entry;
2047 entry = create_proc_entry(name, mode, parent);
2050 entry->proc_fops = seq_fops;
2055 EXPORT_SYMBOL(lprocfs_seq_create);
2057 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2059 struct file_operations *seq_fops,
2062 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2063 mode, seq_fops, data));
2065 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2067 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2069 if (value >= OBD_HIST_MAX)
2070 value = OBD_HIST_MAX - 1;
2072 cfs_spin_lock(&oh->oh_lock);
2073 oh->oh_buckets[value]++;
2074 cfs_spin_unlock(&oh->oh_lock);
2076 EXPORT_SYMBOL(lprocfs_oh_tally);
2078 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2082 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2085 lprocfs_oh_tally(oh, val);
2087 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2089 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2091 unsigned long ret = 0;
2094 for (i = 0; i < OBD_HIST_MAX; i++)
2095 ret += oh->oh_buckets[i];
2098 EXPORT_SYMBOL(lprocfs_oh_sum);
2100 void lprocfs_oh_clear(struct obd_histogram *oh)
2102 cfs_spin_lock(&oh->oh_lock);
2103 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2104 cfs_spin_unlock(&oh->oh_lock);
2106 EXPORT_SYMBOL(lprocfs_oh_clear);
2108 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2109 int count, int *eof, void *data)
2111 struct obd_device *obd = data;
2117 c += cfs_hash_debug_header(page, count);
2118 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2119 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2120 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2124 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2126 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2127 int count, int *eof, void *data)
2129 struct obd_device *obd = data;
2132 LASSERT(obd != NULL);
2133 LASSERT(count >= 0);
2135 /* Set start of user data returned to
2136 page + off since the user may have
2137 requested to read much smaller than
2138 what we need to read */
2139 *start = page + off;
2141 /* We know we are allocated a page here.
2142 Also we know that this function will
2143 not need to write more than a page
2144 so we can truncate at CFS_PAGE_SIZE. */
2145 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2147 /* Initialize the page */
2148 memset(page, 0, size);
2150 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2152 if (obd->obd_max_recoverable_clients == 0) {
2153 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2159 /* sampled unlocked, but really... */
2160 if (obd->obd_recovering == 0) {
2161 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2163 if (lprocfs_obd_snprintf(&page, size, &len,
2164 "recovery_start: %lu\n",
2165 obd->obd_recovery_start) <= 0)
2167 if (lprocfs_obd_snprintf(&page, size, &len,
2168 "recovery_duration: %lu\n",
2169 obd->obd_recovery_end -
2170 obd->obd_recovery_start) <= 0)
2172 /* Number of clients that have completed recovery */
2173 if (lprocfs_obd_snprintf(&page, size, &len,
2174 "completed_clients: %d/%d\n",
2175 obd->obd_max_recoverable_clients -
2176 obd->obd_stale_clients,
2177 obd->obd_max_recoverable_clients) <= 0)
2179 if (lprocfs_obd_snprintf(&page, size, &len,
2180 "replayed_requests: %d\n",
2181 obd->obd_replayed_requests) <= 0)
2183 if (lprocfs_obd_snprintf(&page, size, &len,
2184 "last_transno: "LPD64"\n",
2185 obd->obd_next_recovery_transno - 1)<=0)
2187 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2188 obd->obd_version_recov ? "ON" : "OFF")<=0)
2193 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2195 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2196 obd->obd_recovery_start) <= 0)
2198 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2199 cfs_time_current_sec() >= obd->obd_recovery_end ? 0 :
2200 obd->obd_recovery_end - cfs_time_current_sec()) <= 0)
2202 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2203 obd->obd_connected_clients,
2204 obd->obd_max_recoverable_clients) <= 0)
2206 /* Number of clients that have completed recovery */
2207 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2208 cfs_atomic_read(&obd->obd_req_replay_clients))
2211 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2212 cfs_atomic_read(&obd->obd_lock_replay_clients))
2215 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2216 obd->obd_connected_clients -
2217 cfs_atomic_read(&obd->obd_lock_replay_clients))
2220 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2221 obd->obd_stale_clients) <= 0)
2223 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2224 obd->obd_replayed_requests) <= 0)
2226 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2227 obd->obd_requests_queued_for_recovery) <= 0)
2230 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2231 obd->obd_next_recovery_transno) <= 0)
2237 return min(count, len - (int)off);
2239 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2241 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2242 int count, int *eof, void *data)
2244 struct obd_device *obd = (struct obd_device *)data;
2245 LASSERT(obd != NULL);
2247 return snprintf(page, count, "%d\n",
2248 obd->obd_recovery_timeout);
2250 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2252 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2253 unsigned long count, void *data)
2255 struct obd_device *obd = (struct obd_device *)data;
2257 LASSERT(obd != NULL);
2259 rc = lprocfs_write_helper(buffer, count, &val);
2263 obd->obd_recovery_timeout = val;
2266 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2268 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2269 int count, int *eof, void *data)
2271 struct obd_device *obd = data;
2272 LASSERT(obd != NULL);
2274 return snprintf(page, count, "%lu\n", obd->obd_recovery_time_hard);
2276 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2278 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2279 unsigned long count, void *data)
2281 struct obd_device *obd = data;
2283 LASSERT(obd != NULL);
2285 rc = lprocfs_write_helper(buffer, count, &val);
2289 obd->obd_recovery_time_hard = val;
2292 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2294 EXPORT_SYMBOL(lprocfs_register);
2295 EXPORT_SYMBOL(lprocfs_srch);
2296 EXPORT_SYMBOL(lprocfs_remove);
2297 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2298 EXPORT_SYMBOL(lprocfs_add_vars);
2299 EXPORT_SYMBOL(lprocfs_obd_setup);
2300 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2301 EXPORT_SYMBOL(lprocfs_add_simple);
2302 EXPORT_SYMBOL(lprocfs_add_symlink);
2303 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2304 EXPORT_SYMBOL(lprocfs_alloc_stats);
2305 EXPORT_SYMBOL(lprocfs_free_stats);
2306 EXPORT_SYMBOL(lprocfs_clear_stats);
2307 EXPORT_SYMBOL(lprocfs_register_stats);
2308 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2309 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2310 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2311 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2312 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2313 EXPORT_SYMBOL(lprocfs_free_md_stats);
2314 EXPORT_SYMBOL(lprocfs_exp_setup);
2315 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2317 EXPORT_SYMBOL(lprocfs_rd_u64);
2318 EXPORT_SYMBOL(lprocfs_rd_atomic);
2319 EXPORT_SYMBOL(lprocfs_wr_atomic);
2320 EXPORT_SYMBOL(lprocfs_rd_uint);
2321 EXPORT_SYMBOL(lprocfs_wr_uint);
2322 EXPORT_SYMBOL(lprocfs_rd_uuid);
2323 EXPORT_SYMBOL(lprocfs_rd_name);
2324 EXPORT_SYMBOL(lprocfs_rd_fstype);
2325 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2326 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2327 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2328 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2329 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2330 EXPORT_SYMBOL(lprocfs_rd_import);
2331 EXPORT_SYMBOL(lprocfs_rd_state);
2332 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2333 EXPORT_SYMBOL(lprocfs_rd_blksize);
2334 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2335 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2336 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2337 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2338 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2340 EXPORT_SYMBOL(lprocfs_write_helper);
2341 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2342 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2343 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2344 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2345 EXPORT_SYMBOL(lprocfs_stats_collect);