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);
1499 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync_fs);
1502 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1504 struct lprocfs_stats *stats;
1505 unsigned int num_stats;
1508 LASSERT(obd->obd_stats == NULL);
1509 LASSERT(obd->obd_proc_entry != NULL);
1510 LASSERT(obd->obd_cntr_base == 0);
1512 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1513 num_private_stats - 1 /* o_owner */;
1514 stats = lprocfs_alloc_stats(num_stats, 0);
1518 lprocfs_init_ops_stats(num_private_stats, stats);
1520 for (i = num_private_stats; i < num_stats; i++) {
1521 /* If this LBUGs, it is likely that an obd
1522 * operation was added to struct obd_ops in
1523 * <obd.h>, and that the corresponding line item
1524 * LPROCFS_OBD_OP_INIT(.., .., opname)
1525 * is missing from the list above. */
1526 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1527 "Missing obd_stat initializer obd_op "
1528 "operation at offset %d.\n", i - num_private_stats);
1530 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1532 lprocfs_free_stats(&stats);
1534 obd->obd_stats = stats;
1535 obd->obd_cntr_base = num_private_stats;
1540 void lprocfs_free_obd_stats(struct obd_device *obd)
1543 lprocfs_free_stats(&obd->obd_stats);
1546 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1548 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1549 LASSERT(coffset < stats->ls_num); \
1550 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1553 int lprocfs_alloc_md_stats(struct obd_device *obd,
1554 unsigned num_private_stats)
1556 struct lprocfs_stats *stats;
1557 unsigned int num_stats;
1560 LASSERT(obd->md_stats == NULL);
1561 LASSERT(obd->obd_proc_entry != NULL);
1562 LASSERT(obd->md_cntr_base == 0);
1564 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1566 stats = lprocfs_alloc_stats(num_stats, 0);
1570 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1571 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1572 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1573 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1574 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1575 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1576 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1577 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1578 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1579 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1580 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1581 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1582 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1583 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1584 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1585 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1586 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1587 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1588 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1589 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1590 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1591 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1592 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1593 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1594 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1595 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1596 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1597 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1598 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1599 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1600 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1601 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1603 for (i = num_private_stats; i < num_stats; i++) {
1604 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1605 CERROR("Missing md_stat initializer md_op "
1606 "operation at offset %d. Aborting.\n",
1607 i - num_private_stats);
1611 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1613 lprocfs_free_stats(&stats);
1615 obd->md_stats = stats;
1616 obd->md_cntr_base = num_private_stats;
1621 void lprocfs_free_md_stats(struct obd_device *obd)
1623 struct lprocfs_stats *stats = obd->md_stats;
1625 if (stats != NULL) {
1626 obd->md_stats = NULL;
1627 obd->md_cntr_base = 0;
1628 lprocfs_free_stats(&stats);
1632 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1634 lprocfs_counter_init(ldlm_stats,
1635 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1636 0, "ldlm_enqueue", "reqs");
1637 lprocfs_counter_init(ldlm_stats,
1638 LDLM_CONVERT - LDLM_FIRST_OPC,
1639 0, "ldlm_convert", "reqs");
1640 lprocfs_counter_init(ldlm_stats,
1641 LDLM_CANCEL - LDLM_FIRST_OPC,
1642 0, "ldlm_cancel", "reqs");
1643 lprocfs_counter_init(ldlm_stats,
1644 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1645 0, "ldlm_bl_callback", "reqs");
1646 lprocfs_counter_init(ldlm_stats,
1647 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1648 0, "ldlm_cp_callback", "reqs");
1649 lprocfs_counter_init(ldlm_stats,
1650 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1651 0, "ldlm_gl_callback", "reqs");
1654 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1655 int *eof, void *data)
1657 struct obd_export *exp = data;
1658 LASSERT(exp != NULL);
1660 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1663 struct exp_uuid_cb_data {
1671 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1672 int count, int *eof, int *len)
1674 cb_data->page = page;
1675 cb_data->count = count;
1680 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1681 cfs_hlist_node_t *hnode, void *cb_data)
1684 struct obd_export *exp = cfs_hash_object(hs, hnode);
1685 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1687 if (exp->exp_nid_stats)
1688 *data->len += snprintf((data->page + *data->len),
1689 data->count, "%s\n",
1690 obd_uuid2str(&exp->exp_client_uuid));
1694 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1695 int *eof, void *data)
1697 struct nid_stat *stats = (struct nid_stat *)data;
1698 struct exp_uuid_cb_data cb_data;
1699 struct obd_device *obd = stats->nid_obd;
1704 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1705 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1706 lprocfs_exp_print_uuid, &cb_data);
1707 return (*cb_data.len);
1710 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1711 cfs_hlist_node_t *hnode, void *cb_data)
1714 struct exp_uuid_cb_data *data = cb_data;
1715 struct obd_export *exp = cfs_hash_object(hs, hnode);
1717 LASSERT(hs == exp->exp_lock_hash);
1719 *data->len += cfs_hash_debug_header(data->page,
1722 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1727 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1728 int *eof, void *data)
1730 struct nid_stat *stats = (struct nid_stat *)data;
1731 struct exp_uuid_cb_data cb_data;
1732 struct obd_device *obd = stats->nid_obd;
1737 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1739 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1740 lprocfs_exp_print_hash, &cb_data);
1741 return (*cb_data.len);
1744 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1745 int count, int *eof, void *data)
1748 return snprintf(page, count, "%s\n",
1749 "Write into this file to clear all nid stats and "
1750 "stale nid entries");
1752 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1754 int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1756 struct nid_stat *stat = obj;
1759 /* object has only hash + iterate_all references.
1760 * add/delete blocked by hash bucket lock */
1761 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1762 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 2) {
1763 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1764 cfs_list_move(&stat->nid_list, data);
1765 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1768 /* we has reference to object - only clear data*/
1769 if (stat->nid_stats)
1770 lprocfs_clear_stats(stat->nid_stats);
1772 if (stat->nid_brw_stats) {
1773 for (i = 0; i < BRW_LAST; i++)
1774 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1779 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1780 unsigned long count, void *data)
1782 struct obd_device *obd = (struct obd_device *)data;
1783 struct nid_stat *client_stat;
1784 CFS_LIST_HEAD(free_list);
1786 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1787 lprocfs_nid_stats_clear_write_cb, &free_list);
1789 while (!cfs_list_empty(&free_list)) {
1790 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1792 cfs_list_del_init(&client_stat->nid_list);
1793 lprocfs_free_client_stats(client_stat);
1798 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1800 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int reconnect,
1803 struct nid_stat *new_stat, *old_stat;
1804 struct obd_device *obd = NULL;
1805 cfs_proc_dir_entry_t *entry;
1806 char *buffer = NULL;
1812 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1813 !exp->exp_obd->obd_nid_stats_hash)
1816 /* not test against zero because eric say:
1817 * You may only test nid against another nid, or LNET_NID_ANY.
1818 * Anything else is nonsense.*/
1819 if (!nid || *nid == LNET_NID_ANY)
1824 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1826 OBD_ALLOC_PTR(new_stat);
1827 if (new_stat == NULL)
1830 new_stat->nid = *nid;
1831 new_stat->nid_obd = exp->exp_obd;
1832 /* we need set default refcount to 1 to balance obd_disconnect */
1833 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1835 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1836 nid, &new_stat->nid_hash);
1837 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1838 old_stat, libcfs_nid2str(*nid),
1839 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1841 /* Return -EALREADY here so that we know that the /proc
1842 * entry already has been created */
1843 if (old_stat != new_stat) {
1844 /* if this connects to the existing export of same nid,
1845 * we need to release old stats for obd_disconnect won't
1846 * balance the reference gotten in "cfs_hash_findadd_uinque" */
1847 if (reconnect && exp->exp_nid_stats)
1848 nidstat_putref(old_stat);
1850 exp->exp_nid_stats = old_stat;
1851 GOTO(destroy_new, rc = -EALREADY);
1853 /* not found - create */
1854 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1856 GOTO(destroy_new, rc = -ENOMEM);
1858 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1859 new_stat->nid_proc = lprocfs_register(buffer,
1860 obd->obd_proc_exports_entry,
1862 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1864 if (new_stat->nid_proc == NULL) {
1865 CERROR("Error making export directory for nid %s\n",
1866 libcfs_nid2str(*nid));
1867 GOTO(destroy_new_ns, rc = -ENOMEM);
1870 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1871 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1872 if (IS_ERR(entry)) {
1873 CWARN("Error adding the NID stats file\n");
1874 rc = PTR_ERR(entry);
1875 GOTO(destroy_new_ns, rc);
1878 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1879 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1880 if (IS_ERR(entry)) {
1881 CWARN("Error adding the hash file\n");
1882 rc = PTR_ERR(entry);
1883 GOTO(destroy_new_ns, rc);
1886 exp->exp_nid_stats = new_stat;
1888 /* protect competitive add to list, not need locking on destroy */
1889 cfs_spin_lock(&obd->obd_nid_lock);
1890 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1891 cfs_spin_unlock(&obd->obd_nid_lock);
1896 if (new_stat->nid_proc != NULL)
1897 lprocfs_remove(&new_stat->nid_proc);
1898 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1901 nidstat_putref(new_stat);
1902 OBD_FREE_PTR(new_stat);
1906 int lprocfs_exp_cleanup(struct obd_export *exp)
1908 struct nid_stat *stat = exp->exp_nid_stats;
1910 if(!stat || !exp->exp_obd)
1913 nidstat_putref(exp->exp_nid_stats);
1914 exp->exp_nid_stats = NULL;
1919 int lprocfs_write_helper(const char *buffer, unsigned long count,
1922 return lprocfs_write_frac_helper(buffer, count, val, 1);
1925 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1928 char kernbuf[20], *end, *pbuf;
1930 if (count > (sizeof(kernbuf) - 1))
1933 if (cfs_copy_from_user(kernbuf, buffer, count))
1936 kernbuf[count] = '\0';
1943 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1947 if (end != NULL && *end == '.') {
1948 int temp_val, pow = 1;
1952 if (strlen(pbuf) > 5)
1953 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1955 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1958 for (i = 0; i < (end - pbuf); i++)
1961 *val += temp_val / pow;
1967 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
1970 long decimal_val, frac_val;
1976 decimal_val = val / mult;
1977 prtn = snprintf(buffer, count, "%ld", decimal_val);
1978 frac_val = val % mult;
1980 if (prtn < (count - 4) && frac_val > 0) {
1982 int i, temp_mult = 1, frac_bits = 0;
1984 temp_frac = frac_val * 10;
1985 buffer[prtn++] = '.';
1986 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
1987 /* only reserved 2 bits fraction */
1988 buffer[prtn++] ='0';
1993 * Need to think these cases :
1994 * 1. #echo x.00 > /proc/xxx output result : x
1995 * 2. #echo x.0x > /proc/xxx output result : x.0x
1996 * 3. #echo x.x0 > /proc/xxx output result : x.x
1997 * 4. #echo x.xx > /proc/xxx output result : x.xx
1998 * Only reserved 2 bits fraction.
2000 for (i = 0; i < (5 - prtn); i++)
2003 frac_bits = min((int)count - prtn, 3 - frac_bits);
2004 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2005 frac_val * temp_mult / mult);
2008 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2010 if (buffer[prtn] == '.') {
2017 buffer[prtn++] ='\n';
2021 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2023 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2026 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2027 __u64 *val, int mult)
2029 char kernbuf[22], *end, *pbuf;
2030 __u64 whole, frac = 0, units;
2031 unsigned frac_d = 1;
2033 if (count > (sizeof(kernbuf) - 1))
2036 if (cfs_copy_from_user(kernbuf, buffer, count))
2039 kernbuf[count] = '\0';
2046 whole = simple_strtoull(pbuf, &end, 10);
2050 if (end != NULL && *end == '.') {
2054 /* need to limit frac_d to a __u32 */
2055 if (strlen(pbuf) > 10)
2058 frac = simple_strtoull(pbuf, &end, 10);
2059 /* count decimal places */
2060 for (i = 0; i < (end - pbuf); i++)
2077 /* Specified units override the multiplier */
2079 mult = mult < 0 ? -units : units;
2082 do_div(frac, frac_d);
2083 *val = whole * mult + frac;
2087 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2088 struct file_operations *seq_fops, void *data)
2090 struct proc_dir_entry *entry;
2093 LPROCFS_WRITE_ENTRY();
2094 entry = create_proc_entry(name, mode, parent);
2096 entry->proc_fops = seq_fops;
2099 LPROCFS_WRITE_EXIT();
2106 EXPORT_SYMBOL(lprocfs_seq_create);
2108 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2110 struct file_operations *seq_fops,
2113 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2114 mode, seq_fops, data));
2116 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2118 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2120 if (value >= OBD_HIST_MAX)
2121 value = OBD_HIST_MAX - 1;
2123 cfs_spin_lock(&oh->oh_lock);
2124 oh->oh_buckets[value]++;
2125 cfs_spin_unlock(&oh->oh_lock);
2127 EXPORT_SYMBOL(lprocfs_oh_tally);
2129 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2133 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2136 lprocfs_oh_tally(oh, val);
2138 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2140 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2142 unsigned long ret = 0;
2145 for (i = 0; i < OBD_HIST_MAX; i++)
2146 ret += oh->oh_buckets[i];
2149 EXPORT_SYMBOL(lprocfs_oh_sum);
2151 void lprocfs_oh_clear(struct obd_histogram *oh)
2153 cfs_spin_lock(&oh->oh_lock);
2154 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2155 cfs_spin_unlock(&oh->oh_lock);
2157 EXPORT_SYMBOL(lprocfs_oh_clear);
2159 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2160 int count, int *eof, void *data)
2162 struct obd_device *obd = data;
2168 c += cfs_hash_debug_header(page, count);
2169 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2170 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2171 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2172 #ifdef HAVE_QUOTA_SUPPORT
2173 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2174 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2175 page + c, count - c);
2180 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2182 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2183 int count, int *eof, void *data)
2185 struct obd_device *obd = data;
2188 LASSERT(obd != NULL);
2189 LASSERT(count >= 0);
2191 /* Set start of user data returned to
2192 page + off since the user may have
2193 requested to read much smaller than
2194 what we need to read */
2195 *start = page + off;
2197 /* We know we are allocated a page here.
2198 Also we know that this function will
2199 not need to write more than a page
2200 so we can truncate at CFS_PAGE_SIZE. */
2201 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2203 /* Initialize the page */
2204 memset(page, 0, size);
2206 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2208 if (obd->obd_max_recoverable_clients == 0) {
2209 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2215 /* sampled unlocked, but really... */
2216 if (obd->obd_recovering == 0) {
2217 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2219 if (lprocfs_obd_snprintf(&page, size, &len,
2220 "recovery_start: %lu\n",
2221 obd->obd_recovery_start) <= 0)
2223 if (lprocfs_obd_snprintf(&page, size, &len,
2224 "recovery_duration: %lu\n",
2225 obd->obd_recovery_end -
2226 obd->obd_recovery_start) <= 0)
2228 /* Number of clients that have completed recovery */
2229 if (lprocfs_obd_snprintf(&page, size, &len,
2230 "completed_clients: %d/%d\n",
2231 obd->obd_max_recoverable_clients -
2232 obd->obd_stale_clients,
2233 obd->obd_max_recoverable_clients) <= 0)
2235 if (lprocfs_obd_snprintf(&page, size, &len,
2236 "replayed_requests: %d\n",
2237 obd->obd_replayed_requests) <= 0)
2239 if (lprocfs_obd_snprintf(&page, size, &len,
2240 "last_transno: "LPD64"\n",
2241 obd->obd_next_recovery_transno - 1)<=0)
2243 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2244 obd->obd_version_recov ? "ON" : "OFF")<=0)
2249 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2251 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2252 obd->obd_recovery_start) <= 0)
2254 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2255 cfs_time_current_sec() >= obd->obd_recovery_end ? 0 :
2256 obd->obd_recovery_end - cfs_time_current_sec()) <= 0)
2258 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2259 obd->obd_connected_clients,
2260 obd->obd_max_recoverable_clients) <= 0)
2262 /* Number of clients that have completed recovery */
2263 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2264 cfs_atomic_read(&obd->obd_req_replay_clients))
2267 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2268 cfs_atomic_read(&obd->obd_lock_replay_clients))
2271 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2272 obd->obd_connected_clients -
2273 cfs_atomic_read(&obd->obd_lock_replay_clients))
2276 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2277 obd->obd_stale_clients) <= 0)
2279 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2280 obd->obd_replayed_requests) <= 0)
2282 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2283 obd->obd_requests_queued_for_recovery) <= 0)
2286 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2287 obd->obd_next_recovery_transno) <= 0)
2293 return min(count, len - (int)off);
2295 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2297 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2298 int count, int *eof, void *data)
2300 struct obd_device *obd = (struct obd_device *)data;
2301 LASSERT(obd != NULL);
2303 return snprintf(page, count, "%d\n",
2304 obd->obd_recovery_timeout);
2306 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2308 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2309 unsigned long count, void *data)
2311 struct obd_device *obd = (struct obd_device *)data;
2313 LASSERT(obd != NULL);
2315 rc = lprocfs_write_helper(buffer, count, &val);
2319 obd->obd_recovery_timeout = val;
2322 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2324 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2325 int count, int *eof, void *data)
2327 struct obd_device *obd = data;
2328 LASSERT(obd != NULL);
2330 return snprintf(page, count, "%lu\n", obd->obd_recovery_time_hard);
2332 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2334 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2335 unsigned long count, void *data)
2337 struct obd_device *obd = data;
2339 LASSERT(obd != NULL);
2341 rc = lprocfs_write_helper(buffer, count, &val);
2345 obd->obd_recovery_time_hard = val;
2348 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2350 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2351 int count, int *eof, void *data)
2353 struct obd_device *obd = (struct obd_device *)data;
2355 LASSERT(obd != NULL);
2356 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2358 return snprintf(page, count, "%s\n",
2359 obd->u.obt.obt_vfsmnt->mnt_devname);
2361 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2363 EXPORT_SYMBOL(lprocfs_register);
2364 EXPORT_SYMBOL(lprocfs_srch);
2365 EXPORT_SYMBOL(lprocfs_remove);
2366 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2367 EXPORT_SYMBOL(lprocfs_add_vars);
2368 EXPORT_SYMBOL(lprocfs_obd_setup);
2369 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2370 EXPORT_SYMBOL(lprocfs_add_simple);
2371 EXPORT_SYMBOL(lprocfs_add_symlink);
2372 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2373 EXPORT_SYMBOL(lprocfs_alloc_stats);
2374 EXPORT_SYMBOL(lprocfs_free_stats);
2375 EXPORT_SYMBOL(lprocfs_clear_stats);
2376 EXPORT_SYMBOL(lprocfs_register_stats);
2377 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2378 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2379 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2380 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2381 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2382 EXPORT_SYMBOL(lprocfs_free_md_stats);
2383 EXPORT_SYMBOL(lprocfs_exp_setup);
2384 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2386 EXPORT_SYMBOL(lprocfs_rd_u64);
2387 EXPORT_SYMBOL(lprocfs_rd_atomic);
2388 EXPORT_SYMBOL(lprocfs_wr_atomic);
2389 EXPORT_SYMBOL(lprocfs_rd_uint);
2390 EXPORT_SYMBOL(lprocfs_wr_uint);
2391 EXPORT_SYMBOL(lprocfs_rd_uuid);
2392 EXPORT_SYMBOL(lprocfs_rd_name);
2393 EXPORT_SYMBOL(lprocfs_rd_fstype);
2394 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2395 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2396 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2397 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2398 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2399 EXPORT_SYMBOL(lprocfs_rd_import);
2400 EXPORT_SYMBOL(lprocfs_rd_state);
2401 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2402 EXPORT_SYMBOL(lprocfs_rd_blksize);
2403 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2404 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2405 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2406 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2407 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2409 EXPORT_SYMBOL(lprocfs_write_helper);
2410 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2411 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2412 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2413 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2414 EXPORT_SYMBOL(lprocfs_stats_collect);