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 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
706 for (i = 0; i < num_cpu; i++) {
707 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
710 centry = cfs_atomic_read(&percpu_cntr-> \
712 t.lc_count = percpu_cntr->lc_count;
713 t.lc_sum = percpu_cntr->lc_sum;
714 t.lc_min = percpu_cntr->lc_min;
715 t.lc_max = percpu_cntr->lc_max;
716 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
717 } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
719 centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
721 cnt->lc_count += t.lc_count;
722 cnt->lc_sum += t.lc_sum;
723 if (t.lc_min < cnt->lc_min)
724 cnt->lc_min = t.lc_min;
725 if (t.lc_max > cnt->lc_max)
726 cnt->lc_max = t.lc_max;
727 cnt->lc_sumsquare += t.lc_sumsquare;
730 cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
731 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
735 * Append a space separated list of current set flags to str.
737 #define flag2str(flag) \
738 if (imp->imp_##flag && max - len > 0) \
739 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
740 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
744 if (imp->imp_obd->obd_no_recov)
745 len += snprintf(str, max - len, "no_recov");
749 flag2str(replayable);
755 static const char *obd_connect_names[] = {
769 "join_file(obsolete)",
773 "remote_client_by_force",
782 "mds_mds_connection",
785 "alt_checksum_algorithm",
797 static int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
802 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
804 ret += snprintf(page + ret, count - ret, "%s%s",
805 ret ? sep : "", obd_connect_names[i]);
807 if (flags & ~(mask - 1))
808 ret += snprintf(page + ret, count - ret,
809 "%sunknown flags "LPX64,
810 ret ? sep : "", flags & ~(mask - 1));
814 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
815 int *eof, void *data)
817 struct lprocfs_counter ret;
818 struct obd_device *obd = (struct obd_device *)data;
819 struct obd_import *imp;
820 struct obd_import_conn *conn;
823 LASSERT(obd != NULL);
824 LPROCFS_CLIMP_CHECK(obd);
825 imp = obd->u.cli.cl_import;
828 i = snprintf(page, count,
836 ptlrpc_import_state_name(imp->imp_state));
837 i += obd_connect_flags2str(page + i, count - i,
838 imp->imp_connect_data.ocd_connect_flags,
840 i += snprintf(page + i, count - i,
843 i += obd_import_flags2str(imp, page + i, count - i);
845 i += snprintf(page + i, count - i,
848 " failover_nids: [");
849 cfs_spin_lock(&imp->imp_lock);
851 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
852 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
853 libcfs_nid2str(conn->oic_conn->c_peer.nid));
856 cfs_spin_unlock(&imp->imp_lock);
857 i += snprintf(page + i, count - i,
859 " current_connection: %s\n"
860 " connection_attempts: %u\n"
862 " in-progress_invalidations: %u\n",
863 libcfs_nid2str(imp->imp_connection->c_peer.nid),
866 cfs_atomic_read(&imp->imp_inval_count));
868 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
869 if (ret.lc_count != 0) {
870 /* first argument to do_div MUST be __u64 */
871 __u64 sum = ret.lc_sum;
872 do_div(sum, ret.lc_count);
876 i += snprintf(page + i, count - i,
879 " unregistering: %u\n"
881 " avg_waittime: "LPU64" %s\n",
882 cfs_atomic_read(&imp->imp_inflight),
883 cfs_atomic_read(&imp->imp_unregistering),
884 cfs_atomic_read(&imp->imp_timeouts),
885 ret.lc_sum, ret.lc_units);
888 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
889 if (imp->imp_at.iat_portal[j] == 0)
891 k = max_t(unsigned int, k,
892 at_get(&imp->imp_at.iat_service_estimate[j]));
894 i += snprintf(page + i, count - i,
895 " service_estimates:\n"
896 " services: %u sec\n"
897 " network: %u sec\n",
899 at_get(&imp->imp_at.iat_net_latency));
901 i += snprintf(page + i, count - i,
903 " last_replay: "LPU64"\n"
904 " peer_committed: "LPU64"\n"
905 " last_checked: "LPU64"\n",
906 imp->imp_last_replay_transno,
907 imp->imp_peer_committed_transno,
908 imp->imp_last_transno_checked);
911 for (rw = 0; rw <= 1; rw++) {
912 lprocfs_stats_collect(obd->obd_svc_stats,
913 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
915 if (ret.lc_sum > 0 && ret.lc_count > 0) {
916 /* first argument to do_div MUST be __u64 */
917 __u64 sum = ret.lc_sum;
918 do_div(sum, ret.lc_count);
920 i += snprintf(page + i, count - i,
921 " %s_data_averages:\n"
922 " bytes_per_rpc: "LPU64"\n",
923 rw ? "write" : "read",
927 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
928 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
929 if (ret.lc_sum > 0 && ret.lc_count != 0) {
930 /* first argument to do_div MUST be __u64 */
931 __u64 sum = ret.lc_sum;
932 do_div(sum, ret.lc_count);
934 i += snprintf(page + i, count - i,
935 " %s_per_rpc: "LPU64"\n",
936 ret.lc_units, ret.lc_sum);
939 i += snprintf(page + i, count - i,
940 " MB_per_sec: %u.%.02u\n",
941 k / j, (100 * k / j) % 100);
945 LPROCFS_CLIMP_EXIT(obd);
949 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
950 int *eof, void *data)
952 struct obd_device *obd = (struct obd_device *)data;
953 struct obd_import *imp;
956 LASSERT(obd != NULL);
957 LPROCFS_CLIMP_CHECK(obd);
958 imp = obd->u.cli.cl_import;
961 i = snprintf(page, count, "current_state: %s\n",
962 ptlrpc_import_state_name(imp->imp_state));
963 i += snprintf(page + i, count - i,
965 k = imp->imp_state_hist_idx;
966 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
967 struct import_state_hist *ish =
968 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
969 if (ish->ish_state == 0)
971 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
973 ptlrpc_import_state_name(ish->ish_state));
976 LPROCFS_CLIMP_EXIT(obd);
980 int lprocfs_at_hist_helper(char *page, int count, int rc,
981 struct adaptive_timeout *at)
984 for (i = 0; i < AT_BINS; i++)
985 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
986 rc += snprintf(page + rc, count - rc, "\n");
990 /* See also ptlrpc_lprocfs_rd_timeouts */
991 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
992 int *eof, void *data)
994 struct obd_device *obd = (struct obd_device *)data;
995 struct obd_import *imp;
996 unsigned int cur, worst;
1001 LASSERT(obd != NULL);
1002 LPROCFS_CLIMP_CHECK(obd);
1003 imp = obd->u.cli.cl_import;
1006 now = cfs_time_current_sec();
1008 /* Some network health info for kicks */
1009 s2dhms(&ts, now - imp->imp_last_reply_time);
1010 rc += snprintf(page + rc, count - rc,
1011 "%-10s : %ld, "DHMS_FMT" ago\n",
1012 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1014 cur = at_get(&imp->imp_at.iat_net_latency);
1015 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1016 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1017 s2dhms(&ts, now - worstt);
1018 rc += snprintf(page + rc, count - rc,
1019 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1020 "network", cur, worst, worstt, DHMS_VARS(&ts));
1021 rc = lprocfs_at_hist_helper(page, count, rc,
1022 &imp->imp_at.iat_net_latency);
1024 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1025 if (imp->imp_at.iat_portal[i] == 0)
1027 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1028 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1029 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1030 s2dhms(&ts, now - worstt);
1031 rc += snprintf(page + rc, count - rc,
1032 "portal %-2d : cur %3u worst %3u (at %ld, "
1033 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1034 cur, worst, worstt, DHMS_VARS(&ts));
1035 rc = lprocfs_at_hist_helper(page, count, rc,
1036 &imp->imp_at.iat_service_estimate[i]);
1039 LPROCFS_CLIMP_EXIT(obd);
1043 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1044 int count, int *eof, void *data)
1046 struct obd_device *obd = data;
1050 LPROCFS_CLIMP_CHECK(obd);
1051 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1052 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1053 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1054 ret += snprintf(page + ret, count - ret, "\n");
1055 LPROCFS_CLIMP_EXIT(obd);
1058 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1060 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1061 int *eof, void *data)
1063 struct obd_device *obd = data;
1065 LASSERT(obd != NULL);
1067 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1070 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1071 int *eof, void *data)
1073 struct obd_type *class = (struct obd_type*) data;
1075 LASSERT(class != NULL);
1077 return snprintf(page, count, "%d\n", class->typ_refcnt);
1080 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1084 LASSERT(obd != NULL);
1085 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1086 LASSERT(obd->obd_type->typ_procroot != NULL);
1088 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1089 obd->obd_type->typ_procroot,
1091 if (IS_ERR(obd->obd_proc_entry)) {
1092 rc = PTR_ERR(obd->obd_proc_entry);
1093 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1094 obd->obd_proc_entry = NULL;
1099 int lprocfs_obd_cleanup(struct obd_device *obd)
1103 if (obd->obd_proc_exports_entry) {
1104 /* Should be no exports left */
1105 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1106 lprocfs_remove(&obd->obd_proc_exports_entry);
1107 obd->obd_proc_exports_entry = NULL;
1109 if (obd->obd_proc_entry) {
1110 lprocfs_remove(&obd->obd_proc_entry);
1111 obd->obd_proc_entry = NULL;
1116 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1118 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1119 client_stat->nid_proc, client_stat->nid_stats,
1120 client_stat->nid_brw_stats);
1122 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1124 cfs_atomic_read(&client_stat->nid_exp_ref_count));
1126 cfs_hlist_del_init(&client_stat->nid_hash);
1128 if (client_stat->nid_proc)
1129 lprocfs_remove(&client_stat->nid_proc);
1131 if (client_stat->nid_stats)
1132 lprocfs_free_stats(&client_stat->nid_stats);
1134 if (client_stat->nid_brw_stats)
1135 OBD_FREE_PTR(client_stat->nid_brw_stats);
1137 if (client_stat->nid_ldlm_stats)
1138 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1140 OBD_FREE_PTR(client_stat);
1145 void lprocfs_free_per_client_stats(struct obd_device *obd)
1147 struct nid_stat *stat;
1150 /* we need extra list - because hash_exit called to early */
1151 /* not need locking because all clients is died */
1152 while(!cfs_list_empty(&obd->obd_nid_stats)) {
1153 stat = cfs_list_entry(obd->obd_nid_stats.next,
1154 struct nid_stat, nid_list);
1155 cfs_list_del_init(&stat->nid_list);
1156 lprocfs_free_client_stats(stat);
1162 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1163 enum lprocfs_stats_flags flags)
1165 struct lprocfs_stats *stats;
1166 unsigned int percpusize;
1168 unsigned int num_cpu;
1173 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1176 num_cpu = cfs_num_possible_cpus();
1178 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1182 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1183 stats->ls_flags = flags;
1184 cfs_spin_lock_init(&stats->ls_lock);
1185 /* Use this lock only if there are no percpu areas */
1187 stats->ls_flags = 0;
1190 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1192 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1194 for (i = 0; i < num_cpu; i++) {
1195 OBD_ALLOC(stats->ls_percpu[i], percpusize);
1196 if (stats->ls_percpu[i] == NULL) {
1197 for (j = 0; j < i; j++) {
1198 OBD_FREE(stats->ls_percpu[j], percpusize);
1199 stats->ls_percpu[j] = NULL;
1204 if (stats->ls_percpu[0] == NULL) {
1205 OBD_FREE(stats, offsetof(typeof(*stats),
1206 ls_percpu[num_cpu]));
1210 stats->ls_num = num;
1214 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1216 struct lprocfs_stats *stats = *statsh;
1217 unsigned int num_cpu;
1218 unsigned int percpusize;
1221 if (stats == NULL || stats->ls_num == 0)
1225 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1228 num_cpu = cfs_num_possible_cpus();
1230 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1232 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1233 for (i = 0; i < num_cpu; i++)
1234 OBD_FREE(stats->ls_percpu[i], percpusize);
1235 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1238 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1240 struct lprocfs_counter *percpu_cntr;
1242 unsigned int num_cpu;
1244 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1246 for (i = 0; i < num_cpu; i++) {
1247 for (j = 0; j < stats->ls_num; j++) {
1248 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1249 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1250 percpu_cntr->lc_count = 0;
1251 percpu_cntr->lc_sum = 0;
1252 percpu_cntr->lc_min = LC_MIN_INIT;
1253 percpu_cntr->lc_max = 0;
1254 percpu_cntr->lc_sumsquare = 0;
1255 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1259 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1262 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1263 size_t len, loff_t *off)
1265 struct seq_file *seq = file->private_data;
1266 struct lprocfs_stats *stats = seq->private;
1268 lprocfs_clear_stats(stats);
1273 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1275 struct lprocfs_stats *stats = p->private;
1276 /* return 1st cpu location */
1277 return (*pos >= stats->ls_num) ? NULL :
1278 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1281 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1285 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1287 struct lprocfs_stats *stats = p->private;
1289 return (*pos >= stats->ls_num) ? NULL :
1290 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1293 /* seq file export of one lprocfs counter */
1294 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1296 struct lprocfs_stats *stats = p->private;
1297 struct lprocfs_counter *cntr = v;
1298 struct lprocfs_counter ret;
1301 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1303 cfs_gettimeofday(&now);
1304 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1305 "snapshot_time", now.tv_sec, now.tv_usec);
1309 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1311 lprocfs_stats_collect(stats, idx, &ret);
1313 if (ret.lc_count == 0)
1316 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1317 ret.lc_count, cntr->lc_units);
1322 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1323 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1324 ret.lc_min, ret.lc_max, ret.lc_sum);
1327 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1328 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1332 rc = seq_printf(p, "\n");
1334 return (rc < 0) ? rc : 0;
1337 struct seq_operations lprocfs_stats_seq_sops = {
1338 start: lprocfs_stats_seq_start,
1339 stop: lprocfs_stats_seq_stop,
1340 next: lprocfs_stats_seq_next,
1341 show: lprocfs_stats_seq_show,
1344 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1346 struct proc_dir_entry *dp = PDE(inode);
1347 struct seq_file *seq;
1350 if (LPROCFS_ENTRY_AND_CHECK(dp))
1353 rc = seq_open(file, &lprocfs_stats_seq_sops);
1358 seq = file->private_data;
1359 seq->private = dp->data;
1363 struct file_operations lprocfs_stats_seq_fops = {
1364 .owner = THIS_MODULE,
1365 .open = lprocfs_stats_seq_open,
1367 .write = lprocfs_stats_seq_write,
1368 .llseek = seq_lseek,
1369 .release = lprocfs_seq_release,
1372 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1373 struct lprocfs_stats *stats)
1375 struct proc_dir_entry *entry;
1376 LASSERT(root != NULL);
1378 LPROCFS_WRITE_ENTRY();
1379 entry = create_proc_entry(name, 0644, root);
1381 entry->proc_fops = &lprocfs_stats_seq_fops;
1382 entry->data = stats;
1385 LPROCFS_WRITE_EXIT();
1393 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1394 unsigned conf, const char *name, const char *units)
1396 struct lprocfs_counter *c;
1398 unsigned int num_cpu;
1400 LASSERT(stats != NULL);
1402 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1404 for (i = 0; i < num_cpu; i++) {
1405 c = &(stats->ls_percpu[i]->lp_cntr[index]);
1406 c->lc_config = conf;
1409 c->lc_min = LC_MIN_INIT;
1412 c->lc_units = units;
1415 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1417 EXPORT_SYMBOL(lprocfs_counter_init);
1419 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1421 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1422 LASSERT(coffset < stats->ls_num); \
1423 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1426 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1428 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1429 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1430 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1431 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1432 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1433 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1434 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1435 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1436 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1437 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1438 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1439 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1440 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1441 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1442 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1443 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1444 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1445 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1446 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1447 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1448 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1449 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1450 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1451 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1452 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1453 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1454 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1455 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1456 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1457 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1458 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1459 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1460 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1461 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1462 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1463 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1467 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1468 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1469 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1470 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1471 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1472 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1473 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1474 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1475 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1476 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1477 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1478 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1479 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1480 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1481 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1482 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1483 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1484 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1485 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1486 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1487 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1488 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1489 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1490 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1491 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1492 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1493 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1494 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1495 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1496 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1499 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1501 struct lprocfs_stats *stats;
1502 unsigned int num_stats;
1505 LASSERT(obd->obd_stats == NULL);
1506 LASSERT(obd->obd_proc_entry != NULL);
1507 LASSERT(obd->obd_cntr_base == 0);
1509 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1510 num_private_stats - 1 /* o_owner */;
1511 stats = lprocfs_alloc_stats(num_stats, 0);
1515 lprocfs_init_ops_stats(num_private_stats, stats);
1517 for (i = num_private_stats; i < num_stats; i++) {
1518 /* If this LBUGs, it is likely that an obd
1519 * operation was added to struct obd_ops in
1520 * <obd.h>, and that the corresponding line item
1521 * LPROCFS_OBD_OP_INIT(.., .., opname)
1522 * is missing from the list above. */
1523 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1524 "Missing obd_stat initializer obd_op "
1525 "operation at offset %d.\n", i - num_private_stats);
1527 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1529 lprocfs_free_stats(&stats);
1531 obd->obd_stats = stats;
1532 obd->obd_cntr_base = num_private_stats;
1537 void lprocfs_free_obd_stats(struct obd_device *obd)
1540 lprocfs_free_stats(&obd->obd_stats);
1543 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1545 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1546 LASSERT(coffset < stats->ls_num); \
1547 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1550 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1552 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1553 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1554 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1555 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1556 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1557 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1558 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1559 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1560 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1561 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1562 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1563 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1564 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1565 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1566 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1567 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1568 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1569 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1570 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1571 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1572 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1573 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1574 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1575 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1576 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1577 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1578 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1579 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1580 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1581 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1582 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1583 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1586 int lprocfs_alloc_md_stats(struct obd_device *obd,
1587 unsigned num_private_stats)
1589 struct lprocfs_stats *stats;
1590 unsigned int num_stats;
1593 LASSERT(obd->md_stats == NULL);
1594 LASSERT(obd->obd_proc_entry != NULL);
1595 LASSERT(obd->md_cntr_base == 0);
1597 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1599 stats = lprocfs_alloc_stats(num_stats, 0);
1603 lprocfs_init_mps_stats(num_private_stats, stats);
1605 for (i = num_private_stats; i < num_stats; i++) {
1606 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1607 CERROR("Missing md_stat initializer md_op "
1608 "operation at offset %d. Aborting.\n",
1609 i - num_private_stats);
1613 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1615 lprocfs_free_stats(&stats);
1617 obd->md_stats = stats;
1618 obd->md_cntr_base = num_private_stats;
1623 void lprocfs_free_md_stats(struct obd_device *obd)
1625 struct lprocfs_stats *stats = obd->md_stats;
1627 if (stats != NULL) {
1628 obd->md_stats = NULL;
1629 obd->md_cntr_base = 0;
1630 lprocfs_free_stats(&stats);
1634 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1636 lprocfs_counter_init(ldlm_stats,
1637 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1638 0, "ldlm_enqueue", "reqs");
1639 lprocfs_counter_init(ldlm_stats,
1640 LDLM_CONVERT - LDLM_FIRST_OPC,
1641 0, "ldlm_convert", "reqs");
1642 lprocfs_counter_init(ldlm_stats,
1643 LDLM_CANCEL - LDLM_FIRST_OPC,
1644 0, "ldlm_cancel", "reqs");
1645 lprocfs_counter_init(ldlm_stats,
1646 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1647 0, "ldlm_bl_callback", "reqs");
1648 lprocfs_counter_init(ldlm_stats,
1649 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1650 0, "ldlm_cp_callback", "reqs");
1651 lprocfs_counter_init(ldlm_stats,
1652 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1653 0, "ldlm_gl_callback", "reqs");
1656 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1657 int *eof, void *data)
1659 struct obd_export *exp = data;
1660 LASSERT(exp != NULL);
1662 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1665 struct exp_uuid_cb_data {
1673 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1674 int count, int *eof, int *len)
1676 cb_data->page = page;
1677 cb_data->count = count;
1682 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1683 cfs_hlist_node_t *hnode, void *cb_data)
1686 struct obd_export *exp = cfs_hash_object(hs, hnode);
1687 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1689 if (exp->exp_nid_stats)
1690 *data->len += snprintf((data->page + *data->len),
1691 data->count, "%s\n",
1692 obd_uuid2str(&exp->exp_client_uuid));
1696 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1697 int *eof, void *data)
1699 struct nid_stat *stats = (struct nid_stat *)data;
1700 struct exp_uuid_cb_data cb_data;
1701 struct obd_device *obd = stats->nid_obd;
1706 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1707 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1708 lprocfs_exp_print_uuid, &cb_data);
1709 return (*cb_data.len);
1712 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1713 cfs_hlist_node_t *hnode, void *cb_data)
1716 struct exp_uuid_cb_data *data = cb_data;
1717 struct obd_export *exp = cfs_hash_object(hs, hnode);
1719 if (exp->exp_lock_hash != NULL) {
1721 *data->len += cfs_hash_debug_header(data->page,
1724 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1731 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1732 int *eof, void *data)
1734 struct nid_stat *stats = (struct nid_stat *)data;
1735 struct exp_uuid_cb_data cb_data;
1736 struct obd_device *obd = stats->nid_obd;
1741 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1743 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1744 lprocfs_exp_print_hash, &cb_data);
1745 return (*cb_data.len);
1748 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1749 int count, int *eof, void *data)
1752 return snprintf(page, count, "%s\n",
1753 "Write into this file to clear all nid stats and "
1754 "stale nid entries");
1756 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1758 int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1760 struct nid_stat *stat = obj;
1764 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1765 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1766 /* object has only hash references. */
1767 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1768 cfs_list_move(&stat->nid_list, data);
1769 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1772 /* we has reference to object - only clear data*/
1773 if (stat->nid_stats)
1774 lprocfs_clear_stats(stat->nid_stats);
1776 if (stat->nid_brw_stats) {
1777 for (i = 0; i < BRW_LAST; i++)
1778 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1783 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1784 unsigned long count, void *data)
1786 struct obd_device *obd = (struct obd_device *)data;
1787 struct nid_stat *client_stat;
1788 CFS_LIST_HEAD(free_list);
1790 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1791 lprocfs_nid_stats_clear_write_cb, &free_list);
1793 while (!cfs_list_empty(&free_list)) {
1794 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1796 cfs_list_del_init(&client_stat->nid_list);
1797 lprocfs_free_client_stats(client_stat);
1802 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1804 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int reconnect,
1807 struct nid_stat *new_stat, *old_stat;
1808 struct obd_device *obd = NULL;
1809 cfs_proc_dir_entry_t *entry;
1810 char *buffer = NULL;
1816 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1817 !exp->exp_obd->obd_nid_stats_hash)
1820 /* not test against zero because eric say:
1821 * You may only test nid against another nid, or LNET_NID_ANY.
1822 * Anything else is nonsense.*/
1823 if (!nid || *nid == LNET_NID_ANY)
1828 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1830 OBD_ALLOC_PTR(new_stat);
1831 if (new_stat == NULL)
1834 new_stat->nid = *nid;
1835 new_stat->nid_obd = exp->exp_obd;
1836 /* we need set default refcount to 1 to balance obd_disconnect */
1837 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1839 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1840 nid, &new_stat->nid_hash);
1841 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1842 old_stat, libcfs_nid2str(*nid),
1843 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1845 /* Return -EALREADY here so that we know that the /proc
1846 * entry already has been created */
1847 if (old_stat != new_stat) {
1848 /* if this connects to the existing export of same nid,
1849 * we need to release old stats for obd_disconnect won't
1850 * balance the reference gotten in "cfs_hash_findadd_uinque" */
1851 if (reconnect && exp->exp_nid_stats)
1852 nidstat_putref(old_stat);
1854 exp->exp_nid_stats = old_stat;
1855 GOTO(destroy_new, rc = -EALREADY);
1857 /* not found - create */
1858 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1860 GOTO(destroy_new, rc = -ENOMEM);
1862 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1863 new_stat->nid_proc = lprocfs_register(buffer,
1864 obd->obd_proc_exports_entry,
1866 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1868 if (new_stat->nid_proc == NULL) {
1869 CERROR("Error making export directory for nid %s\n",
1870 libcfs_nid2str(*nid));
1871 GOTO(destroy_new_ns, rc = -ENOMEM);
1874 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1875 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1876 if (IS_ERR(entry)) {
1877 CWARN("Error adding the NID stats file\n");
1878 rc = PTR_ERR(entry);
1879 GOTO(destroy_new_ns, rc);
1882 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1883 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1884 if (IS_ERR(entry)) {
1885 CWARN("Error adding the hash file\n");
1886 rc = PTR_ERR(entry);
1887 GOTO(destroy_new_ns, rc);
1890 exp->exp_nid_stats = new_stat;
1892 /* protect competitive add to list, not need locking on destroy */
1893 cfs_spin_lock(&obd->obd_nid_lock);
1894 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1895 cfs_spin_unlock(&obd->obd_nid_lock);
1900 if (new_stat->nid_proc != NULL)
1901 lprocfs_remove(&new_stat->nid_proc);
1902 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1905 nidstat_putref(new_stat);
1906 OBD_FREE_PTR(new_stat);
1910 int lprocfs_exp_cleanup(struct obd_export *exp)
1912 struct nid_stat *stat = exp->exp_nid_stats;
1914 if(!stat || !exp->exp_obd)
1917 nidstat_putref(exp->exp_nid_stats);
1918 exp->exp_nid_stats = NULL;
1923 int lprocfs_write_helper(const char *buffer, unsigned long count,
1926 return lprocfs_write_frac_helper(buffer, count, val, 1);
1929 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1932 char kernbuf[20], *end, *pbuf;
1934 if (count > (sizeof(kernbuf) - 1))
1937 if (cfs_copy_from_user(kernbuf, buffer, count))
1940 kernbuf[count] = '\0';
1947 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1951 if (end != NULL && *end == '.') {
1952 int temp_val, pow = 1;
1956 if (strlen(pbuf) > 5)
1957 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1959 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1962 for (i = 0; i < (end - pbuf); i++)
1965 *val += temp_val / pow;
1971 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
1974 long decimal_val, frac_val;
1980 decimal_val = val / mult;
1981 prtn = snprintf(buffer, count, "%ld", decimal_val);
1982 frac_val = val % mult;
1984 if (prtn < (count - 4) && frac_val > 0) {
1986 int i, temp_mult = 1, frac_bits = 0;
1988 temp_frac = frac_val * 10;
1989 buffer[prtn++] = '.';
1990 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
1991 /* only reserved 2 bits fraction */
1992 buffer[prtn++] ='0';
1997 * Need to think these cases :
1998 * 1. #echo x.00 > /proc/xxx output result : x
1999 * 2. #echo x.0x > /proc/xxx output result : x.0x
2000 * 3. #echo x.x0 > /proc/xxx output result : x.x
2001 * 4. #echo x.xx > /proc/xxx output result : x.xx
2002 * Only reserved 2 bits fraction.
2004 for (i = 0; i < (5 - prtn); i++)
2007 frac_bits = min((int)count - prtn, 3 - frac_bits);
2008 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2009 frac_val * temp_mult / mult);
2012 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2014 if (buffer[prtn] == '.') {
2021 buffer[prtn++] ='\n';
2025 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2027 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2030 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2031 __u64 *val, int mult)
2033 char kernbuf[22], *end, *pbuf;
2034 __u64 whole, frac = 0, units;
2035 unsigned frac_d = 1;
2037 if (count > (sizeof(kernbuf) - 1))
2040 if (cfs_copy_from_user(kernbuf, buffer, count))
2043 kernbuf[count] = '\0';
2050 whole = simple_strtoull(pbuf, &end, 10);
2054 if (end != NULL && *end == '.') {
2058 /* need to limit frac_d to a __u32 */
2059 if (strlen(pbuf) > 10)
2062 frac = simple_strtoull(pbuf, &end, 10);
2063 /* count decimal places */
2064 for (i = 0; i < (end - pbuf); i++)
2081 /* Specified units override the multiplier */
2083 mult = mult < 0 ? -units : units;
2086 do_div(frac, frac_d);
2087 *val = whole * mult + frac;
2091 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2092 struct file_operations *seq_fops, void *data)
2094 struct proc_dir_entry *entry;
2097 LPROCFS_WRITE_ENTRY();
2098 entry = create_proc_entry(name, mode, parent);
2100 entry->proc_fops = seq_fops;
2103 LPROCFS_WRITE_EXIT();
2110 EXPORT_SYMBOL(lprocfs_seq_create);
2112 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2114 struct file_operations *seq_fops,
2117 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2118 mode, seq_fops, data));
2120 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2122 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2124 if (value >= OBD_HIST_MAX)
2125 value = OBD_HIST_MAX - 1;
2127 cfs_spin_lock(&oh->oh_lock);
2128 oh->oh_buckets[value]++;
2129 cfs_spin_unlock(&oh->oh_lock);
2131 EXPORT_SYMBOL(lprocfs_oh_tally);
2133 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2137 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2140 lprocfs_oh_tally(oh, val);
2142 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2144 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2146 unsigned long ret = 0;
2149 for (i = 0; i < OBD_HIST_MAX; i++)
2150 ret += oh->oh_buckets[i];
2153 EXPORT_SYMBOL(lprocfs_oh_sum);
2155 void lprocfs_oh_clear(struct obd_histogram *oh)
2157 cfs_spin_lock(&oh->oh_lock);
2158 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2159 cfs_spin_unlock(&oh->oh_lock);
2161 EXPORT_SYMBOL(lprocfs_oh_clear);
2163 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2164 int count, int *eof, void *data)
2166 struct obd_device *obd = data;
2172 c += cfs_hash_debug_header(page, count);
2173 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2174 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2175 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2176 #ifdef HAVE_QUOTA_SUPPORT
2177 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2178 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2179 page + c, count - c);
2184 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2186 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2187 int count, int *eof, void *data)
2189 struct obd_device *obd = data;
2192 LASSERT(obd != NULL);
2193 LASSERT(count >= 0);
2195 /* Set start of user data returned to
2196 page + off since the user may have
2197 requested to read much smaller than
2198 what we need to read */
2199 *start = page + off;
2201 /* We know we are allocated a page here.
2202 Also we know that this function will
2203 not need to write more than a page
2204 so we can truncate at CFS_PAGE_SIZE. */
2205 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2207 /* Initialize the page */
2208 memset(page, 0, size);
2210 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2212 if (obd->obd_max_recoverable_clients == 0) {
2213 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2219 /* sampled unlocked, but really... */
2220 if (obd->obd_recovering == 0) {
2221 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2223 if (lprocfs_obd_snprintf(&page, size, &len,
2224 "recovery_start: %lu\n",
2225 obd->obd_recovery_start) <= 0)
2227 if (lprocfs_obd_snprintf(&page, size, &len,
2228 "recovery_duration: %lu\n",
2229 obd->obd_recovery_end -
2230 obd->obd_recovery_start) <= 0)
2232 /* Number of clients that have completed recovery */
2233 if (lprocfs_obd_snprintf(&page, size, &len,
2234 "completed_clients: %d/%d\n",
2235 obd->obd_max_recoverable_clients -
2236 obd->obd_stale_clients,
2237 obd->obd_max_recoverable_clients) <= 0)
2239 if (lprocfs_obd_snprintf(&page, size, &len,
2240 "replayed_requests: %d\n",
2241 obd->obd_replayed_requests) <= 0)
2243 if (lprocfs_obd_snprintf(&page, size, &len,
2244 "last_transno: "LPD64"\n",
2245 obd->obd_next_recovery_transno - 1)<=0)
2247 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2248 obd->obd_version_recov ? "ON" : "OFF")<=0)
2253 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2255 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2256 obd->obd_recovery_start) <= 0)
2258 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2259 cfs_time_current_sec() >= obd->obd_recovery_end ? 0 :
2260 obd->obd_recovery_end - cfs_time_current_sec()) <= 0)
2262 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2263 obd->obd_connected_clients,
2264 obd->obd_max_recoverable_clients) <= 0)
2266 /* Number of clients that have completed recovery */
2267 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2268 cfs_atomic_read(&obd->obd_req_replay_clients))
2271 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2272 cfs_atomic_read(&obd->obd_lock_replay_clients))
2275 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2276 obd->obd_connected_clients -
2277 cfs_atomic_read(&obd->obd_lock_replay_clients))
2280 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2281 obd->obd_stale_clients) <= 0)
2283 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2284 obd->obd_replayed_requests) <= 0)
2286 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2287 obd->obd_requests_queued_for_recovery) <= 0)
2290 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2291 obd->obd_next_recovery_transno) <= 0)
2297 return min(count, len - (int)off);
2299 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2301 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2302 int count, int *eof, void *data)
2304 struct obd_device *obd = (struct obd_device *)data;
2305 LASSERT(obd != NULL);
2307 return snprintf(page, count, "%d\n",
2308 obd->obd_recovery_timeout);
2310 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2312 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2313 unsigned long count, void *data)
2315 struct obd_device *obd = (struct obd_device *)data;
2317 LASSERT(obd != NULL);
2319 rc = lprocfs_write_helper(buffer, count, &val);
2323 obd->obd_recovery_timeout = val;
2326 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2328 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2329 int count, int *eof, void *data)
2331 struct obd_device *obd = data;
2332 LASSERT(obd != NULL);
2334 return snprintf(page, count, "%lu\n", obd->obd_recovery_time_hard);
2336 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2338 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2339 unsigned long count, void *data)
2341 struct obd_device *obd = data;
2343 LASSERT(obd != NULL);
2345 rc = lprocfs_write_helper(buffer, count, &val);
2349 obd->obd_recovery_time_hard = val;
2352 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2354 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2355 int count, int *eof, void *data)
2357 struct obd_device *obd = (struct obd_device *)data;
2359 LASSERT(obd != NULL);
2360 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2362 return snprintf(page, count, "%s\n",
2363 obd->u.obt.obt_vfsmnt->mnt_devname);
2365 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2367 EXPORT_SYMBOL(lprocfs_register);
2368 EXPORT_SYMBOL(lprocfs_srch);
2369 EXPORT_SYMBOL(lprocfs_remove);
2370 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2371 EXPORT_SYMBOL(lprocfs_add_vars);
2372 EXPORT_SYMBOL(lprocfs_obd_setup);
2373 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2374 EXPORT_SYMBOL(lprocfs_add_simple);
2375 EXPORT_SYMBOL(lprocfs_add_symlink);
2376 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2377 EXPORT_SYMBOL(lprocfs_alloc_stats);
2378 EXPORT_SYMBOL(lprocfs_free_stats);
2379 EXPORT_SYMBOL(lprocfs_clear_stats);
2380 EXPORT_SYMBOL(lprocfs_register_stats);
2381 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2382 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2383 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2384 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2385 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2386 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2387 EXPORT_SYMBOL(lprocfs_free_md_stats);
2388 EXPORT_SYMBOL(lprocfs_exp_setup);
2389 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2391 EXPORT_SYMBOL(lprocfs_rd_u64);
2392 EXPORT_SYMBOL(lprocfs_rd_atomic);
2393 EXPORT_SYMBOL(lprocfs_wr_atomic);
2394 EXPORT_SYMBOL(lprocfs_rd_uint);
2395 EXPORT_SYMBOL(lprocfs_wr_uint);
2396 EXPORT_SYMBOL(lprocfs_rd_uuid);
2397 EXPORT_SYMBOL(lprocfs_rd_name);
2398 EXPORT_SYMBOL(lprocfs_rd_fstype);
2399 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2400 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2401 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2402 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2403 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2404 EXPORT_SYMBOL(lprocfs_rd_import);
2405 EXPORT_SYMBOL(lprocfs_rd_state);
2406 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2407 EXPORT_SYMBOL(lprocfs_rd_blksize);
2408 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2409 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2410 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2411 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2412 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2414 EXPORT_SYMBOL(lprocfs_write_helper);
2415 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2416 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2417 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2418 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2419 EXPORT_SYMBOL(lprocfs_stats_collect);