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 (c) 2002, 2010, Oracle and/or its affiliates. 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)) {
193 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
195 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
201 /* for lustre proc read, the read count must be less than PAGE_SIZE */
210 start = page + *ppos;
211 } else if (start < page) {
215 count = (rc < size) ? rc : size;
216 if (cfs_copy_to_user(buf, start, count)) {
223 free_page((unsigned long)page);
227 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
228 size_t size, loff_t *ppos)
230 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
233 if (LPROCFS_ENTRY_AND_CHECK(dp))
236 rc = dp->write_proc(f, buf, size, dp->data);
241 static struct file_operations lprocfs_generic_fops = {
242 .owner = THIS_MODULE,
243 .read = lprocfs_fops_read,
244 .write = lprocfs_fops_write,
247 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
249 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
250 struct obd_device *obd = dp->data;
252 cfs_atomic_inc(&obd->obd_evict_inprogress);
257 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
259 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
260 struct obd_device *obd = dp->data;
262 cfs_atomic_dec(&obd->obd_evict_inprogress);
263 cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
268 struct file_operations lprocfs_evict_client_fops = {
269 .owner = THIS_MODULE,
270 .read = lprocfs_fops_read,
271 .write = lprocfs_fops_write,
272 .open = lprocfs_evict_client_open,
273 .release = lprocfs_evict_client_release,
275 EXPORT_SYMBOL(lprocfs_evict_client_fops);
280 * \param root [in] The parent proc entry on which new entry will be added.
281 * \param list [in] Array of proc entries to be added.
282 * \param data [in] The argument to be passed when entries read/write routines
283 * are called through /proc file.
285 * \retval 0 on success
288 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
291 if (root == NULL || list == NULL)
294 while (list->name != NULL) {
295 struct proc_dir_entry *cur_root, *proc;
296 char *pathcopy, *cur, *next, pathbuf[64];
297 int pathsize = strlen(list->name) + 1;
302 /* need copy of path for strsep */
303 if (strlen(list->name) > sizeof(pathbuf) - 1) {
304 OBD_ALLOC(pathcopy, pathsize);
305 if (pathcopy == NULL)
312 strcpy(pathcopy, list->name);
314 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
315 if (*cur =='\0') /* skip double/trailing "/" */
318 proc = lprocfs_srch(cur_root, cur);
319 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
320 cur_root->name, cur, next,
321 (proc ? "exists" : "new"));
323 cur_root = (proc ? proc :
324 proc_mkdir(cur, cur_root));
325 } else if (proc == NULL) {
327 if (list->proc_mode != 0000) {
328 mode = list->proc_mode;
332 if (list->write_fptr)
335 proc = create_proc_entry(cur, mode, cur_root);
339 if (pathcopy != pathbuf)
340 OBD_FREE(pathcopy, pathsize);
342 if (cur_root == NULL || proc == NULL) {
343 CERROR("LprocFS: No memory to create /proc entry %s",
349 proc->proc_fops = list->fops;
351 proc->proc_fops = &lprocfs_generic_fops;
352 proc->read_proc = list->read_fptr;
353 proc->write_proc = list->write_fptr;
354 proc->data = (list->data ? list->data : data);
360 void lprocfs_remove(struct proc_dir_entry **rooth)
362 struct proc_dir_entry *root = *rooth;
363 struct proc_dir_entry *temp = root;
364 struct proc_dir_entry *rm_entry;
365 struct proc_dir_entry *parent;
371 parent = root->parent;
372 LASSERT(parent != NULL);
373 LPROCFS_WRITE_ENTRY(); /* search vs remove race */
376 while (temp->subdir != NULL)
382 /* Memory corruption once caused this to fail, and
383 without this LASSERT we would loop here forever. */
384 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
385 "0x%p %s/%s len %d\n", rm_entry, temp->name,
386 rm_entry->name, (int)strlen(rm_entry->name));
388 /* Now, the rm_entry->deleted flags is protected
389 * by _lprocfs_lock. */
390 rm_entry->data = NULL;
391 remove_proc_entry(rm_entry->name, temp);
395 LPROCFS_WRITE_EXIT();
398 void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
400 LASSERT(parent != NULL);
401 remove_proc_entry(name, parent);
404 struct proc_dir_entry *lprocfs_register(const char *name,
405 struct proc_dir_entry *parent,
406 struct lprocfs_vars *list, void *data)
408 struct proc_dir_entry *newchild;
410 newchild = lprocfs_srch(parent, name);
411 if (newchild != NULL) {
412 CERROR(" Lproc: Attempting to register %s more than once \n",
414 return ERR_PTR(-EALREADY);
417 newchild = proc_mkdir(name, parent);
418 if (newchild != NULL && list != NULL) {
419 int rc = lprocfs_add_vars(newchild, list, data);
421 lprocfs_remove(&newchild);
428 /* Generic callbacks */
429 int lprocfs_rd_uint(char *page, char **start, off_t off,
430 int count, int *eof, void *data)
432 unsigned int *temp = data;
433 return snprintf(page, count, "%u\n", *temp);
436 int lprocfs_wr_uint(struct file *file, const char *buffer,
437 unsigned long count, void *data)
440 char dummy[MAX_STRING_SIZE + 1], *end;
443 dummy[MAX_STRING_SIZE] = '\0';
444 if (cfs_copy_from_user(dummy, buffer, MAX_STRING_SIZE))
447 tmp = simple_strtoul(dummy, &end, 0);
451 *p = (unsigned int)tmp;
455 int lprocfs_rd_u64(char *page, char **start, off_t off,
456 int count, int *eof, void *data)
458 LASSERT(data != NULL);
460 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
463 int lprocfs_rd_atomic(char *page, char **start, off_t off,
464 int count, int *eof, void *data)
466 cfs_atomic_t *atom = data;
467 LASSERT(atom != NULL);
469 return snprintf(page, count, "%d\n", cfs_atomic_read(atom));
472 int lprocfs_wr_atomic(struct file *file, const char *buffer,
473 unsigned long count, void *data)
475 cfs_atomic_t *atm = data;
479 rc = lprocfs_write_helper(buffer, count, &val);
486 cfs_atomic_set(atm, val);
490 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
491 int *eof, void *data)
493 struct obd_device *obd = data;
495 LASSERT(obd != NULL);
497 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
500 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
501 int *eof, void *data)
503 struct obd_device *dev = data;
505 LASSERT(dev != NULL);
506 LASSERT(dev->obd_name != NULL);
508 return snprintf(page, count, "%s\n", dev->obd_name);
511 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
514 struct obd_device *obd = data;
516 LASSERT(obd != NULL);
517 LASSERT(obd->obd_fsops != NULL);
518 LASSERT(obd->obd_fsops->fs_type != NULL);
519 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
522 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
523 int *eof, void *data)
525 struct obd_statfs osfs;
526 int rc = obd_statfs(data, &osfs,
527 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
531 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
536 int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
537 int *eof, void *data)
539 struct obd_statfs osfs;
540 int rc = obd_statfs(data, &osfs,
541 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
544 __u32 blk_size = osfs.os_bsize >> 10;
545 __u64 result = osfs.os_blocks;
547 while (blk_size >>= 1)
551 rc = snprintf(page, count, LPU64"\n", result);
556 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
557 int *eof, void *data)
559 struct obd_statfs osfs;
560 int rc = obd_statfs(data, &osfs,
561 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
564 __u32 blk_size = osfs.os_bsize >> 10;
565 __u64 result = osfs.os_bfree;
567 while (blk_size >>= 1)
571 rc = snprintf(page, count, LPU64"\n", result);
576 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
577 int *eof, void *data)
579 struct obd_statfs osfs;
580 int rc = obd_statfs(data, &osfs,
581 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
584 __u32 blk_size = osfs.os_bsize >> 10;
585 __u64 result = osfs.os_bavail;
587 while (blk_size >>= 1)
591 rc = snprintf(page, count, LPU64"\n", result);
596 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
597 int *eof, void *data)
599 struct obd_statfs osfs;
600 int rc = obd_statfs(data, &osfs,
601 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
605 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
611 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
612 int *eof, void *data)
614 struct obd_statfs osfs;
615 int rc = obd_statfs(data, &osfs,
616 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
620 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
625 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
626 int *eof, void *data)
628 struct obd_device *obd = data;
629 struct obd_import *imp;
630 char *imp_state_name = NULL;
633 LASSERT(obd != NULL);
634 LPROCFS_CLIMP_CHECK(obd);
635 imp = obd->u.cli.cl_import;
636 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
638 rc = snprintf(page, count, "%s\t%s%s\n",
639 obd2cli_tgt(obd), imp_state_name,
640 imp->imp_deactive ? "\tDEACTIVATED" : "");
642 LPROCFS_CLIMP_EXIT(obd);
646 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
647 int *eof, void *data)
649 struct obd_device *obd = data;
650 struct ptlrpc_connection *conn;
653 LASSERT(obd != NULL);
655 LPROCFS_CLIMP_CHECK(obd);
656 conn = obd->u.cli.cl_import->imp_connection;
658 if (conn && obd->u.cli.cl_import) {
659 rc = snprintf(page, count, "%s\n",
660 conn->c_remote_uuid.uuid);
662 rc = snprintf(page, count, "%s\n", "<none>");
665 LPROCFS_CLIMP_EXIT(obd);
669 /** add up per-cpu counters */
670 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
671 struct lprocfs_counter *cnt)
673 unsigned int num_cpu;
674 struct lprocfs_counter t;
675 struct lprocfs_counter *percpu_cntr;
678 memset(cnt, 0, sizeof(*cnt));
681 /* set count to 1 to avoid divide-by-zero errs in callers */
686 cnt->lc_min = LC_MIN_INIT;
688 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
691 num_cpu = cfs_num_possible_cpus();
693 for (i = 0; i < num_cpu; i++) {
694 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
697 centry = cfs_atomic_read(&percpu_cntr-> \
699 t.lc_count = percpu_cntr->lc_count;
700 t.lc_sum = percpu_cntr->lc_sum;
701 t.lc_min = percpu_cntr->lc_min;
702 t.lc_max = percpu_cntr->lc_max;
703 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
704 } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
706 centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
708 cnt->lc_count += t.lc_count;
709 cnt->lc_sum += t.lc_sum;
710 if (t.lc_min < cnt->lc_min)
711 cnt->lc_min = t.lc_min;
712 if (t.lc_max > cnt->lc_max)
713 cnt->lc_max = t.lc_max;
714 cnt->lc_sumsquare += t.lc_sumsquare;
717 cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
721 * Append a space separated list of current set flags to str.
723 #define flag2str(flag) \
724 if (imp->imp_##flag && max - len > 0) \
725 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
726 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
730 if (imp->imp_obd->obd_no_recov)
731 len += snprintf(str, max - len, "no_recov");
735 flag2str(replayable);
741 static const char *obd_connect_names[] = {
755 "join_file(obsolete)",
759 "remote_client_by_force",
768 "mds_mds_connection",
771 "alt_checksum_algorithm",
783 static int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
788 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
790 ret += snprintf(page + ret, count - ret, "%s%s",
791 ret ? sep : "", obd_connect_names[i]);
793 if (flags & ~(mask - 1))
794 ret += snprintf(page + ret, count - ret,
795 "%sunknown flags "LPX64,
796 ret ? sep : "", flags & ~(mask - 1));
800 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
801 int *eof, void *data)
803 struct lprocfs_counter ret;
804 struct obd_device *obd = (struct obd_device *)data;
805 struct obd_import *imp;
806 struct obd_import_conn *conn;
809 LASSERT(obd != NULL);
810 LPROCFS_CLIMP_CHECK(obd);
811 imp = obd->u.cli.cl_import;
814 i = snprintf(page, count,
822 ptlrpc_import_state_name(imp->imp_state));
823 i += obd_connect_flags2str(page + i, count - i,
824 imp->imp_connect_data.ocd_connect_flags,
826 i += snprintf(page + i, count - i,
829 i += obd_import_flags2str(imp, page + i, count - i);
831 i += snprintf(page + i, count - i,
834 " failover_nids: [");
835 cfs_spin_lock(&imp->imp_lock);
837 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
838 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
839 libcfs_nid2str(conn->oic_conn->c_peer.nid));
842 cfs_spin_unlock(&imp->imp_lock);
843 i += snprintf(page + i, count - i,
845 " current_connection: %s\n"
846 " connection_attempts: %u\n"
848 " in-progress_invalidations: %u\n",
849 libcfs_nid2str(imp->imp_connection->c_peer.nid),
852 cfs_atomic_read(&imp->imp_inval_count));
854 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
855 if (ret.lc_count != 0)
856 do_div(ret.lc_sum, ret.lc_count);
859 i += snprintf(page + i, count - i,
862 " unregistering: %u\n"
864 " avg_waittime: "LPU64" %s\n",
865 cfs_atomic_read(&imp->imp_inflight),
866 cfs_atomic_read(&imp->imp_unregistering),
867 cfs_atomic_read(&imp->imp_timeouts),
868 ret.lc_sum, ret.lc_units);
871 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
872 if (imp->imp_at.iat_portal[j] == 0)
874 k = max_t(unsigned int, k,
875 at_get(&imp->imp_at.iat_service_estimate[j]));
877 i += snprintf(page + i, count - i,
878 " service_estimates:\n"
879 " services: %u sec\n"
880 " network: %u sec\n",
882 at_get(&imp->imp_at.iat_net_latency));
884 i += snprintf(page + i, count - i,
886 " last_replay: "LPU64"\n"
887 " peer_committed: "LPU64"\n"
888 " last_checked: "LPU64"\n",
889 imp->imp_last_replay_transno,
890 imp->imp_peer_committed_transno,
891 imp->imp_last_transno_checked);
894 for (rw = 0; rw <= 1; rw++) {
895 lprocfs_stats_collect(obd->obd_svc_stats,
896 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
898 if (ret.lc_sum > 0 && ret.lc_count > 0) {
899 do_div(ret.lc_sum, ret.lc_count);
900 i += snprintf(page + i, count - i,
901 " %s_data_averages:\n"
902 " bytes_per_rpc: "LPU64"\n",
903 rw ? "write" : "read",
907 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
908 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
909 if (ret.lc_sum > 0 && ret.lc_count != 0) {
910 do_div(ret.lc_sum, ret.lc_count);
911 i += snprintf(page + i, count - i,
912 " %s_per_rpc: "LPU64"\n",
913 ret.lc_units, ret.lc_sum);
916 i += snprintf(page + i, count - i,
917 " MB_per_sec: %u.%.02u\n",
918 k / j, (100 * k / j) % 100);
922 LPROCFS_CLIMP_EXIT(obd);
926 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
927 int *eof, void *data)
929 struct obd_device *obd = (struct obd_device *)data;
930 struct obd_import *imp;
933 LASSERT(obd != NULL);
934 LPROCFS_CLIMP_CHECK(obd);
935 imp = obd->u.cli.cl_import;
938 i = snprintf(page, count, "current_state: %s\n",
939 ptlrpc_import_state_name(imp->imp_state));
940 i += snprintf(page + i, count - i,
942 k = imp->imp_state_hist_idx;
943 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
944 struct import_state_hist *ish =
945 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
946 if (ish->ish_state == 0)
948 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
950 ptlrpc_import_state_name(ish->ish_state));
953 LPROCFS_CLIMP_EXIT(obd);
957 int lprocfs_at_hist_helper(char *page, int count, int rc,
958 struct adaptive_timeout *at)
961 for (i = 0; i < AT_BINS; i++)
962 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
963 rc += snprintf(page + rc, count - rc, "\n");
967 /* See also ptlrpc_lprocfs_rd_timeouts */
968 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
969 int *eof, void *data)
971 struct obd_device *obd = (struct obd_device *)data;
972 struct obd_import *imp;
973 unsigned int cur, worst;
978 LASSERT(obd != NULL);
979 LPROCFS_CLIMP_CHECK(obd);
980 imp = obd->u.cli.cl_import;
983 now = cfs_time_current_sec();
985 /* Some network health info for kicks */
986 s2dhms(&ts, now - imp->imp_last_reply_time);
987 rc += snprintf(page + rc, count - rc,
988 "%-10s : %ld, "DHMS_FMT" ago\n",
989 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
991 cur = at_get(&imp->imp_at.iat_net_latency);
992 worst = imp->imp_at.iat_net_latency.at_worst_ever;
993 worstt = imp->imp_at.iat_net_latency.at_worst_time;
994 s2dhms(&ts, now - worstt);
995 rc += snprintf(page + rc, count - rc,
996 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
997 "network", cur, worst, worstt, DHMS_VARS(&ts));
998 rc = lprocfs_at_hist_helper(page, count, rc,
999 &imp->imp_at.iat_net_latency);
1001 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1002 if (imp->imp_at.iat_portal[i] == 0)
1004 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1005 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1006 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1007 s2dhms(&ts, now - worstt);
1008 rc += snprintf(page + rc, count - rc,
1009 "portal %-2d : cur %3u worst %3u (at %ld, "
1010 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1011 cur, worst, worstt, DHMS_VARS(&ts));
1012 rc = lprocfs_at_hist_helper(page, count, rc,
1013 &imp->imp_at.iat_service_estimate[i]);
1016 LPROCFS_CLIMP_EXIT(obd);
1020 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1021 int count, int *eof, void *data)
1023 struct obd_device *obd = data;
1027 LPROCFS_CLIMP_CHECK(obd);
1028 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1029 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1030 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1031 ret += snprintf(page + ret, count - ret, "\n");
1032 LPROCFS_CLIMP_EXIT(obd);
1035 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1037 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1038 int *eof, void *data)
1040 struct obd_device *obd = data;
1042 LASSERT(obd != NULL);
1044 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1047 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1048 int *eof, void *data)
1050 struct obd_type *class = (struct obd_type*) data;
1052 LASSERT(class != NULL);
1054 return snprintf(page, count, "%d\n", class->typ_refcnt);
1057 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1061 LASSERT(obd != NULL);
1062 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1063 LASSERT(obd->obd_type->typ_procroot != NULL);
1065 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1066 obd->obd_type->typ_procroot,
1068 if (IS_ERR(obd->obd_proc_entry)) {
1069 rc = PTR_ERR(obd->obd_proc_entry);
1070 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1071 obd->obd_proc_entry = NULL;
1076 int lprocfs_obd_cleanup(struct obd_device *obd)
1080 if (obd->obd_proc_exports_entry) {
1081 /* Should be no exports left */
1082 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1083 lprocfs_remove(&obd->obd_proc_exports_entry);
1084 obd->obd_proc_exports_entry = NULL;
1086 if (obd->obd_proc_entry) {
1087 lprocfs_remove(&obd->obd_proc_entry);
1088 obd->obd_proc_entry = NULL;
1093 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1095 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1096 client_stat->nid_proc, client_stat->nid_stats,
1097 client_stat->nid_brw_stats);
1099 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1101 cfs_atomic_read(&client_stat->nid_exp_ref_count));
1103 cfs_hlist_del_init(&client_stat->nid_hash);
1105 if (client_stat->nid_proc)
1106 lprocfs_remove(&client_stat->nid_proc);
1108 if (client_stat->nid_stats)
1109 lprocfs_free_stats(&client_stat->nid_stats);
1111 if (client_stat->nid_brw_stats)
1112 OBD_FREE_PTR(client_stat->nid_brw_stats);
1114 if (client_stat->nid_ldlm_stats)
1115 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1117 OBD_FREE_PTR(client_stat);
1122 void lprocfs_free_per_client_stats(struct obd_device *obd)
1124 struct nid_stat *stat;
1127 /* we need extra list - because hash_exit called to early */
1128 /* not need locking because all clients is died */
1129 while(!cfs_list_empty(&obd->obd_nid_stats)) {
1130 stat = cfs_list_entry(obd->obd_nid_stats.next,
1131 struct nid_stat, nid_list);
1132 cfs_list_del_init(&stat->nid_list);
1133 lprocfs_free_client_stats(stat);
1139 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1140 enum lprocfs_stats_flags flags)
1142 struct lprocfs_stats *stats;
1143 unsigned int percpusize;
1145 unsigned int num_cpu;
1150 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1153 num_cpu = cfs_num_possible_cpus();
1155 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1159 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1160 stats->ls_flags = flags;
1161 cfs_spin_lock_init(&stats->ls_lock);
1162 /* Use this lock only if there are no percpu areas */
1164 stats->ls_flags = 0;
1167 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1169 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1171 for (i = 0; i < num_cpu; i++) {
1172 OBD_ALLOC(stats->ls_percpu[i], percpusize);
1173 if (stats->ls_percpu[i] == NULL) {
1174 for (j = 0; j < i; j++) {
1175 OBD_FREE(stats->ls_percpu[j], percpusize);
1176 stats->ls_percpu[j] = NULL;
1181 if (stats->ls_percpu[0] == NULL) {
1182 OBD_FREE(stats, offsetof(typeof(*stats),
1183 ls_percpu[num_cpu]));
1187 stats->ls_num = num;
1191 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1193 struct lprocfs_stats *stats = *statsh;
1194 unsigned int num_cpu;
1195 unsigned int percpusize;
1198 if (stats == NULL || stats->ls_num == 0)
1202 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1205 num_cpu = cfs_num_possible_cpus();
1207 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1209 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1210 for (i = 0; i < num_cpu; i++)
1211 OBD_FREE(stats->ls_percpu[i], percpusize);
1212 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1215 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1217 struct lprocfs_counter *percpu_cntr;
1219 unsigned int num_cpu;
1221 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1223 for (i = 0; i < num_cpu; i++) {
1224 for (j = 0; j < stats->ls_num; j++) {
1225 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1226 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1227 percpu_cntr->lc_count = 0;
1228 percpu_cntr->lc_sum = 0;
1229 percpu_cntr->lc_min = LC_MIN_INIT;
1230 percpu_cntr->lc_max = 0;
1231 percpu_cntr->lc_sumsquare = 0;
1232 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1236 lprocfs_stats_unlock(stats);
1239 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1240 size_t len, loff_t *off)
1242 struct seq_file *seq = file->private_data;
1243 struct lprocfs_stats *stats = seq->private;
1245 lprocfs_clear_stats(stats);
1250 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1252 struct lprocfs_stats *stats = p->private;
1253 /* return 1st cpu location */
1254 return (*pos >= stats->ls_num) ? NULL :
1255 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1258 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1262 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1264 struct lprocfs_stats *stats = p->private;
1266 return (*pos >= stats->ls_num) ? NULL :
1267 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1270 /* seq file export of one lprocfs counter */
1271 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1273 struct lprocfs_stats *stats = p->private;
1274 struct lprocfs_counter *cntr = v;
1275 struct lprocfs_counter ret;
1278 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1280 cfs_gettimeofday(&now);
1281 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1282 "snapshot_time", now.tv_sec, now.tv_usec);
1286 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1288 lprocfs_stats_collect(stats, idx, &ret);
1290 if (ret.lc_count == 0)
1293 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1294 ret.lc_count, cntr->lc_units);
1299 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1300 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1301 ret.lc_min, ret.lc_max, ret.lc_sum);
1304 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1305 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1309 rc = seq_printf(p, "\n");
1311 return (rc < 0) ? rc : 0;
1314 struct seq_operations lprocfs_stats_seq_sops = {
1315 start: lprocfs_stats_seq_start,
1316 stop: lprocfs_stats_seq_stop,
1317 next: lprocfs_stats_seq_next,
1318 show: lprocfs_stats_seq_show,
1321 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1323 struct proc_dir_entry *dp = PDE(inode);
1324 struct seq_file *seq;
1327 if (LPROCFS_ENTRY_AND_CHECK(dp))
1330 rc = seq_open(file, &lprocfs_stats_seq_sops);
1335 seq = file->private_data;
1336 seq->private = dp->data;
1340 struct file_operations lprocfs_stats_seq_fops = {
1341 .owner = THIS_MODULE,
1342 .open = lprocfs_stats_seq_open,
1344 .write = lprocfs_stats_seq_write,
1345 .llseek = seq_lseek,
1346 .release = lprocfs_seq_release,
1349 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1350 struct lprocfs_stats *stats)
1352 struct proc_dir_entry *entry;
1353 LASSERT(root != NULL);
1355 entry = create_proc_entry(name, 0644, root);
1358 entry->proc_fops = &lprocfs_stats_seq_fops;
1359 entry->data = stats;
1363 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1364 unsigned conf, const char *name, const char *units)
1366 struct lprocfs_counter *c;
1368 unsigned int num_cpu;
1370 LASSERT(stats != NULL);
1372 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1374 for (i = 0; i < num_cpu; i++) {
1375 c = &(stats->ls_percpu[i]->lp_cntr[index]);
1376 c->lc_config = conf;
1379 c->lc_min = LC_MIN_INIT;
1382 c->lc_units = units;
1385 lprocfs_stats_unlock(stats);
1387 EXPORT_SYMBOL(lprocfs_counter_init);
1389 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1391 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1392 LASSERT(coffset < stats->ls_num); \
1393 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1396 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1398 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1399 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1400 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1401 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1402 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1403 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1404 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1405 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1406 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1407 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1408 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1409 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1410 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1411 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1412 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1413 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1414 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1415 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1416 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1417 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1418 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1419 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1420 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1421 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1422 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1423 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1424 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1425 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1426 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1427 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1428 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1429 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1430 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1431 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1432 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1433 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1434 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1435 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1436 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1437 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1438 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1439 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1440 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1441 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1442 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1443 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1444 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1445 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1446 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1447 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1448 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1449 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1450 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1451 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1452 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1453 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1454 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1455 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1456 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1457 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1458 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1459 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1460 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1461 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1462 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1463 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1469 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1471 struct lprocfs_stats *stats;
1472 unsigned int num_stats;
1475 LASSERT(obd->obd_stats == NULL);
1476 LASSERT(obd->obd_proc_entry != NULL);
1477 LASSERT(obd->obd_cntr_base == 0);
1479 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1480 num_private_stats - 1 /* o_owner */;
1481 stats = lprocfs_alloc_stats(num_stats, 0);
1485 lprocfs_init_ops_stats(num_private_stats, stats);
1487 for (i = num_private_stats; i < num_stats; i++) {
1488 /* If this LBUGs, it is likely that an obd
1489 * operation was added to struct obd_ops in
1490 * <obd.h>, and that the corresponding line item
1491 * LPROCFS_OBD_OP_INIT(.., .., opname)
1492 * is missing from the list above. */
1493 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1494 "Missing obd_stat initializer obd_op "
1495 "operation at offset %d.\n", i - num_private_stats);
1497 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1499 lprocfs_free_stats(&stats);
1501 obd->obd_stats = stats;
1502 obd->obd_cntr_base = num_private_stats;
1507 void lprocfs_free_obd_stats(struct obd_device *obd)
1510 lprocfs_free_stats(&obd->obd_stats);
1513 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1515 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1516 LASSERT(coffset < stats->ls_num); \
1517 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1520 int lprocfs_alloc_md_stats(struct obd_device *obd,
1521 unsigned num_private_stats)
1523 struct lprocfs_stats *stats;
1524 unsigned int num_stats;
1527 LASSERT(obd->md_stats == NULL);
1528 LASSERT(obd->obd_proc_entry != NULL);
1529 LASSERT(obd->md_cntr_base == 0);
1531 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1533 stats = lprocfs_alloc_stats(num_stats, 0);
1537 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1538 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1539 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1540 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1541 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1542 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1543 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1544 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1545 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1546 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1547 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1548 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1549 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1550 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1551 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1552 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1553 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1554 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1555 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1556 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1557 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1558 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1559 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1560 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1561 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1562 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1563 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1564 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1565 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1566 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1567 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1568 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1570 for (i = num_private_stats; i < num_stats; i++) {
1571 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1572 CERROR("Missing md_stat initializer md_op "
1573 "operation at offset %d. Aborting.\n",
1574 i - num_private_stats);
1578 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1580 lprocfs_free_stats(&stats);
1582 obd->md_stats = stats;
1583 obd->md_cntr_base = num_private_stats;
1588 void lprocfs_free_md_stats(struct obd_device *obd)
1590 struct lprocfs_stats *stats = obd->md_stats;
1592 if (stats != NULL) {
1593 obd->md_stats = NULL;
1594 obd->md_cntr_base = 0;
1595 lprocfs_free_stats(&stats);
1599 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1601 lprocfs_counter_init(ldlm_stats,
1602 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1603 0, "ldlm_enqueue", "reqs");
1604 lprocfs_counter_init(ldlm_stats,
1605 LDLM_CONVERT - LDLM_FIRST_OPC,
1606 0, "ldlm_convert", "reqs");
1607 lprocfs_counter_init(ldlm_stats,
1608 LDLM_CANCEL - LDLM_FIRST_OPC,
1609 0, "ldlm_cancel", "reqs");
1610 lprocfs_counter_init(ldlm_stats,
1611 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1612 0, "ldlm_bl_callback", "reqs");
1613 lprocfs_counter_init(ldlm_stats,
1614 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1615 0, "ldlm_cp_callback", "reqs");
1616 lprocfs_counter_init(ldlm_stats,
1617 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1618 0, "ldlm_gl_callback", "reqs");
1621 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1622 int *eof, void *data)
1624 struct obd_export *exp = data;
1625 LASSERT(exp != NULL);
1627 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1630 struct exp_uuid_cb_data {
1638 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1639 int count, int *eof, int *len)
1641 cb_data->page = page;
1642 cb_data->count = count;
1647 void lprocfs_exp_print_uuid(void *obj, void *cb_data)
1649 struct obd_export *exp = (struct obd_export *)obj;
1650 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1652 if (exp->exp_nid_stats)
1653 *data->len += snprintf((data->page + *data->len),
1654 data->count, "%s\n",
1655 obd_uuid2str(&exp->exp_client_uuid));
1658 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1659 int *eof, void *data)
1661 struct nid_stat *stats = (struct nid_stat *)data;
1662 struct exp_uuid_cb_data cb_data;
1663 struct obd_device *obd = stats->nid_obd;
1668 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1669 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1670 lprocfs_exp_print_uuid, &cb_data);
1671 return (*cb_data.len);
1674 void lprocfs_exp_print_hash(void *obj, void *cb_data)
1676 struct exp_uuid_cb_data *data = cb_data;
1677 struct obd_export *exp = obj;
1680 hs = exp->exp_lock_hash;
1683 *data->len += cfs_hash_debug_header(data->page,
1686 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1691 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1692 int *eof, void *data)
1694 struct nid_stat *stats = (struct nid_stat *)data;
1695 struct exp_uuid_cb_data cb_data;
1696 struct obd_device *obd = stats->nid_obd;
1701 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1703 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1704 lprocfs_exp_print_hash, &cb_data);
1705 return (*cb_data.len);
1708 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1709 int count, int *eof, void *data)
1712 return snprintf(page, count, "%s\n",
1713 "Write into this file to clear all nid stats and "
1714 "stale nid entries");
1716 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1718 int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1720 struct nid_stat *stat = obj;
1723 /* object has only hash + iterate_all references.
1724 * add/delete blocked by hash bucket lock */
1725 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1726 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 2) {
1727 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1728 cfs_list_move(&stat->nid_list, data);
1729 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1732 /* we has reference to object - only clear data*/
1733 if (stat->nid_stats)
1734 lprocfs_clear_stats(stat->nid_stats);
1736 if (stat->nid_brw_stats) {
1737 for (i = 0; i < BRW_LAST; i++)
1738 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1743 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1744 unsigned long count, void *data)
1746 struct obd_device *obd = (struct obd_device *)data;
1747 struct nid_stat *client_stat;
1748 CFS_LIST_HEAD(free_list);
1750 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1751 lprocfs_nid_stats_clear_write_cb, &free_list);
1753 while (!cfs_list_empty(&free_list)) {
1754 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1756 cfs_list_del_init(&client_stat->nid_list);
1757 lprocfs_free_client_stats(client_stat);
1762 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1764 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1766 struct nid_stat *new_stat, *old_stat;
1767 struct obd_device *obd = NULL;
1768 cfs_proc_dir_entry_t *entry;
1769 char *buffer = NULL;
1775 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1776 !exp->exp_obd->obd_nid_stats_hash)
1779 /* not test against zero because eric say:
1780 * You may only test nid against another nid, or LNET_NID_ANY.
1781 * Anything else is nonsense.*/
1782 if (!nid || *nid == LNET_NID_ANY)
1787 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1789 OBD_ALLOC_PTR(new_stat);
1790 if (new_stat == NULL)
1793 new_stat->nid = *nid;
1794 new_stat->nid_obd = exp->exp_obd;
1795 cfs_atomic_set(&new_stat->nid_exp_ref_count, 0);
1797 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1798 nid, &new_stat->nid_hash);
1799 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1800 old_stat, libcfs_nid2str(*nid),
1801 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1803 /* Return -EALREADY here so that we know that the /proc
1804 * entry already has been created */
1805 if (old_stat != new_stat) {
1806 cfs_spin_lock(&obd->obd_nid_lock);
1807 if (exp->exp_nid_stats != old_stat) {
1808 if (exp->exp_nid_stats)
1809 nidstat_putref(exp->exp_nid_stats);
1810 exp->exp_nid_stats = old_stat;
1812 /* cfs_hash_findadd_unique() has added
1813 * old_stat's refcount */
1814 nidstat_putref(old_stat);
1817 cfs_spin_unlock(&obd->obd_nid_lock);
1819 GOTO(destroy_new, rc = -EALREADY);
1821 /* not found - create */
1822 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1824 GOTO(destroy_new, rc = -ENOMEM);
1826 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1827 new_stat->nid_proc = lprocfs_register(buffer,
1828 obd->obd_proc_exports_entry,
1830 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1832 if (new_stat->nid_proc == NULL) {
1833 CERROR("Error making export directory for nid %s\n",
1834 libcfs_nid2str(*nid));
1835 GOTO(destroy_new_ns, rc = -ENOMEM);
1838 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1839 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1840 if (IS_ERR(entry)) {
1841 CWARN("Error adding the NID stats file\n");
1842 rc = PTR_ERR(entry);
1843 GOTO(destroy_new_ns, rc);
1846 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1847 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1848 if (IS_ERR(entry)) {
1849 CWARN("Error adding the hash file\n");
1850 rc = PTR_ERR(entry);
1851 GOTO(destroy_new_ns, rc);
1854 if (exp->exp_nid_stats)
1855 nidstat_putref(exp->exp_nid_stats);
1856 nidstat_getref(new_stat);
1857 exp->exp_nid_stats = new_stat;
1859 /* protect competitive add to list, not need locking on destroy */
1860 cfs_spin_lock(&obd->obd_nid_lock);
1861 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1862 cfs_spin_unlock(&obd->obd_nid_lock);
1867 if (new_stat->nid_proc != NULL)
1868 lprocfs_remove(&new_stat->nid_proc);
1869 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1872 OBD_FREE_PTR(new_stat);
1876 int lprocfs_exp_cleanup(struct obd_export *exp)
1878 struct nid_stat *stat = exp->exp_nid_stats;
1880 if(!stat || !exp->exp_obd)
1883 nidstat_putref(exp->exp_nid_stats);
1884 exp->exp_nid_stats = NULL;
1889 int lprocfs_write_helper(const char *buffer, unsigned long count,
1892 return lprocfs_write_frac_helper(buffer, count, val, 1);
1895 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1898 char kernbuf[20], *end, *pbuf;
1900 if (count > (sizeof(kernbuf) - 1))
1903 if (cfs_copy_from_user(kernbuf, buffer, count))
1906 kernbuf[count] = '\0';
1913 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1917 if (end != NULL && *end == '.') {
1918 int temp_val, pow = 1;
1922 if (strlen(pbuf) > 5)
1923 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1925 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1928 for (i = 0; i < (end - pbuf); i++)
1931 *val += temp_val / pow;
1937 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
1940 long decimal_val, frac_val;
1946 decimal_val = val / mult;
1947 prtn = snprintf(buffer, count, "%ld", decimal_val);
1948 frac_val = val % mult;
1950 if (prtn < (count - 4) && frac_val > 0) {
1952 int i, temp_mult = 1, frac_bits = 0;
1954 temp_frac = frac_val * 10;
1955 buffer[prtn++] = '.';
1956 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
1957 /* only reserved 2 bits fraction */
1958 buffer[prtn++] ='0';
1963 * Need to think these cases :
1964 * 1. #echo x.00 > /proc/xxx output result : x
1965 * 2. #echo x.0x > /proc/xxx output result : x.0x
1966 * 3. #echo x.x0 > /proc/xxx output result : x.x
1967 * 4. #echo x.xx > /proc/xxx output result : x.xx
1968 * Only reserved 2 bits fraction.
1970 for (i = 0; i < (5 - prtn); i++)
1973 frac_bits = min((int)count - prtn, 3 - frac_bits);
1974 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
1975 frac_val * temp_mult / mult);
1978 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
1980 if (buffer[prtn] == '.') {
1987 buffer[prtn++] ='\n';
1991 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
1993 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
1996 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
1997 __u64 *val, int mult)
1999 char kernbuf[22], *end, *pbuf;
2000 __u64 whole, frac = 0, units;
2001 unsigned frac_d = 1;
2003 if (count > (sizeof(kernbuf) - 1))
2006 if (cfs_copy_from_user(kernbuf, buffer, count))
2009 kernbuf[count] = '\0';
2016 whole = simple_strtoull(pbuf, &end, 10);
2020 if (end != NULL && *end == '.') {
2024 /* need to limit frac_d to a __u32 */
2025 if (strlen(pbuf) > 10)
2028 frac = simple_strtoull(pbuf, &end, 10);
2029 /* count decimal places */
2030 for (i = 0; i < (end - pbuf); i++)
2047 /* Specified units override the multiplier */
2049 mult = mult < 0 ? -units : units;
2052 do_div(frac, frac_d);
2053 *val = whole * mult + frac;
2057 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2058 struct file_operations *seq_fops, void *data)
2060 struct proc_dir_entry *entry;
2063 entry = create_proc_entry(name, mode, parent);
2066 entry->proc_fops = seq_fops;
2071 EXPORT_SYMBOL(lprocfs_seq_create);
2073 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2075 struct file_operations *seq_fops,
2078 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2079 mode, seq_fops, data));
2081 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2083 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2085 if (value >= OBD_HIST_MAX)
2086 value = OBD_HIST_MAX - 1;
2088 cfs_spin_lock(&oh->oh_lock);
2089 oh->oh_buckets[value]++;
2090 cfs_spin_unlock(&oh->oh_lock);
2092 EXPORT_SYMBOL(lprocfs_oh_tally);
2094 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2098 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2101 lprocfs_oh_tally(oh, val);
2103 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2105 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2107 unsigned long ret = 0;
2110 for (i = 0; i < OBD_HIST_MAX; i++)
2111 ret += oh->oh_buckets[i];
2114 EXPORT_SYMBOL(lprocfs_oh_sum);
2116 void lprocfs_oh_clear(struct obd_histogram *oh)
2118 cfs_spin_lock(&oh->oh_lock);
2119 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2120 cfs_spin_unlock(&oh->oh_lock);
2122 EXPORT_SYMBOL(lprocfs_oh_clear);
2124 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2125 int count, int *eof, void *data)
2127 struct obd_device *obd = data;
2133 c += cfs_hash_debug_header(page, count);
2134 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2135 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2136 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2140 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2142 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2143 int count, int *eof, void *data)
2145 struct obd_device *obd = data;
2148 LASSERT(obd != NULL);
2149 LASSERT(count >= 0);
2151 /* Set start of user data returned to
2152 page + off since the user may have
2153 requested to read much smaller than
2154 what we need to read */
2155 *start = page + off;
2157 /* We know we are allocated a page here.
2158 Also we know that this function will
2159 not need to write more than a page
2160 so we can truncate at CFS_PAGE_SIZE. */
2161 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2163 /* Initialize the page */
2164 memset(page, 0, size);
2166 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2168 if (obd->obd_max_recoverable_clients == 0) {
2169 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2175 /* sampled unlocked, but really... */
2176 if (obd->obd_recovering == 0) {
2177 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2179 if (lprocfs_obd_snprintf(&page, size, &len,
2180 "recovery_start: %lu\n",
2181 obd->obd_recovery_start) <= 0)
2183 if (lprocfs_obd_snprintf(&page, size, &len,
2184 "recovery_duration: %lu\n",
2185 obd->obd_recovery_end -
2186 obd->obd_recovery_start) <= 0)
2188 /* Number of clients that have completed recovery */
2189 if (lprocfs_obd_snprintf(&page, size, &len,
2190 "completed_clients: %d/%d\n",
2191 obd->obd_max_recoverable_clients -
2192 obd->obd_stale_clients,
2193 obd->obd_max_recoverable_clients) <= 0)
2195 if (lprocfs_obd_snprintf(&page, size, &len,
2196 "replayed_requests: %d\n",
2197 obd->obd_replayed_requests) <= 0)
2199 if (lprocfs_obd_snprintf(&page, size, &len,
2200 "last_transno: "LPD64"\n",
2201 obd->obd_next_recovery_transno - 1)<=0)
2203 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2204 obd->obd_version_recov ? "ON" : "OFF")<=0)
2209 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2211 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2212 obd->obd_recovery_start) <= 0)
2214 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2215 cfs_time_current_sec() >= obd->obd_recovery_end ? 0 :
2216 obd->obd_recovery_end - cfs_time_current_sec()) <= 0)
2218 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2219 obd->obd_connected_clients,
2220 obd->obd_max_recoverable_clients) <= 0)
2222 /* Number of clients that have completed recovery */
2223 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2224 cfs_atomic_read(&obd->obd_req_replay_clients))
2227 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2228 cfs_atomic_read(&obd->obd_lock_replay_clients))
2231 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2232 obd->obd_connected_clients -
2233 cfs_atomic_read(&obd->obd_lock_replay_clients))
2236 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2237 obd->obd_stale_clients) <= 0)
2239 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2240 obd->obd_replayed_requests) <= 0)
2242 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2243 obd->obd_requests_queued_for_recovery) <= 0)
2246 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2247 obd->obd_next_recovery_transno) <= 0)
2253 return min(count, len - (int)off);
2255 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2257 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2258 int count, int *eof, void *data)
2260 struct obd_device *obd = (struct obd_device *)data;
2261 LASSERT(obd != NULL);
2263 return snprintf(page, count, "%d\n",
2264 obd->obd_recovery_timeout);
2266 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2268 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2269 unsigned long count, void *data)
2271 struct obd_device *obd = (struct obd_device *)data;
2273 LASSERT(obd != NULL);
2275 rc = lprocfs_write_helper(buffer, count, &val);
2279 obd->obd_recovery_timeout = val;
2282 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2284 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2285 int count, int *eof, void *data)
2287 struct obd_device *obd = data;
2288 LASSERT(obd != NULL);
2290 return snprintf(page, count, "%lu\n", obd->obd_recovery_time_hard);
2292 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2294 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2295 unsigned long count, void *data)
2297 struct obd_device *obd = data;
2299 LASSERT(obd != NULL);
2301 rc = lprocfs_write_helper(buffer, count, &val);
2305 obd->obd_recovery_time_hard = val;
2308 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2310 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2311 int count, int *eof, void *data)
2313 struct obd_device *obd = (struct obd_device *)data;
2315 LASSERT(obd != NULL);
2316 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2318 return snprintf(page, count, "%s\n",
2319 obd->u.obt.obt_vfsmnt->mnt_devname);
2321 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2323 EXPORT_SYMBOL(lprocfs_register);
2324 EXPORT_SYMBOL(lprocfs_srch);
2325 EXPORT_SYMBOL(lprocfs_remove);
2326 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2327 EXPORT_SYMBOL(lprocfs_add_vars);
2328 EXPORT_SYMBOL(lprocfs_obd_setup);
2329 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2330 EXPORT_SYMBOL(lprocfs_add_simple);
2331 EXPORT_SYMBOL(lprocfs_add_symlink);
2332 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2333 EXPORT_SYMBOL(lprocfs_alloc_stats);
2334 EXPORT_SYMBOL(lprocfs_free_stats);
2335 EXPORT_SYMBOL(lprocfs_clear_stats);
2336 EXPORT_SYMBOL(lprocfs_register_stats);
2337 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2338 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2339 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2340 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2341 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2342 EXPORT_SYMBOL(lprocfs_free_md_stats);
2343 EXPORT_SYMBOL(lprocfs_exp_setup);
2344 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2346 EXPORT_SYMBOL(lprocfs_rd_u64);
2347 EXPORT_SYMBOL(lprocfs_rd_atomic);
2348 EXPORT_SYMBOL(lprocfs_wr_atomic);
2349 EXPORT_SYMBOL(lprocfs_rd_uint);
2350 EXPORT_SYMBOL(lprocfs_wr_uint);
2351 EXPORT_SYMBOL(lprocfs_rd_uuid);
2352 EXPORT_SYMBOL(lprocfs_rd_name);
2353 EXPORT_SYMBOL(lprocfs_rd_fstype);
2354 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2355 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2356 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2357 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2358 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2359 EXPORT_SYMBOL(lprocfs_rd_import);
2360 EXPORT_SYMBOL(lprocfs_rd_state);
2361 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2362 EXPORT_SYMBOL(lprocfs_rd_blksize);
2363 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2364 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2365 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2366 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2367 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2369 EXPORT_SYMBOL(lprocfs_write_helper);
2370 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2371 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2372 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2373 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2374 EXPORT_SYMBOL(lprocfs_stats_collect);