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 static struct proc_dir_entry *__lprocfs_srch(struct proc_dir_entry *head,
74 struct proc_dir_entry *temp;
80 while (temp != NULL) {
81 if (strcmp(temp->name, name) == 0) {
90 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
93 struct proc_dir_entry *temp;
96 temp = __lprocfs_srch(head, name);
101 /* lprocfs API calls */
103 /* Function that emulates snprintf but also has the side effect of advancing
104 the page pointer for the next write into the buffer, incrementing the total
105 length written to the buffer, and decrementing the size left in the
107 static int lprocfs_obd_snprintf(char **page, int end, int *len,
108 const char *format, ...)
116 va_start(list, format);
117 n = vsnprintf(*page, end - *len, format, list);
120 *page += n; *len += n;
124 cfs_proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
126 read_proc_t *read_proc,
127 write_proc_t *write_proc,
129 struct file_operations *fops)
131 cfs_proc_dir_entry_t *proc;
134 if (root == NULL || name == NULL)
135 return ERR_PTR(-EINVAL);
142 LPROCFS_WRITE_ENTRY();
143 proc = create_proc_entry(name, mode, root);
145 CERROR("LprocFS: No memory to create /proc entry %s", name);
146 LPROCFS_WRITE_EXIT();
147 return ERR_PTR(-ENOMEM);
149 proc->read_proc = read_proc;
150 proc->write_proc = write_proc;
153 proc->proc_fops = fops;
154 LPROCFS_WRITE_EXIT();
158 struct proc_dir_entry *lprocfs_add_symlink(const char *name,
159 struct proc_dir_entry *parent, const char *format, ...)
161 struct proc_dir_entry *entry;
165 if (parent == NULL || format == NULL)
168 OBD_ALLOC_WAIT(dest, MAX_STRING_SIZE + 1);
172 va_start(ap, format);
173 vsnprintf(dest, MAX_STRING_SIZE, format, ap);
176 entry = proc_symlink(name, parent, dest);
178 CERROR("LprocFS: Could not create symbolic link from %s to %s",
181 OBD_FREE(dest, MAX_STRING_SIZE + 1);
185 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
186 size_t size, loff_t *ppos)
188 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
189 char *page, *start = NULL;
190 int rc = 0, eof = 1, count;
192 if (*ppos >= CFS_PAGE_SIZE)
195 page = (char *)__get_free_page(GFP_KERNEL);
199 if (LPROCFS_ENTRY_AND_CHECK(dp)) {
204 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
206 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
212 /* for lustre proc read, the read count must be less than PAGE_SIZE */
221 start = page + *ppos;
222 } else if (start < page) {
226 count = (rc < size) ? rc : size;
227 if (cfs_copy_to_user(buf, start, count)) {
234 free_page((unsigned long)page);
238 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
239 size_t size, loff_t *ppos)
241 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
244 if (LPROCFS_ENTRY_AND_CHECK(dp))
247 rc = dp->write_proc(f, buf, size, dp->data);
252 static struct file_operations lprocfs_generic_fops = {
253 .owner = THIS_MODULE,
254 .read = lprocfs_fops_read,
255 .write = lprocfs_fops_write,
258 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
260 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
261 struct obd_device *obd = dp->data;
263 cfs_atomic_inc(&obd->obd_evict_inprogress);
268 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
270 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
271 struct obd_device *obd = dp->data;
273 cfs_atomic_dec(&obd->obd_evict_inprogress);
274 cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
279 struct file_operations lprocfs_evict_client_fops = {
280 .owner = THIS_MODULE,
281 .read = lprocfs_fops_read,
282 .write = lprocfs_fops_write,
283 .open = lprocfs_evict_client_open,
284 .release = lprocfs_evict_client_release,
286 EXPORT_SYMBOL(lprocfs_evict_client_fops);
291 * \param root [in] The parent proc entry on which new entry will be added.
292 * \param list [in] Array of proc entries to be added.
293 * \param data [in] The argument to be passed when entries read/write routines
294 * are called through /proc file.
296 * \retval 0 on success
299 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
304 if (root == NULL || list == NULL)
307 LPROCFS_WRITE_ENTRY();
308 while (list->name != NULL) {
309 struct proc_dir_entry *cur_root, *proc;
310 char *pathcopy, *cur, *next, pathbuf[64];
311 int pathsize = strlen(list->name) + 1;
316 /* need copy of path for strsep */
317 if (strlen(list->name) > sizeof(pathbuf) - 1) {
318 OBD_ALLOC(pathcopy, pathsize);
319 if (pathcopy == NULL)
320 GOTO(out, rc = -ENOMEM);
326 strcpy(pathcopy, list->name);
328 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
329 if (*cur =='\0') /* skip double/trailing "/" */
332 proc = __lprocfs_srch(cur_root, cur);
333 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
334 cur_root->name, cur, next,
335 (proc ? "exists" : "new"));
337 cur_root = (proc ? proc :
338 proc_mkdir(cur, cur_root));
339 } else if (proc == NULL) {
341 if (list->proc_mode != 0000) {
342 mode = list->proc_mode;
346 if (list->write_fptr)
349 proc = create_proc_entry(cur, mode, cur_root);
353 if (pathcopy != pathbuf)
354 OBD_FREE(pathcopy, pathsize);
356 if (cur_root == NULL || proc == NULL) {
357 CERROR("LprocFS: No memory to create /proc entry %s",
359 GOTO(out, rc = -ENOMEM);
363 proc->proc_fops = list->fops;
365 proc->proc_fops = &lprocfs_generic_fops;
366 proc->read_proc = list->read_fptr;
367 proc->write_proc = list->write_fptr;
368 proc->data = (list->data ? list->data : data);
372 LPROCFS_WRITE_EXIT();
376 void lprocfs_remove(struct proc_dir_entry **rooth)
378 struct proc_dir_entry *root = *rooth;
379 struct proc_dir_entry *temp = root;
380 struct proc_dir_entry *rm_entry;
381 struct proc_dir_entry *parent;
387 parent = root->parent;
388 LASSERT(parent != NULL);
389 LPROCFS_WRITE_ENTRY(); /* search vs remove race */
392 while (temp->subdir != NULL)
398 /* Memory corruption once caused this to fail, and
399 without this LASSERT we would loop here forever. */
400 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
401 "0x%p %s/%s len %d\n", rm_entry, temp->name,
402 rm_entry->name, (int)strlen(rm_entry->name));
404 /* Now, the rm_entry->deleted flags is protected
405 * by _lprocfs_lock. */
406 rm_entry->data = NULL;
407 remove_proc_entry(rm_entry->name, temp);
411 LPROCFS_WRITE_EXIT();
414 void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
416 LASSERT(parent != NULL);
417 remove_proc_entry(name, parent);
420 struct proc_dir_entry *lprocfs_register(const char *name,
421 struct proc_dir_entry *parent,
422 struct lprocfs_vars *list, void *data)
424 struct proc_dir_entry *newchild;
426 newchild = lprocfs_srch(parent, name);
427 if (newchild != NULL) {
428 CERROR(" Lproc: Attempting to register %s more than once \n",
430 return ERR_PTR(-EALREADY);
433 newchild = proc_mkdir(name, parent);
434 if (newchild != NULL && list != NULL) {
435 int rc = lprocfs_add_vars(newchild, list, data);
437 lprocfs_remove(&newchild);
444 /* Generic callbacks */
445 int lprocfs_rd_uint(char *page, char **start, off_t off,
446 int count, int *eof, void *data)
448 unsigned int *temp = data;
449 return snprintf(page, count, "%u\n", *temp);
452 int lprocfs_wr_uint(struct file *file, const char *buffer,
453 unsigned long count, void *data)
456 char dummy[MAX_STRING_SIZE + 1], *end;
459 dummy[MAX_STRING_SIZE] = '\0';
460 if (cfs_copy_from_user(dummy, buffer, MAX_STRING_SIZE))
463 tmp = simple_strtoul(dummy, &end, 0);
467 *p = (unsigned int)tmp;
471 int lprocfs_rd_u64(char *page, char **start, off_t off,
472 int count, int *eof, void *data)
474 LASSERT(data != NULL);
476 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
479 int lprocfs_rd_atomic(char *page, char **start, off_t off,
480 int count, int *eof, void *data)
482 cfs_atomic_t *atom = data;
483 LASSERT(atom != NULL);
485 return snprintf(page, count, "%d\n", cfs_atomic_read(atom));
488 int lprocfs_wr_atomic(struct file *file, const char *buffer,
489 unsigned long count, void *data)
491 cfs_atomic_t *atm = data;
495 rc = lprocfs_write_helper(buffer, count, &val);
502 cfs_atomic_set(atm, val);
506 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
507 int *eof, void *data)
509 struct obd_device *obd = data;
511 LASSERT(obd != NULL);
513 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
516 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
517 int *eof, void *data)
519 struct obd_device *dev = data;
521 LASSERT(dev != NULL);
522 LASSERT(dev->obd_name != NULL);
524 return snprintf(page, count, "%s\n", dev->obd_name);
527 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
530 struct obd_device *obd = data;
532 LASSERT(obd != NULL);
533 LASSERT(obd->obd_fsops != NULL);
534 LASSERT(obd->obd_fsops->fs_type != NULL);
535 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
538 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
539 int *eof, void *data)
541 struct obd_statfs osfs;
542 int rc = obd_statfs(data, &osfs,
543 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
547 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
552 int lprocfs_rd_kbytestotal(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,
557 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
560 __u32 blk_size = osfs.os_bsize >> 10;
561 __u64 result = osfs.os_blocks;
563 while (blk_size >>= 1)
567 rc = snprintf(page, count, LPU64"\n", result);
572 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
573 int *eof, void *data)
575 struct obd_statfs osfs;
576 int rc = obd_statfs(data, &osfs,
577 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
580 __u32 blk_size = osfs.os_bsize >> 10;
581 __u64 result = osfs.os_bfree;
583 while (blk_size >>= 1)
587 rc = snprintf(page, count, LPU64"\n", result);
592 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
593 int *eof, void *data)
595 struct obd_statfs osfs;
596 int rc = obd_statfs(data, &osfs,
597 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
600 __u32 blk_size = osfs.os_bsize >> 10;
601 __u64 result = osfs.os_bavail;
603 while (blk_size >>= 1)
607 rc = snprintf(page, count, LPU64"\n", result);
612 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
613 int *eof, void *data)
615 struct obd_statfs osfs;
616 int rc = obd_statfs(data, &osfs,
617 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
621 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
627 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
628 int *eof, void *data)
630 struct obd_statfs osfs;
631 int rc = obd_statfs(data, &osfs,
632 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
636 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
641 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
642 int *eof, void *data)
644 struct obd_device *obd = data;
645 struct obd_import *imp;
646 char *imp_state_name = NULL;
649 LASSERT(obd != NULL);
650 LPROCFS_CLIMP_CHECK(obd);
651 imp = obd->u.cli.cl_import;
652 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
654 rc = snprintf(page, count, "%s\t%s%s\n",
655 obd2cli_tgt(obd), imp_state_name,
656 imp->imp_deactive ? "\tDEACTIVATED" : "");
658 LPROCFS_CLIMP_EXIT(obd);
662 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
663 int *eof, void *data)
665 struct obd_device *obd = data;
666 struct ptlrpc_connection *conn;
669 LASSERT(obd != NULL);
671 LPROCFS_CLIMP_CHECK(obd);
672 conn = obd->u.cli.cl_import->imp_connection;
674 if (conn && obd->u.cli.cl_import) {
675 rc = snprintf(page, count, "%s\n",
676 conn->c_remote_uuid.uuid);
678 rc = snprintf(page, count, "%s\n", "<none>");
681 LPROCFS_CLIMP_EXIT(obd);
685 /** add up per-cpu counters */
686 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
687 struct lprocfs_counter *cnt)
689 unsigned int num_cpu;
690 struct lprocfs_counter t;
691 struct lprocfs_counter *percpu_cntr;
694 memset(cnt, 0, sizeof(*cnt));
697 /* set count to 1 to avoid divide-by-zero errs in callers */
702 cnt->lc_min = LC_MIN_INIT;
704 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
707 num_cpu = cfs_num_possible_cpus();
709 for (i = 0; i < num_cpu; i++) {
710 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
713 centry = cfs_atomic_read(&percpu_cntr-> \
715 t.lc_count = percpu_cntr->lc_count;
716 t.lc_sum = percpu_cntr->lc_sum;
717 t.lc_min = percpu_cntr->lc_min;
718 t.lc_max = percpu_cntr->lc_max;
719 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
720 } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
722 centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
724 cnt->lc_count += t.lc_count;
725 cnt->lc_sum += t.lc_sum;
726 if (t.lc_min < cnt->lc_min)
727 cnt->lc_min = t.lc_min;
728 if (t.lc_max > cnt->lc_max)
729 cnt->lc_max = t.lc_max;
730 cnt->lc_sumsquare += t.lc_sumsquare;
733 cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
737 * Append a space separated list of current set flags to str.
739 #define flag2str(flag) \
740 if (imp->imp_##flag && max - len > 0) \
741 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
742 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
746 if (imp->imp_obd->obd_no_recov)
747 len += snprintf(str, max - len, "no_recov");
751 flag2str(replayable);
757 static const char *obd_connect_names[] = {
771 "join_file(obsolete)",
775 "remote_client_by_force",
784 "mds_mds_connection",
787 "alt_checksum_algorithm",
799 static int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
804 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
806 ret += snprintf(page + ret, count - ret, "%s%s",
807 ret ? sep : "", obd_connect_names[i]);
809 if (flags & ~(mask - 1))
810 ret += snprintf(page + ret, count - ret,
811 "%sunknown flags "LPX64,
812 ret ? sep : "", flags & ~(mask - 1));
816 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
817 int *eof, void *data)
819 struct lprocfs_counter ret;
820 struct obd_device *obd = (struct obd_device *)data;
821 struct obd_import *imp;
822 struct obd_import_conn *conn;
825 LASSERT(obd != NULL);
826 LPROCFS_CLIMP_CHECK(obd);
827 imp = obd->u.cli.cl_import;
830 i = snprintf(page, count,
838 ptlrpc_import_state_name(imp->imp_state));
839 i += obd_connect_flags2str(page + i, count - i,
840 imp->imp_connect_data.ocd_connect_flags,
842 i += snprintf(page + i, count - i,
845 i += obd_import_flags2str(imp, page + i, count - i);
847 i += snprintf(page + i, count - i,
850 " failover_nids: [");
851 cfs_spin_lock(&imp->imp_lock);
853 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
854 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
855 libcfs_nid2str(conn->oic_conn->c_peer.nid));
858 cfs_spin_unlock(&imp->imp_lock);
859 i += snprintf(page + i, count - i,
861 " current_connection: %s\n"
862 " connection_attempts: %u\n"
864 " in-progress_invalidations: %u\n",
865 libcfs_nid2str(imp->imp_connection->c_peer.nid),
868 cfs_atomic_read(&imp->imp_inval_count));
870 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
871 if (ret.lc_count != 0) {
872 /* first argument to do_div MUST be __u64 */
873 __u64 sum = ret.lc_sum;
874 do_div(sum, ret.lc_count);
878 i += snprintf(page + i, count - i,
881 " unregistering: %u\n"
883 " avg_waittime: "LPU64" %s\n",
884 cfs_atomic_read(&imp->imp_inflight),
885 cfs_atomic_read(&imp->imp_unregistering),
886 cfs_atomic_read(&imp->imp_timeouts),
887 ret.lc_sum, ret.lc_units);
890 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
891 if (imp->imp_at.iat_portal[j] == 0)
893 k = max_t(unsigned int, k,
894 at_get(&imp->imp_at.iat_service_estimate[j]));
896 i += snprintf(page + i, count - i,
897 " service_estimates:\n"
898 " services: %u sec\n"
899 " network: %u sec\n",
901 at_get(&imp->imp_at.iat_net_latency));
903 i += snprintf(page + i, count - i,
905 " last_replay: "LPU64"\n"
906 " peer_committed: "LPU64"\n"
907 " last_checked: "LPU64"\n",
908 imp->imp_last_replay_transno,
909 imp->imp_peer_committed_transno,
910 imp->imp_last_transno_checked);
913 for (rw = 0; rw <= 1; rw++) {
914 lprocfs_stats_collect(obd->obd_svc_stats,
915 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
917 if (ret.lc_sum > 0 && ret.lc_count > 0) {
918 /* first argument to do_div MUST be __u64 */
919 __u64 sum = ret.lc_sum;
920 do_div(sum, ret.lc_count);
922 i += snprintf(page + i, count - i,
923 " %s_data_averages:\n"
924 " bytes_per_rpc: "LPU64"\n",
925 rw ? "write" : "read",
929 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
930 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
931 if (ret.lc_sum > 0 && ret.lc_count != 0) {
932 /* first argument to do_div MUST be __u64 */
933 __u64 sum = ret.lc_sum;
934 do_div(sum, ret.lc_count);
936 i += snprintf(page + i, count - i,
937 " %s_per_rpc: "LPU64"\n",
938 ret.lc_units, ret.lc_sum);
941 i += snprintf(page + i, count - i,
942 " MB_per_sec: %u.%.02u\n",
943 k / j, (100 * k / j) % 100);
947 LPROCFS_CLIMP_EXIT(obd);
951 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
952 int *eof, void *data)
954 struct obd_device *obd = (struct obd_device *)data;
955 struct obd_import *imp;
958 LASSERT(obd != NULL);
959 LPROCFS_CLIMP_CHECK(obd);
960 imp = obd->u.cli.cl_import;
963 i = snprintf(page, count, "current_state: %s\n",
964 ptlrpc_import_state_name(imp->imp_state));
965 i += snprintf(page + i, count - i,
967 k = imp->imp_state_hist_idx;
968 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
969 struct import_state_hist *ish =
970 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
971 if (ish->ish_state == 0)
973 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
975 ptlrpc_import_state_name(ish->ish_state));
978 LPROCFS_CLIMP_EXIT(obd);
982 int lprocfs_at_hist_helper(char *page, int count, int rc,
983 struct adaptive_timeout *at)
986 for (i = 0; i < AT_BINS; i++)
987 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
988 rc += snprintf(page + rc, count - rc, "\n");
992 /* See also ptlrpc_lprocfs_rd_timeouts */
993 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
994 int *eof, void *data)
996 struct obd_device *obd = (struct obd_device *)data;
997 struct obd_import *imp;
998 unsigned int cur, worst;
1003 LASSERT(obd != NULL);
1004 LPROCFS_CLIMP_CHECK(obd);
1005 imp = obd->u.cli.cl_import;
1008 now = cfs_time_current_sec();
1010 /* Some network health info for kicks */
1011 s2dhms(&ts, now - imp->imp_last_reply_time);
1012 rc += snprintf(page + rc, count - rc,
1013 "%-10s : %ld, "DHMS_FMT" ago\n",
1014 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1016 cur = at_get(&imp->imp_at.iat_net_latency);
1017 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1018 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1019 s2dhms(&ts, now - worstt);
1020 rc += snprintf(page + rc, count - rc,
1021 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1022 "network", cur, worst, worstt, DHMS_VARS(&ts));
1023 rc = lprocfs_at_hist_helper(page, count, rc,
1024 &imp->imp_at.iat_net_latency);
1026 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1027 if (imp->imp_at.iat_portal[i] == 0)
1029 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1030 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1031 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1032 s2dhms(&ts, now - worstt);
1033 rc += snprintf(page + rc, count - rc,
1034 "portal %-2d : cur %3u worst %3u (at %ld, "
1035 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1036 cur, worst, worstt, DHMS_VARS(&ts));
1037 rc = lprocfs_at_hist_helper(page, count, rc,
1038 &imp->imp_at.iat_service_estimate[i]);
1041 LPROCFS_CLIMP_EXIT(obd);
1045 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1046 int count, int *eof, void *data)
1048 struct obd_device *obd = data;
1052 LPROCFS_CLIMP_CHECK(obd);
1053 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1054 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1055 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1056 ret += snprintf(page + ret, count - ret, "\n");
1057 LPROCFS_CLIMP_EXIT(obd);
1060 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1062 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1063 int *eof, void *data)
1065 struct obd_device *obd = data;
1067 LASSERT(obd != NULL);
1069 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1072 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1073 int *eof, void *data)
1075 struct obd_type *class = (struct obd_type*) data;
1077 LASSERT(class != NULL);
1079 return snprintf(page, count, "%d\n", class->typ_refcnt);
1082 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1086 LASSERT(obd != NULL);
1087 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1088 LASSERT(obd->obd_type->typ_procroot != NULL);
1090 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1091 obd->obd_type->typ_procroot,
1093 if (IS_ERR(obd->obd_proc_entry)) {
1094 rc = PTR_ERR(obd->obd_proc_entry);
1095 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1096 obd->obd_proc_entry = NULL;
1101 int lprocfs_obd_cleanup(struct obd_device *obd)
1105 if (obd->obd_proc_exports_entry) {
1106 /* Should be no exports left */
1107 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1108 lprocfs_remove(&obd->obd_proc_exports_entry);
1109 obd->obd_proc_exports_entry = NULL;
1111 if (obd->obd_proc_entry) {
1112 lprocfs_remove(&obd->obd_proc_entry);
1113 obd->obd_proc_entry = NULL;
1118 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1120 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1121 client_stat->nid_proc, client_stat->nid_stats,
1122 client_stat->nid_brw_stats);
1124 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1126 cfs_atomic_read(&client_stat->nid_exp_ref_count));
1128 cfs_hlist_del_init(&client_stat->nid_hash);
1130 if (client_stat->nid_proc)
1131 lprocfs_remove(&client_stat->nid_proc);
1133 if (client_stat->nid_stats)
1134 lprocfs_free_stats(&client_stat->nid_stats);
1136 if (client_stat->nid_brw_stats)
1137 OBD_FREE_PTR(client_stat->nid_brw_stats);
1139 if (client_stat->nid_ldlm_stats)
1140 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1142 OBD_FREE_PTR(client_stat);
1147 void lprocfs_free_per_client_stats(struct obd_device *obd)
1149 struct nid_stat *stat;
1152 /* we need extra list - because hash_exit called to early */
1153 /* not need locking because all clients is died */
1154 while(!cfs_list_empty(&obd->obd_nid_stats)) {
1155 stat = cfs_list_entry(obd->obd_nid_stats.next,
1156 struct nid_stat, nid_list);
1157 cfs_list_del_init(&stat->nid_list);
1158 lprocfs_free_client_stats(stat);
1164 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1165 enum lprocfs_stats_flags flags)
1167 struct lprocfs_stats *stats;
1168 unsigned int percpusize;
1170 unsigned int num_cpu;
1175 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1178 num_cpu = cfs_num_possible_cpus();
1180 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1184 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1185 stats->ls_flags = flags;
1186 cfs_spin_lock_init(&stats->ls_lock);
1187 /* Use this lock only if there are no percpu areas */
1189 stats->ls_flags = 0;
1192 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1194 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1196 for (i = 0; i < num_cpu; i++) {
1197 OBD_ALLOC(stats->ls_percpu[i], percpusize);
1198 if (stats->ls_percpu[i] == NULL) {
1199 for (j = 0; j < i; j++) {
1200 OBD_FREE(stats->ls_percpu[j], percpusize);
1201 stats->ls_percpu[j] = NULL;
1206 if (stats->ls_percpu[0] == NULL) {
1207 OBD_FREE(stats, offsetof(typeof(*stats),
1208 ls_percpu[num_cpu]));
1212 stats->ls_num = num;
1216 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1218 struct lprocfs_stats *stats = *statsh;
1219 unsigned int num_cpu;
1220 unsigned int percpusize;
1223 if (stats == NULL || stats->ls_num == 0)
1227 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1230 num_cpu = cfs_num_possible_cpus();
1232 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1234 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1235 for (i = 0; i < num_cpu; i++)
1236 OBD_FREE(stats->ls_percpu[i], percpusize);
1237 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1240 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1242 struct lprocfs_counter *percpu_cntr;
1244 unsigned int num_cpu;
1246 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1248 for (i = 0; i < num_cpu; i++) {
1249 for (j = 0; j < stats->ls_num; j++) {
1250 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1251 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1252 percpu_cntr->lc_count = 0;
1253 percpu_cntr->lc_sum = 0;
1254 percpu_cntr->lc_min = LC_MIN_INIT;
1255 percpu_cntr->lc_max = 0;
1256 percpu_cntr->lc_sumsquare = 0;
1257 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1261 lprocfs_stats_unlock(stats);
1264 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1265 size_t len, loff_t *off)
1267 struct seq_file *seq = file->private_data;
1268 struct lprocfs_stats *stats = seq->private;
1270 lprocfs_clear_stats(stats);
1275 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1277 struct lprocfs_stats *stats = p->private;
1278 /* return 1st cpu location */
1279 return (*pos >= stats->ls_num) ? NULL :
1280 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1283 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1287 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1289 struct lprocfs_stats *stats = p->private;
1291 return (*pos >= stats->ls_num) ? NULL :
1292 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1295 /* seq file export of one lprocfs counter */
1296 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1298 struct lprocfs_stats *stats = p->private;
1299 struct lprocfs_counter *cntr = v;
1300 struct lprocfs_counter ret;
1303 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1305 cfs_gettimeofday(&now);
1306 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1307 "snapshot_time", now.tv_sec, now.tv_usec);
1311 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1313 lprocfs_stats_collect(stats, idx, &ret);
1315 if (ret.lc_count == 0)
1318 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1319 ret.lc_count, cntr->lc_units);
1324 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1325 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1326 ret.lc_min, ret.lc_max, ret.lc_sum);
1329 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1330 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1334 rc = seq_printf(p, "\n");
1336 return (rc < 0) ? rc : 0;
1339 struct seq_operations lprocfs_stats_seq_sops = {
1340 start: lprocfs_stats_seq_start,
1341 stop: lprocfs_stats_seq_stop,
1342 next: lprocfs_stats_seq_next,
1343 show: lprocfs_stats_seq_show,
1346 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1348 struct proc_dir_entry *dp = PDE(inode);
1349 struct seq_file *seq;
1352 if (LPROCFS_ENTRY_AND_CHECK(dp))
1355 rc = seq_open(file, &lprocfs_stats_seq_sops);
1360 seq = file->private_data;
1361 seq->private = dp->data;
1365 struct file_operations lprocfs_stats_seq_fops = {
1366 .owner = THIS_MODULE,
1367 .open = lprocfs_stats_seq_open,
1369 .write = lprocfs_stats_seq_write,
1370 .llseek = seq_lseek,
1371 .release = lprocfs_seq_release,
1374 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1375 struct lprocfs_stats *stats)
1377 struct proc_dir_entry *entry;
1378 LASSERT(root != NULL);
1380 LPROCFS_WRITE_ENTRY();
1381 entry = create_proc_entry(name, 0644, root);
1383 entry->proc_fops = &lprocfs_stats_seq_fops;
1384 entry->data = stats;
1387 LPROCFS_WRITE_EXIT();
1395 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1396 unsigned conf, const char *name, const char *units)
1398 struct lprocfs_counter *c;
1400 unsigned int num_cpu;
1402 LASSERT(stats != NULL);
1404 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1406 for (i = 0; i < num_cpu; i++) {
1407 c = &(stats->ls_percpu[i]->lp_cntr[index]);
1408 c->lc_config = conf;
1411 c->lc_min = LC_MIN_INIT;
1414 c->lc_units = units;
1417 lprocfs_stats_unlock(stats);
1419 EXPORT_SYMBOL(lprocfs_counter_init);
1421 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1423 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1424 LASSERT(coffset < stats->ls_num); \
1425 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1428 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1430 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1431 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1432 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1433 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1434 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1435 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1436 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1437 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1438 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1439 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1440 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1441 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1442 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1443 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1444 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1445 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1446 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1447 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1448 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1449 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1450 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1451 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1452 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1453 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1454 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1455 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1456 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1457 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1458 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1459 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1460 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1461 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1462 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1463 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1467 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1468 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1469 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1470 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1471 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1472 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1473 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1474 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1475 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1476 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1477 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1478 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1479 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1480 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1481 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1482 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1483 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1484 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1485 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1486 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1487 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1488 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1489 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1490 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1491 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1492 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1493 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1494 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1495 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1496 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1497 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1498 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1501 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1503 struct lprocfs_stats *stats;
1504 unsigned int num_stats;
1507 LASSERT(obd->obd_stats == NULL);
1508 LASSERT(obd->obd_proc_entry != NULL);
1509 LASSERT(obd->obd_cntr_base == 0);
1511 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1512 num_private_stats - 1 /* o_owner */;
1513 stats = lprocfs_alloc_stats(num_stats, 0);
1517 lprocfs_init_ops_stats(num_private_stats, stats);
1519 for (i = num_private_stats; i < num_stats; i++) {
1520 /* If this LBUGs, it is likely that an obd
1521 * operation was added to struct obd_ops in
1522 * <obd.h>, and that the corresponding line item
1523 * LPROCFS_OBD_OP_INIT(.., .., opname)
1524 * is missing from the list above. */
1525 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1526 "Missing obd_stat initializer obd_op "
1527 "operation at offset %d.\n", i - num_private_stats);
1529 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1531 lprocfs_free_stats(&stats);
1533 obd->obd_stats = stats;
1534 obd->obd_cntr_base = num_private_stats;
1539 void lprocfs_free_obd_stats(struct obd_device *obd)
1542 lprocfs_free_stats(&obd->obd_stats);
1545 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1547 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1548 LASSERT(coffset < stats->ls_num); \
1549 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1552 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1554 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1555 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1556 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1557 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1558 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1559 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1560 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1561 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1562 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1563 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1564 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1565 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1566 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1567 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1568 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1569 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1570 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1571 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1572 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1573 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1574 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1575 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1576 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1577 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1578 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1579 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1580 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1581 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1582 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1583 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1584 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1585 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1588 int lprocfs_alloc_md_stats(struct obd_device *obd,
1589 unsigned num_private_stats)
1591 struct lprocfs_stats *stats;
1592 unsigned int num_stats;
1595 LASSERT(obd->md_stats == NULL);
1596 LASSERT(obd->obd_proc_entry != NULL);
1597 LASSERT(obd->md_cntr_base == 0);
1599 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1601 stats = lprocfs_alloc_stats(num_stats, 0);
1605 lprocfs_init_mps_stats(num_private_stats, stats);
1607 for (i = num_private_stats; i < num_stats; i++) {
1608 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1609 CERROR("Missing md_stat initializer md_op "
1610 "operation at offset %d. Aborting.\n",
1611 i - num_private_stats);
1615 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1617 lprocfs_free_stats(&stats);
1619 obd->md_stats = stats;
1620 obd->md_cntr_base = num_private_stats;
1625 void lprocfs_free_md_stats(struct obd_device *obd)
1627 struct lprocfs_stats *stats = obd->md_stats;
1629 if (stats != NULL) {
1630 obd->md_stats = NULL;
1631 obd->md_cntr_base = 0;
1632 lprocfs_free_stats(&stats);
1636 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1638 lprocfs_counter_init(ldlm_stats,
1639 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1640 0, "ldlm_enqueue", "reqs");
1641 lprocfs_counter_init(ldlm_stats,
1642 LDLM_CONVERT - LDLM_FIRST_OPC,
1643 0, "ldlm_convert", "reqs");
1644 lprocfs_counter_init(ldlm_stats,
1645 LDLM_CANCEL - LDLM_FIRST_OPC,
1646 0, "ldlm_cancel", "reqs");
1647 lprocfs_counter_init(ldlm_stats,
1648 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1649 0, "ldlm_bl_callback", "reqs");
1650 lprocfs_counter_init(ldlm_stats,
1651 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1652 0, "ldlm_cp_callback", "reqs");
1653 lprocfs_counter_init(ldlm_stats,
1654 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1655 0, "ldlm_gl_callback", "reqs");
1658 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1659 int *eof, void *data)
1661 struct obd_export *exp = data;
1662 LASSERT(exp != NULL);
1664 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1667 struct exp_uuid_cb_data {
1675 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1676 int count, int *eof, int *len)
1678 cb_data->page = page;
1679 cb_data->count = count;
1684 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1685 cfs_hlist_node_t *hnode, void *cb_data)
1688 struct obd_export *exp = cfs_hash_object(hs, hnode);
1689 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1691 if (exp->exp_nid_stats)
1692 *data->len += snprintf((data->page + *data->len),
1693 data->count, "%s\n",
1694 obd_uuid2str(&exp->exp_client_uuid));
1698 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1699 int *eof, void *data)
1701 struct nid_stat *stats = (struct nid_stat *)data;
1702 struct exp_uuid_cb_data cb_data;
1703 struct obd_device *obd = stats->nid_obd;
1708 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1709 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1710 lprocfs_exp_print_uuid, &cb_data);
1711 return (*cb_data.len);
1714 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1715 cfs_hlist_node_t *hnode, void *cb_data)
1718 struct exp_uuid_cb_data *data = cb_data;
1719 struct obd_export *exp = cfs_hash_object(hs, hnode);
1721 LASSERT(hs == exp->exp_lock_hash);
1723 *data->len += cfs_hash_debug_header(data->page,
1726 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1731 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1732 int *eof, void *data)
1734 struct nid_stat *stats = (struct nid_stat *)data;
1735 struct exp_uuid_cb_data cb_data;
1736 struct obd_device *obd = stats->nid_obd;
1741 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1743 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1744 lprocfs_exp_print_hash, &cb_data);
1745 return (*cb_data.len);
1748 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1749 int count, int *eof, void *data)
1752 return snprintf(page, count, "%s\n",
1753 "Write into this file to clear all nid stats and "
1754 "stale nid entries");
1756 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1758 int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1760 struct nid_stat *stat = obj;
1764 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1765 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1766 /* object has only hash references. */
1767 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1768 cfs_list_move(&stat->nid_list, data);
1769 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1772 /* we has reference to object - only clear data*/
1773 if (stat->nid_stats)
1774 lprocfs_clear_stats(stat->nid_stats);
1776 if (stat->nid_brw_stats) {
1777 for (i = 0; i < BRW_LAST; i++)
1778 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1783 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1784 unsigned long count, void *data)
1786 struct obd_device *obd = (struct obd_device *)data;
1787 struct nid_stat *client_stat;
1788 CFS_LIST_HEAD(free_list);
1790 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1791 lprocfs_nid_stats_clear_write_cb, &free_list);
1793 while (!cfs_list_empty(&free_list)) {
1794 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1796 cfs_list_del_init(&client_stat->nid_list);
1797 lprocfs_free_client_stats(client_stat);
1802 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1804 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int reconnect,
1807 struct nid_stat *new_stat, *old_stat;
1808 struct obd_device *obd = NULL;
1809 cfs_proc_dir_entry_t *entry;
1810 char *buffer = NULL;
1816 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1817 !exp->exp_obd->obd_nid_stats_hash)
1820 /* not test against zero because eric say:
1821 * You may only test nid against another nid, or LNET_NID_ANY.
1822 * Anything else is nonsense.*/
1823 if (!nid || *nid == LNET_NID_ANY)
1828 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1830 OBD_ALLOC_PTR(new_stat);
1831 if (new_stat == NULL)
1834 new_stat->nid = *nid;
1835 new_stat->nid_obd = exp->exp_obd;
1836 /* we need set default refcount to 1 to balance obd_disconnect */
1837 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1839 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1840 nid, &new_stat->nid_hash);
1841 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1842 old_stat, libcfs_nid2str(*nid),
1843 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1845 /* Return -EALREADY here so that we know that the /proc
1846 * entry already has been created */
1847 if (old_stat != new_stat) {
1848 /* if this connects to the existing export of same nid,
1849 * we need to release old stats for obd_disconnect won't
1850 * balance the reference gotten in "cfs_hash_findadd_uinque" */
1851 if (reconnect && exp->exp_nid_stats)
1852 nidstat_putref(old_stat);
1854 exp->exp_nid_stats = old_stat;
1855 GOTO(destroy_new, rc = -EALREADY);
1857 /* not found - create */
1858 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1860 GOTO(destroy_new, rc = -ENOMEM);
1862 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1863 new_stat->nid_proc = lprocfs_register(buffer,
1864 obd->obd_proc_exports_entry,
1866 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1868 if (new_stat->nid_proc == NULL) {
1869 CERROR("Error making export directory for nid %s\n",
1870 libcfs_nid2str(*nid));
1871 GOTO(destroy_new_ns, rc = -ENOMEM);
1874 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1875 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1876 if (IS_ERR(entry)) {
1877 CWARN("Error adding the NID stats file\n");
1878 rc = PTR_ERR(entry);
1879 GOTO(destroy_new_ns, rc);
1882 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1883 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1884 if (IS_ERR(entry)) {
1885 CWARN("Error adding the hash file\n");
1886 rc = PTR_ERR(entry);
1887 GOTO(destroy_new_ns, rc);
1890 exp->exp_nid_stats = new_stat;
1892 /* protect competitive add to list, not need locking on destroy */
1893 cfs_spin_lock(&obd->obd_nid_lock);
1894 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1895 cfs_spin_unlock(&obd->obd_nid_lock);
1900 if (new_stat->nid_proc != NULL)
1901 lprocfs_remove(&new_stat->nid_proc);
1902 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1905 nidstat_putref(new_stat);
1906 OBD_FREE_PTR(new_stat);
1910 int lprocfs_exp_cleanup(struct obd_export *exp)
1912 struct nid_stat *stat = exp->exp_nid_stats;
1914 if(!stat || !exp->exp_obd)
1917 nidstat_putref(exp->exp_nid_stats);
1918 exp->exp_nid_stats = NULL;
1923 int lprocfs_write_helper(const char *buffer, unsigned long count,
1926 return lprocfs_write_frac_helper(buffer, count, val, 1);
1929 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1932 char kernbuf[20], *end, *pbuf;
1934 if (count > (sizeof(kernbuf) - 1))
1937 if (cfs_copy_from_user(kernbuf, buffer, count))
1940 kernbuf[count] = '\0';
1947 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1951 if (end != NULL && *end == '.') {
1952 int temp_val, pow = 1;
1956 if (strlen(pbuf) > 5)
1957 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1959 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1962 for (i = 0; i < (end - pbuf); i++)
1965 *val += temp_val / pow;
1971 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
1974 long decimal_val, frac_val;
1980 decimal_val = val / mult;
1981 prtn = snprintf(buffer, count, "%ld", decimal_val);
1982 frac_val = val % mult;
1984 if (prtn < (count - 4) && frac_val > 0) {
1986 int i, temp_mult = 1, frac_bits = 0;
1988 temp_frac = frac_val * 10;
1989 buffer[prtn++] = '.';
1990 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
1991 /* only reserved 2 bits fraction */
1992 buffer[prtn++] ='0';
1997 * Need to think these cases :
1998 * 1. #echo x.00 > /proc/xxx output result : x
1999 * 2. #echo x.0x > /proc/xxx output result : x.0x
2000 * 3. #echo x.x0 > /proc/xxx output result : x.x
2001 * 4. #echo x.xx > /proc/xxx output result : x.xx
2002 * Only reserved 2 bits fraction.
2004 for (i = 0; i < (5 - prtn); i++)
2007 frac_bits = min((int)count - prtn, 3 - frac_bits);
2008 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2009 frac_val * temp_mult / mult);
2012 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2014 if (buffer[prtn] == '.') {
2021 buffer[prtn++] ='\n';
2025 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2027 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2030 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2031 __u64 *val, int mult)
2033 char kernbuf[22], *end, *pbuf;
2034 __u64 whole, frac = 0, units;
2035 unsigned frac_d = 1;
2037 if (count > (sizeof(kernbuf) - 1))
2040 if (cfs_copy_from_user(kernbuf, buffer, count))
2043 kernbuf[count] = '\0';
2050 whole = simple_strtoull(pbuf, &end, 10);
2054 if (end != NULL && *end == '.') {
2058 /* need to limit frac_d to a __u32 */
2059 if (strlen(pbuf) > 10)
2062 frac = simple_strtoull(pbuf, &end, 10);
2063 /* count decimal places */
2064 for (i = 0; i < (end - pbuf); i++)
2081 /* Specified units override the multiplier */
2083 mult = mult < 0 ? -units : units;
2086 do_div(frac, frac_d);
2087 *val = whole * mult + frac;
2091 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2092 struct file_operations *seq_fops, void *data)
2094 struct proc_dir_entry *entry;
2097 LPROCFS_WRITE_ENTRY();
2098 entry = create_proc_entry(name, mode, parent);
2100 entry->proc_fops = seq_fops;
2103 LPROCFS_WRITE_EXIT();
2110 EXPORT_SYMBOL(lprocfs_seq_create);
2112 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2114 struct file_operations *seq_fops,
2117 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2118 mode, seq_fops, data));
2120 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2122 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2124 if (value >= OBD_HIST_MAX)
2125 value = OBD_HIST_MAX - 1;
2127 cfs_spin_lock(&oh->oh_lock);
2128 oh->oh_buckets[value]++;
2129 cfs_spin_unlock(&oh->oh_lock);
2131 EXPORT_SYMBOL(lprocfs_oh_tally);
2133 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2137 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2140 lprocfs_oh_tally(oh, val);
2142 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2144 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2146 unsigned long ret = 0;
2149 for (i = 0; i < OBD_HIST_MAX; i++)
2150 ret += oh->oh_buckets[i];
2153 EXPORT_SYMBOL(lprocfs_oh_sum);
2155 void lprocfs_oh_clear(struct obd_histogram *oh)
2157 cfs_spin_lock(&oh->oh_lock);
2158 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2159 cfs_spin_unlock(&oh->oh_lock);
2161 EXPORT_SYMBOL(lprocfs_oh_clear);
2163 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2164 int count, int *eof, void *data)
2166 struct obd_device *obd = data;
2172 c += cfs_hash_debug_header(page, count);
2173 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2174 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2175 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2176 #ifdef HAVE_QUOTA_SUPPORT
2177 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2178 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2179 page + c, count - c);
2184 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2186 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2187 int count, int *eof, void *data)
2189 struct obd_device *obd = data;
2192 LASSERT(obd != NULL);
2193 LASSERT(count >= 0);
2195 /* Set start of user data returned to
2196 page + off since the user may have
2197 requested to read much smaller than
2198 what we need to read */
2199 *start = page + off;
2201 /* We know we are allocated a page here.
2202 Also we know that this function will
2203 not need to write more than a page
2204 so we can truncate at CFS_PAGE_SIZE. */
2205 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2207 /* Initialize the page */
2208 memset(page, 0, size);
2210 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2212 if (obd->obd_max_recoverable_clients == 0) {
2213 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2219 /* sampled unlocked, but really... */
2220 if (obd->obd_recovering == 0) {
2221 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2223 if (lprocfs_obd_snprintf(&page, size, &len,
2224 "recovery_start: %lu\n",
2225 obd->obd_recovery_start) <= 0)
2227 if (lprocfs_obd_snprintf(&page, size, &len,
2228 "recovery_duration: %lu\n",
2229 obd->obd_recovery_end -
2230 obd->obd_recovery_start) <= 0)
2232 /* Number of clients that have completed recovery */
2233 if (lprocfs_obd_snprintf(&page, size, &len,
2234 "completed_clients: %d/%d\n",
2235 obd->obd_max_recoverable_clients -
2236 obd->obd_stale_clients,
2237 obd->obd_max_recoverable_clients) <= 0)
2239 if (lprocfs_obd_snprintf(&page, size, &len,
2240 "replayed_requests: %d\n",
2241 obd->obd_replayed_requests) <= 0)
2243 if (lprocfs_obd_snprintf(&page, size, &len,
2244 "last_transno: "LPD64"\n",
2245 obd->obd_next_recovery_transno - 1)<=0)
2247 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2248 obd->obd_version_recov ? "ON" : "OFF")<=0)
2253 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2255 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2256 obd->obd_recovery_start) <= 0)
2258 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2259 cfs_time_current_sec() >= obd->obd_recovery_end ? 0 :
2260 obd->obd_recovery_end - cfs_time_current_sec()) <= 0)
2262 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2263 obd->obd_connected_clients,
2264 obd->obd_max_recoverable_clients) <= 0)
2266 /* Number of clients that have completed recovery */
2267 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2268 cfs_atomic_read(&obd->obd_req_replay_clients))
2271 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2272 cfs_atomic_read(&obd->obd_lock_replay_clients))
2275 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2276 obd->obd_connected_clients -
2277 cfs_atomic_read(&obd->obd_lock_replay_clients))
2280 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2281 obd->obd_stale_clients) <= 0)
2283 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2284 obd->obd_replayed_requests) <= 0)
2286 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2287 obd->obd_requests_queued_for_recovery) <= 0)
2290 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2291 obd->obd_next_recovery_transno) <= 0)
2297 return min(count, len - (int)off);
2299 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2301 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2302 int count, int *eof, void *data)
2304 struct obd_device *obd = (struct obd_device *)data;
2305 LASSERT(obd != NULL);
2307 return snprintf(page, count, "%d\n",
2308 obd->obd_recovery_timeout);
2310 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2312 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2313 unsigned long count, void *data)
2315 struct obd_device *obd = (struct obd_device *)data;
2317 LASSERT(obd != NULL);
2319 rc = lprocfs_write_helper(buffer, count, &val);
2323 obd->obd_recovery_timeout = val;
2326 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2328 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2329 int count, int *eof, void *data)
2331 struct obd_device *obd = data;
2332 LASSERT(obd != NULL);
2334 return snprintf(page, count, "%lu\n", obd->obd_recovery_time_hard);
2336 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2338 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2339 unsigned long count, void *data)
2341 struct obd_device *obd = data;
2343 LASSERT(obd != NULL);
2345 rc = lprocfs_write_helper(buffer, count, &val);
2349 obd->obd_recovery_time_hard = val;
2352 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2354 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2355 int count, int *eof, void *data)
2357 struct obd_device *obd = (struct obd_device *)data;
2359 LASSERT(obd != NULL);
2360 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2362 return snprintf(page, count, "%s\n",
2363 obd->u.obt.obt_vfsmnt->mnt_devname);
2365 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2367 EXPORT_SYMBOL(lprocfs_register);
2368 EXPORT_SYMBOL(lprocfs_srch);
2369 EXPORT_SYMBOL(lprocfs_remove);
2370 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2371 EXPORT_SYMBOL(lprocfs_add_vars);
2372 EXPORT_SYMBOL(lprocfs_obd_setup);
2373 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2374 EXPORT_SYMBOL(lprocfs_add_simple);
2375 EXPORT_SYMBOL(lprocfs_add_symlink);
2376 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2377 EXPORT_SYMBOL(lprocfs_alloc_stats);
2378 EXPORT_SYMBOL(lprocfs_free_stats);
2379 EXPORT_SYMBOL(lprocfs_clear_stats);
2380 EXPORT_SYMBOL(lprocfs_register_stats);
2381 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2382 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2383 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2384 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2385 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2386 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2387 EXPORT_SYMBOL(lprocfs_free_md_stats);
2388 EXPORT_SYMBOL(lprocfs_exp_setup);
2389 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2391 EXPORT_SYMBOL(lprocfs_rd_u64);
2392 EXPORT_SYMBOL(lprocfs_rd_atomic);
2393 EXPORT_SYMBOL(lprocfs_wr_atomic);
2394 EXPORT_SYMBOL(lprocfs_rd_uint);
2395 EXPORT_SYMBOL(lprocfs_wr_uint);
2396 EXPORT_SYMBOL(lprocfs_rd_uuid);
2397 EXPORT_SYMBOL(lprocfs_rd_name);
2398 EXPORT_SYMBOL(lprocfs_rd_fstype);
2399 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2400 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2401 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2402 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2403 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2404 EXPORT_SYMBOL(lprocfs_rd_import);
2405 EXPORT_SYMBOL(lprocfs_rd_state);
2406 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2407 EXPORT_SYMBOL(lprocfs_rd_blksize);
2408 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2409 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2410 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2411 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2412 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2414 EXPORT_SYMBOL(lprocfs_write_helper);
2415 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2416 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2417 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2418 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2419 EXPORT_SYMBOL(lprocfs_stats_collect);