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 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1555 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1556 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1557 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1558 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1559 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1560 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1561 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1562 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1563 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1564 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1565 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1566 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1567 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1568 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1569 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1570 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1571 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1572 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1573 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1574 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1575 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1576 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1577 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1578 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1579 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1580 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1581 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1582 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1583 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1584 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1585 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1586 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1589 int lprocfs_alloc_md_stats(struct obd_device *obd,
1590 unsigned num_private_stats)
1592 struct lprocfs_stats *stats;
1593 unsigned int num_stats;
1596 LASSERT(obd->md_stats == NULL);
1597 LASSERT(obd->obd_proc_entry != NULL);
1598 LASSERT(obd->md_cntr_base == 0);
1600 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1602 stats = lprocfs_alloc_stats(num_stats, 0);
1606 lprocfs_init_mps_stats(num_private_stats, stats);
1608 for (i = num_private_stats; i < num_stats; i++) {
1609 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1610 CERROR("Missing md_stat initializer md_op "
1611 "operation at offset %d. Aborting.\n",
1612 i - num_private_stats);
1616 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1618 lprocfs_free_stats(&stats);
1620 obd->md_stats = stats;
1621 obd->md_cntr_base = num_private_stats;
1626 void lprocfs_free_md_stats(struct obd_device *obd)
1628 struct lprocfs_stats *stats = obd->md_stats;
1630 if (stats != NULL) {
1631 obd->md_stats = NULL;
1632 obd->md_cntr_base = 0;
1633 lprocfs_free_stats(&stats);
1637 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1639 lprocfs_counter_init(ldlm_stats,
1640 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1641 0, "ldlm_enqueue", "reqs");
1642 lprocfs_counter_init(ldlm_stats,
1643 LDLM_CONVERT - LDLM_FIRST_OPC,
1644 0, "ldlm_convert", "reqs");
1645 lprocfs_counter_init(ldlm_stats,
1646 LDLM_CANCEL - LDLM_FIRST_OPC,
1647 0, "ldlm_cancel", "reqs");
1648 lprocfs_counter_init(ldlm_stats,
1649 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1650 0, "ldlm_bl_callback", "reqs");
1651 lprocfs_counter_init(ldlm_stats,
1652 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1653 0, "ldlm_cp_callback", "reqs");
1654 lprocfs_counter_init(ldlm_stats,
1655 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1656 0, "ldlm_gl_callback", "reqs");
1659 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1660 int *eof, void *data)
1662 struct obd_export *exp = data;
1663 LASSERT(exp != NULL);
1665 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1668 struct exp_uuid_cb_data {
1676 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1677 int count, int *eof, int *len)
1679 cb_data->page = page;
1680 cb_data->count = count;
1685 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1686 cfs_hlist_node_t *hnode, void *cb_data)
1689 struct obd_export *exp = cfs_hash_object(hs, hnode);
1690 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1692 if (exp->exp_nid_stats)
1693 *data->len += snprintf((data->page + *data->len),
1694 data->count, "%s\n",
1695 obd_uuid2str(&exp->exp_client_uuid));
1699 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1700 int *eof, void *data)
1702 struct nid_stat *stats = (struct nid_stat *)data;
1703 struct exp_uuid_cb_data cb_data;
1704 struct obd_device *obd = stats->nid_obd;
1709 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1710 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1711 lprocfs_exp_print_uuid, &cb_data);
1712 return (*cb_data.len);
1715 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1716 cfs_hlist_node_t *hnode, void *cb_data)
1719 struct exp_uuid_cb_data *data = cb_data;
1720 struct obd_export *exp = cfs_hash_object(hs, hnode);
1722 LASSERT(hs == exp->exp_lock_hash);
1724 *data->len += cfs_hash_debug_header(data->page,
1727 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1732 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1733 int *eof, void *data)
1735 struct nid_stat *stats = (struct nid_stat *)data;
1736 struct exp_uuid_cb_data cb_data;
1737 struct obd_device *obd = stats->nid_obd;
1742 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1744 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1745 lprocfs_exp_print_hash, &cb_data);
1746 return (*cb_data.len);
1749 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1750 int count, int *eof, void *data)
1753 return snprintf(page, count, "%s\n",
1754 "Write into this file to clear all nid stats and "
1755 "stale nid entries");
1757 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1759 int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1761 struct nid_stat *stat = obj;
1764 /* object has only hash + iterate_all references.
1765 * add/delete blocked by hash bucket lock */
1766 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1767 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 2) {
1768 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1769 cfs_list_move(&stat->nid_list, data);
1770 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1773 /* we has reference to object - only clear data*/
1774 if (stat->nid_stats)
1775 lprocfs_clear_stats(stat->nid_stats);
1777 if (stat->nid_brw_stats) {
1778 for (i = 0; i < BRW_LAST; i++)
1779 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1784 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1785 unsigned long count, void *data)
1787 struct obd_device *obd = (struct obd_device *)data;
1788 struct nid_stat *client_stat;
1789 CFS_LIST_HEAD(free_list);
1791 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1792 lprocfs_nid_stats_clear_write_cb, &free_list);
1794 while (!cfs_list_empty(&free_list)) {
1795 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1797 cfs_list_del_init(&client_stat->nid_list);
1798 lprocfs_free_client_stats(client_stat);
1803 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1805 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int reconnect,
1808 struct nid_stat *new_stat, *old_stat;
1809 struct obd_device *obd = NULL;
1810 cfs_proc_dir_entry_t *entry;
1811 char *buffer = NULL;
1817 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1818 !exp->exp_obd->obd_nid_stats_hash)
1821 /* not test against zero because eric say:
1822 * You may only test nid against another nid, or LNET_NID_ANY.
1823 * Anything else is nonsense.*/
1824 if (!nid || *nid == LNET_NID_ANY)
1829 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1831 OBD_ALLOC_PTR(new_stat);
1832 if (new_stat == NULL)
1835 new_stat->nid = *nid;
1836 new_stat->nid_obd = exp->exp_obd;
1837 /* we need set default refcount to 1 to balance obd_disconnect */
1838 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1840 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1841 nid, &new_stat->nid_hash);
1842 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1843 old_stat, libcfs_nid2str(*nid),
1844 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1846 /* Return -EALREADY here so that we know that the /proc
1847 * entry already has been created */
1848 if (old_stat != new_stat) {
1849 /* if this connects to the existing export of same nid,
1850 * we need to release old stats for obd_disconnect won't
1851 * balance the reference gotten in "cfs_hash_findadd_uinque" */
1852 if (reconnect && exp->exp_nid_stats)
1853 nidstat_putref(old_stat);
1855 exp->exp_nid_stats = old_stat;
1856 GOTO(destroy_new, rc = -EALREADY);
1858 /* not found - create */
1859 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1861 GOTO(destroy_new, rc = -ENOMEM);
1863 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1864 new_stat->nid_proc = lprocfs_register(buffer,
1865 obd->obd_proc_exports_entry,
1867 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1869 if (new_stat->nid_proc == NULL) {
1870 CERROR("Error making export directory for nid %s\n",
1871 libcfs_nid2str(*nid));
1872 GOTO(destroy_new_ns, rc = -ENOMEM);
1875 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1876 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1877 if (IS_ERR(entry)) {
1878 CWARN("Error adding the NID stats file\n");
1879 rc = PTR_ERR(entry);
1880 GOTO(destroy_new_ns, rc);
1883 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1884 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1885 if (IS_ERR(entry)) {
1886 CWARN("Error adding the hash file\n");
1887 rc = PTR_ERR(entry);
1888 GOTO(destroy_new_ns, rc);
1891 exp->exp_nid_stats = new_stat;
1893 /* protect competitive add to list, not need locking on destroy */
1894 cfs_spin_lock(&obd->obd_nid_lock);
1895 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1896 cfs_spin_unlock(&obd->obd_nid_lock);
1901 if (new_stat->nid_proc != NULL)
1902 lprocfs_remove(&new_stat->nid_proc);
1903 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1906 nidstat_putref(new_stat);
1907 OBD_FREE_PTR(new_stat);
1911 int lprocfs_exp_cleanup(struct obd_export *exp)
1913 struct nid_stat *stat = exp->exp_nid_stats;
1915 if(!stat || !exp->exp_obd)
1918 nidstat_putref(exp->exp_nid_stats);
1919 exp->exp_nid_stats = NULL;
1924 int lprocfs_write_helper(const char *buffer, unsigned long count,
1927 return lprocfs_write_frac_helper(buffer, count, val, 1);
1930 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1933 char kernbuf[20], *end, *pbuf;
1935 if (count > (sizeof(kernbuf) - 1))
1938 if (cfs_copy_from_user(kernbuf, buffer, count))
1941 kernbuf[count] = '\0';
1948 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1952 if (end != NULL && *end == '.') {
1953 int temp_val, pow = 1;
1957 if (strlen(pbuf) > 5)
1958 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1960 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1963 for (i = 0; i < (end - pbuf); i++)
1966 *val += temp_val / pow;
1972 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
1975 long decimal_val, frac_val;
1981 decimal_val = val / mult;
1982 prtn = snprintf(buffer, count, "%ld", decimal_val);
1983 frac_val = val % mult;
1985 if (prtn < (count - 4) && frac_val > 0) {
1987 int i, temp_mult = 1, frac_bits = 0;
1989 temp_frac = frac_val * 10;
1990 buffer[prtn++] = '.';
1991 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
1992 /* only reserved 2 bits fraction */
1993 buffer[prtn++] ='0';
1998 * Need to think these cases :
1999 * 1. #echo x.00 > /proc/xxx output result : x
2000 * 2. #echo x.0x > /proc/xxx output result : x.0x
2001 * 3. #echo x.x0 > /proc/xxx output result : x.x
2002 * 4. #echo x.xx > /proc/xxx output result : x.xx
2003 * Only reserved 2 bits fraction.
2005 for (i = 0; i < (5 - prtn); i++)
2008 frac_bits = min((int)count - prtn, 3 - frac_bits);
2009 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2010 frac_val * temp_mult / mult);
2013 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2015 if (buffer[prtn] == '.') {
2022 buffer[prtn++] ='\n';
2026 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2028 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2031 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2032 __u64 *val, int mult)
2034 char kernbuf[22], *end, *pbuf;
2035 __u64 whole, frac = 0, units;
2036 unsigned frac_d = 1;
2038 if (count > (sizeof(kernbuf) - 1))
2041 if (cfs_copy_from_user(kernbuf, buffer, count))
2044 kernbuf[count] = '\0';
2051 whole = simple_strtoull(pbuf, &end, 10);
2055 if (end != NULL && *end == '.') {
2059 /* need to limit frac_d to a __u32 */
2060 if (strlen(pbuf) > 10)
2063 frac = simple_strtoull(pbuf, &end, 10);
2064 /* count decimal places */
2065 for (i = 0; i < (end - pbuf); i++)
2082 /* Specified units override the multiplier */
2084 mult = mult < 0 ? -units : units;
2087 do_div(frac, frac_d);
2088 *val = whole * mult + frac;
2092 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2093 struct file_operations *seq_fops, void *data)
2095 struct proc_dir_entry *entry;
2098 LPROCFS_WRITE_ENTRY();
2099 entry = create_proc_entry(name, mode, parent);
2101 entry->proc_fops = seq_fops;
2104 LPROCFS_WRITE_EXIT();
2111 EXPORT_SYMBOL(lprocfs_seq_create);
2113 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2115 struct file_operations *seq_fops,
2118 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2119 mode, seq_fops, data));
2121 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2123 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2125 if (value >= OBD_HIST_MAX)
2126 value = OBD_HIST_MAX - 1;
2128 cfs_spin_lock(&oh->oh_lock);
2129 oh->oh_buckets[value]++;
2130 cfs_spin_unlock(&oh->oh_lock);
2132 EXPORT_SYMBOL(lprocfs_oh_tally);
2134 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2138 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2141 lprocfs_oh_tally(oh, val);
2143 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2145 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2147 unsigned long ret = 0;
2150 for (i = 0; i < OBD_HIST_MAX; i++)
2151 ret += oh->oh_buckets[i];
2154 EXPORT_SYMBOL(lprocfs_oh_sum);
2156 void lprocfs_oh_clear(struct obd_histogram *oh)
2158 cfs_spin_lock(&oh->oh_lock);
2159 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2160 cfs_spin_unlock(&oh->oh_lock);
2162 EXPORT_SYMBOL(lprocfs_oh_clear);
2164 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2165 int count, int *eof, void *data)
2167 struct obd_device *obd = data;
2173 c += cfs_hash_debug_header(page, count);
2174 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2175 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2176 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2177 #ifdef HAVE_QUOTA_SUPPORT
2178 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2179 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2180 page + c, count - c);
2185 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2187 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2188 int count, int *eof, void *data)
2190 struct obd_device *obd = data;
2193 LASSERT(obd != NULL);
2194 LASSERT(count >= 0);
2196 /* Set start of user data returned to
2197 page + off since the user may have
2198 requested to read much smaller than
2199 what we need to read */
2200 *start = page + off;
2202 /* We know we are allocated a page here.
2203 Also we know that this function will
2204 not need to write more than a page
2205 so we can truncate at CFS_PAGE_SIZE. */
2206 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2208 /* Initialize the page */
2209 memset(page, 0, size);
2211 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2213 if (obd->obd_max_recoverable_clients == 0) {
2214 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2220 /* sampled unlocked, but really... */
2221 if (obd->obd_recovering == 0) {
2222 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2224 if (lprocfs_obd_snprintf(&page, size, &len,
2225 "recovery_start: %lu\n",
2226 obd->obd_recovery_start) <= 0)
2228 if (lprocfs_obd_snprintf(&page, size, &len,
2229 "recovery_duration: %lu\n",
2230 obd->obd_recovery_end -
2231 obd->obd_recovery_start) <= 0)
2233 /* Number of clients that have completed recovery */
2234 if (lprocfs_obd_snprintf(&page, size, &len,
2235 "completed_clients: %d/%d\n",
2236 obd->obd_max_recoverable_clients -
2237 obd->obd_stale_clients,
2238 obd->obd_max_recoverable_clients) <= 0)
2240 if (lprocfs_obd_snprintf(&page, size, &len,
2241 "replayed_requests: %d\n",
2242 obd->obd_replayed_requests) <= 0)
2244 if (lprocfs_obd_snprintf(&page, size, &len,
2245 "last_transno: "LPD64"\n",
2246 obd->obd_next_recovery_transno - 1)<=0)
2248 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2249 obd->obd_version_recov ? "ON" : "OFF")<=0)
2254 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2256 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2257 obd->obd_recovery_start) <= 0)
2259 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2260 cfs_time_current_sec() >= obd->obd_recovery_end ? 0 :
2261 obd->obd_recovery_end - cfs_time_current_sec()) <= 0)
2263 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2264 obd->obd_connected_clients,
2265 obd->obd_max_recoverable_clients) <= 0)
2267 /* Number of clients that have completed recovery */
2268 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2269 cfs_atomic_read(&obd->obd_req_replay_clients))
2272 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2273 cfs_atomic_read(&obd->obd_lock_replay_clients))
2276 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2277 obd->obd_connected_clients -
2278 cfs_atomic_read(&obd->obd_lock_replay_clients))
2281 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2282 obd->obd_stale_clients) <= 0)
2284 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2285 obd->obd_replayed_requests) <= 0)
2287 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2288 obd->obd_requests_queued_for_recovery) <= 0)
2291 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2292 obd->obd_next_recovery_transno) <= 0)
2298 return min(count, len - (int)off);
2300 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2302 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2303 int count, int *eof, void *data)
2305 struct obd_device *obd = (struct obd_device *)data;
2306 LASSERT(obd != NULL);
2308 return snprintf(page, count, "%d\n",
2309 obd->obd_recovery_timeout);
2311 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2313 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2314 unsigned long count, void *data)
2316 struct obd_device *obd = (struct obd_device *)data;
2318 LASSERT(obd != NULL);
2320 rc = lprocfs_write_helper(buffer, count, &val);
2324 obd->obd_recovery_timeout = val;
2327 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2329 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2330 int count, int *eof, void *data)
2332 struct obd_device *obd = data;
2333 LASSERT(obd != NULL);
2335 return snprintf(page, count, "%lu\n", obd->obd_recovery_time_hard);
2337 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2339 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2340 unsigned long count, void *data)
2342 struct obd_device *obd = data;
2344 LASSERT(obd != NULL);
2346 rc = lprocfs_write_helper(buffer, count, &val);
2350 obd->obd_recovery_time_hard = val;
2353 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2355 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2356 int count, int *eof, void *data)
2358 struct obd_device *obd = (struct obd_device *)data;
2360 LASSERT(obd != NULL);
2361 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2363 return snprintf(page, count, "%s\n",
2364 obd->u.obt.obt_vfsmnt->mnt_devname);
2366 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2368 EXPORT_SYMBOL(lprocfs_register);
2369 EXPORT_SYMBOL(lprocfs_srch);
2370 EXPORT_SYMBOL(lprocfs_remove);
2371 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2372 EXPORT_SYMBOL(lprocfs_add_vars);
2373 EXPORT_SYMBOL(lprocfs_obd_setup);
2374 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2375 EXPORT_SYMBOL(lprocfs_add_simple);
2376 EXPORT_SYMBOL(lprocfs_add_symlink);
2377 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2378 EXPORT_SYMBOL(lprocfs_alloc_stats);
2379 EXPORT_SYMBOL(lprocfs_free_stats);
2380 EXPORT_SYMBOL(lprocfs_clear_stats);
2381 EXPORT_SYMBOL(lprocfs_register_stats);
2382 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2383 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2384 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2385 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2386 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2387 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2388 EXPORT_SYMBOL(lprocfs_free_md_stats);
2389 EXPORT_SYMBOL(lprocfs_exp_setup);
2390 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2392 EXPORT_SYMBOL(lprocfs_rd_u64);
2393 EXPORT_SYMBOL(lprocfs_rd_atomic);
2394 EXPORT_SYMBOL(lprocfs_wr_atomic);
2395 EXPORT_SYMBOL(lprocfs_rd_uint);
2396 EXPORT_SYMBOL(lprocfs_wr_uint);
2397 EXPORT_SYMBOL(lprocfs_rd_uuid);
2398 EXPORT_SYMBOL(lprocfs_rd_name);
2399 EXPORT_SYMBOL(lprocfs_rd_fstype);
2400 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2401 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2402 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2403 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2404 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2405 EXPORT_SYMBOL(lprocfs_rd_import);
2406 EXPORT_SYMBOL(lprocfs_rd_state);
2407 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2408 EXPORT_SYMBOL(lprocfs_rd_blksize);
2409 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2410 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2411 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2412 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2413 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2415 EXPORT_SYMBOL(lprocfs_write_helper);
2416 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2417 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2418 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2419 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2420 EXPORT_SYMBOL(lprocfs_stats_collect);