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 * Copyright (c) 2011 Whamcloud, Inc.
36 * This file is part of Lustre, http://www.lustre.org/
37 * Lustre is a trademark of Sun Microsystems, Inc.
39 * lustre/obdclass/lprocfs_status.c
41 * Author: Hariharan Thantry <thantry@users.sourceforge.net>
45 # define EXPORT_SYMTAB
47 #define DEBUG_SUBSYSTEM S_CLASS
50 # include <liblustre.h>
53 #include <obd_class.h>
54 #include <lprocfs_status.h>
55 #include <lustre_fsfilt.h>
56 #include <lustre_log.h>
57 #include <lustre/lustre_idl.h>
61 #define MAX_STRING_SIZE 128
63 /* for bug 10866, global variable */
64 CFS_DECLARE_RWSEM(_lprocfs_lock);
65 EXPORT_SYMBOL(_lprocfs_lock);
67 int lprocfs_seq_release(struct inode *inode, struct file *file)
70 return seq_release(inode, file);
72 EXPORT_SYMBOL(lprocfs_seq_release);
74 static struct proc_dir_entry *__lprocfs_srch(struct proc_dir_entry *head,
77 struct proc_dir_entry *temp;
83 while (temp != NULL) {
84 if (strcmp(temp->name, name) == 0) {
93 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
96 struct proc_dir_entry *temp;
99 temp = __lprocfs_srch(head, name);
104 /* lprocfs API calls */
106 /* Function that emulates snprintf but also has the side effect of advancing
107 the page pointer for the next write into the buffer, incrementing the total
108 length written to the buffer, and decrementing the size left in the
110 static int lprocfs_obd_snprintf(char **page, int end, int *len,
111 const char *format, ...)
119 va_start(list, format);
120 n = vsnprintf(*page, end - *len, format, list);
123 *page += n; *len += n;
127 cfs_proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
129 read_proc_t *read_proc,
130 write_proc_t *write_proc,
132 struct file_operations *fops)
134 cfs_proc_dir_entry_t *proc;
137 if (root == NULL || name == NULL)
138 return ERR_PTR(-EINVAL);
145 LPROCFS_WRITE_ENTRY();
146 proc = create_proc_entry(name, mode, root);
148 CERROR("LprocFS: No memory to create /proc entry %s", name);
149 LPROCFS_WRITE_EXIT();
150 return ERR_PTR(-ENOMEM);
152 proc->read_proc = read_proc;
153 proc->write_proc = write_proc;
156 proc->proc_fops = fops;
157 LPROCFS_WRITE_EXIT();
161 struct proc_dir_entry *lprocfs_add_symlink(const char *name,
162 struct proc_dir_entry *parent, const char *format, ...)
164 struct proc_dir_entry *entry;
168 if (parent == NULL || format == NULL)
171 OBD_ALLOC_WAIT(dest, MAX_STRING_SIZE + 1);
175 va_start(ap, format);
176 vsnprintf(dest, MAX_STRING_SIZE, format, ap);
179 entry = proc_symlink(name, parent, dest);
181 CERROR("LprocFS: Could not create symbolic link from %s to %s",
184 OBD_FREE(dest, MAX_STRING_SIZE + 1);
188 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
189 size_t size, loff_t *ppos)
191 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
192 char *page, *start = NULL;
193 int rc = 0, eof = 1, count;
195 if (*ppos >= CFS_PAGE_SIZE)
198 page = (char *)__get_free_page(GFP_KERNEL);
202 if (LPROCFS_ENTRY_AND_CHECK(dp)) {
207 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
209 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
215 /* for lustre proc read, the read count must be less than PAGE_SIZE */
224 start = page + *ppos;
225 } else if (start < page) {
229 count = (rc < size) ? rc : size;
230 if (cfs_copy_to_user(buf, start, count)) {
237 free_page((unsigned long)page);
241 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
242 size_t size, loff_t *ppos)
244 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
247 if (LPROCFS_ENTRY_AND_CHECK(dp))
250 rc = dp->write_proc(f, buf, size, dp->data);
255 static struct file_operations lprocfs_generic_fops = {
256 .owner = THIS_MODULE,
257 .read = lprocfs_fops_read,
258 .write = lprocfs_fops_write,
261 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
263 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
264 struct obd_device *obd = dp->data;
266 cfs_atomic_inc(&obd->obd_evict_inprogress);
271 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
273 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
274 struct obd_device *obd = dp->data;
276 cfs_atomic_dec(&obd->obd_evict_inprogress);
277 cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
282 struct file_operations lprocfs_evict_client_fops = {
283 .owner = THIS_MODULE,
284 .read = lprocfs_fops_read,
285 .write = lprocfs_fops_write,
286 .open = lprocfs_evict_client_open,
287 .release = lprocfs_evict_client_release,
289 EXPORT_SYMBOL(lprocfs_evict_client_fops);
294 * \param root [in] The parent proc entry on which new entry will be added.
295 * \param list [in] Array of proc entries to be added.
296 * \param data [in] The argument to be passed when entries read/write routines
297 * are called through /proc file.
299 * \retval 0 on success
302 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
307 if (root == NULL || list == NULL)
310 LPROCFS_WRITE_ENTRY();
311 while (list->name != NULL) {
312 struct proc_dir_entry *cur_root, *proc;
313 char *pathcopy, *cur, *next, pathbuf[64];
314 int pathsize = strlen(list->name) + 1;
319 /* need copy of path for strsep */
320 if (strlen(list->name) > sizeof(pathbuf) - 1) {
321 OBD_ALLOC(pathcopy, pathsize);
322 if (pathcopy == NULL)
323 GOTO(out, rc = -ENOMEM);
329 strcpy(pathcopy, list->name);
331 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
332 if (*cur =='\0') /* skip double/trailing "/" */
335 proc = __lprocfs_srch(cur_root, cur);
336 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
337 cur_root->name, cur, next,
338 (proc ? "exists" : "new"));
340 cur_root = (proc ? proc :
341 proc_mkdir(cur, cur_root));
342 } else if (proc == NULL) {
344 if (list->proc_mode != 0000) {
345 mode = list->proc_mode;
349 if (list->write_fptr)
352 proc = create_proc_entry(cur, mode, cur_root);
356 if (pathcopy != pathbuf)
357 OBD_FREE(pathcopy, pathsize);
359 if (cur_root == NULL || proc == NULL) {
360 CERROR("LprocFS: No memory to create /proc entry %s",
362 GOTO(out, rc = -ENOMEM);
366 proc->proc_fops = list->fops;
368 proc->proc_fops = &lprocfs_generic_fops;
369 proc->read_proc = list->read_fptr;
370 proc->write_proc = list->write_fptr;
371 proc->data = (list->data ? list->data : data);
375 LPROCFS_WRITE_EXIT();
379 void lprocfs_remove(struct proc_dir_entry **rooth)
381 struct proc_dir_entry *root = *rooth;
382 struct proc_dir_entry *temp = root;
383 struct proc_dir_entry *rm_entry;
384 struct proc_dir_entry *parent;
390 parent = root->parent;
391 LASSERT(parent != NULL);
392 LPROCFS_WRITE_ENTRY(); /* search vs remove race */
395 while (temp->subdir != NULL)
401 /* Memory corruption once caused this to fail, and
402 without this LASSERT we would loop here forever. */
403 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
404 "0x%p %s/%s len %d\n", rm_entry, temp->name,
405 rm_entry->name, (int)strlen(rm_entry->name));
407 #ifdef HAVE_PROCFS_USERS
408 /* if procfs uses user count to synchronize deletion of
409 * proc entry, there is no protection for rm_entry->data,
410 * then lprocfs_fops_read and lprocfs_fops_write maybe
411 * call proc_dir_entry->read_proc (or write_proc) with
412 * proc_dir_entry->data == NULL, then cause kernel Oops.
413 * see bug19706 for detailed information */
415 /* procfs won't free rm_entry->data if it isn't a LINK,
416 * and Lustre won't use rm_entry->data if it is a LINK */
417 if (S_ISLNK(rm_entry->mode))
418 rm_entry->data = NULL;
420 /* Now, the rm_entry->deleted flags is protected
421 * by _lprocfs_lock. */
422 rm_entry->data = NULL;
424 remove_proc_entry(rm_entry->name, temp);
428 LPROCFS_WRITE_EXIT();
431 void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
433 LASSERT(parent != NULL);
434 remove_proc_entry(name, parent);
437 struct proc_dir_entry *lprocfs_register(const char *name,
438 struct proc_dir_entry *parent,
439 struct lprocfs_vars *list, void *data)
441 struct proc_dir_entry *newchild;
443 newchild = lprocfs_srch(parent, name);
444 if (newchild != NULL) {
445 CERROR(" Lproc: Attempting to register %s more than once \n",
447 return ERR_PTR(-EALREADY);
450 newchild = proc_mkdir(name, parent);
451 if (newchild != NULL && list != NULL) {
452 int rc = lprocfs_add_vars(newchild, list, data);
454 lprocfs_remove(&newchild);
461 /* Generic callbacks */
462 int lprocfs_rd_uint(char *page, char **start, off_t off,
463 int count, int *eof, void *data)
465 unsigned int *temp = data;
466 return snprintf(page, count, "%u\n", *temp);
469 int lprocfs_wr_uint(struct file *file, const char *buffer,
470 unsigned long count, void *data)
473 char dummy[MAX_STRING_SIZE + 1], *end;
476 dummy[MAX_STRING_SIZE] = '\0';
477 if (cfs_copy_from_user(dummy, buffer, MAX_STRING_SIZE))
480 tmp = simple_strtoul(dummy, &end, 0);
484 *p = (unsigned int)tmp;
488 int lprocfs_rd_u64(char *page, char **start, off_t off,
489 int count, int *eof, void *data)
491 LASSERT(data != NULL);
493 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
496 int lprocfs_rd_atomic(char *page, char **start, off_t off,
497 int count, int *eof, void *data)
499 cfs_atomic_t *atom = data;
500 LASSERT(atom != NULL);
502 return snprintf(page, count, "%d\n", cfs_atomic_read(atom));
505 int lprocfs_wr_atomic(struct file *file, const char *buffer,
506 unsigned long count, void *data)
508 cfs_atomic_t *atm = data;
512 rc = lprocfs_write_helper(buffer, count, &val);
519 cfs_atomic_set(atm, val);
523 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
524 int *eof, void *data)
526 struct obd_device *obd = data;
528 LASSERT(obd != NULL);
530 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
533 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
534 int *eof, void *data)
536 struct obd_device *dev = data;
538 LASSERT(dev != NULL);
539 LASSERT(dev->obd_name != NULL);
541 return snprintf(page, count, "%s\n", dev->obd_name);
544 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
547 struct obd_device *obd = data;
549 LASSERT(obd != NULL);
550 LASSERT(obd->obd_fsops != NULL);
551 LASSERT(obd->obd_fsops->fs_type != NULL);
552 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
555 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
556 int *eof, void *data)
558 struct obd_statfs osfs;
559 int rc = obd_statfs(data, &osfs,
560 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
564 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
569 int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
570 int *eof, void *data)
572 struct obd_statfs osfs;
573 int rc = obd_statfs(data, &osfs,
574 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
577 __u32 blk_size = osfs.os_bsize >> 10;
578 __u64 result = osfs.os_blocks;
580 while (blk_size >>= 1)
584 rc = snprintf(page, count, LPU64"\n", result);
589 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
590 int *eof, void *data)
592 struct obd_statfs osfs;
593 int rc = obd_statfs(data, &osfs,
594 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
597 __u32 blk_size = osfs.os_bsize >> 10;
598 __u64 result = osfs.os_bfree;
600 while (blk_size >>= 1)
604 rc = snprintf(page, count, LPU64"\n", result);
609 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
610 int *eof, void *data)
612 struct obd_statfs osfs;
613 int rc = obd_statfs(data, &osfs,
614 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
617 __u32 blk_size = osfs.os_bsize >> 10;
618 __u64 result = osfs.os_bavail;
620 while (blk_size >>= 1)
624 rc = snprintf(page, count, LPU64"\n", result);
629 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
630 int *eof, void *data)
632 struct obd_statfs osfs;
633 int rc = obd_statfs(data, &osfs,
634 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
638 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
644 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
645 int *eof, void *data)
647 struct obd_statfs osfs;
648 int rc = obd_statfs(data, &osfs,
649 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
653 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
658 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
659 int *eof, void *data)
661 struct obd_device *obd = data;
662 struct obd_import *imp;
663 char *imp_state_name = NULL;
666 LASSERT(obd != NULL);
667 LPROCFS_CLIMP_CHECK(obd);
668 imp = obd->u.cli.cl_import;
669 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
671 rc = snprintf(page, count, "%s\t%s%s\n",
672 obd2cli_tgt(obd), imp_state_name,
673 imp->imp_deactive ? "\tDEACTIVATED" : "");
675 LPROCFS_CLIMP_EXIT(obd);
679 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
680 int *eof, void *data)
682 struct obd_device *obd = data;
683 struct ptlrpc_connection *conn;
686 LASSERT(obd != NULL);
688 LPROCFS_CLIMP_CHECK(obd);
689 conn = obd->u.cli.cl_import->imp_connection;
691 if (conn && obd->u.cli.cl_import) {
692 rc = snprintf(page, count, "%s\n",
693 conn->c_remote_uuid.uuid);
695 rc = snprintf(page, count, "%s\n", "<none>");
698 LPROCFS_CLIMP_EXIT(obd);
702 /** add up per-cpu counters */
703 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
704 struct lprocfs_counter *cnt)
706 unsigned int num_cpu;
707 struct lprocfs_counter t;
708 struct lprocfs_counter *percpu_cntr;
711 memset(cnt, 0, sizeof(*cnt));
714 /* set count to 1 to avoid divide-by-zero errs in callers */
719 cnt->lc_min = LC_MIN_INIT;
721 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
723 for (i = 0; i < num_cpu; i++) {
724 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
727 centry = cfs_atomic_read(&percpu_cntr-> \
729 t.lc_count = percpu_cntr->lc_count;
730 t.lc_sum = percpu_cntr->lc_sum;
731 t.lc_min = percpu_cntr->lc_min;
732 t.lc_max = percpu_cntr->lc_max;
733 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
734 } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
736 centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
738 cnt->lc_count += t.lc_count;
739 cnt->lc_sum += t.lc_sum;
740 if (t.lc_min < cnt->lc_min)
741 cnt->lc_min = t.lc_min;
742 if (t.lc_max > cnt->lc_max)
743 cnt->lc_max = t.lc_max;
744 cnt->lc_sumsquare += t.lc_sumsquare;
747 cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
748 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
752 * Append a space separated list of current set flags to str.
754 #define flag2str(flag) \
755 if (imp->imp_##flag && max - len > 0) \
756 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
757 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
761 if (imp->imp_obd->obd_no_recov)
762 len += snprintf(str, max - len, "no_recov");
766 flag2str(replayable);
772 static const char *obd_connect_names[] = {
786 "join_file(obsolete)",
790 "remote_client_by_force",
799 "mds_mds_connection",
802 "alt_checksum_algorithm",
816 static int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
821 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
823 ret += snprintf(page + ret, count - ret, "%s%s",
824 ret ? sep : "", obd_connect_names[i]);
826 if (flags & ~(mask - 1))
827 ret += snprintf(page + ret, count - ret,
828 "%sunknown flags "LPX64,
829 ret ? sep : "", flags & ~(mask - 1));
833 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
834 int *eof, void *data)
836 struct lprocfs_counter ret;
837 struct obd_device *obd = (struct obd_device *)data;
838 struct obd_import *imp;
839 struct obd_import_conn *conn;
842 LASSERT(obd != NULL);
843 LPROCFS_CLIMP_CHECK(obd);
844 imp = obd->u.cli.cl_import;
847 i = snprintf(page, count,
855 ptlrpc_import_state_name(imp->imp_state));
856 i += obd_connect_flags2str(page + i, count - i,
857 imp->imp_connect_data.ocd_connect_flags,
859 i += snprintf(page + i, count - i,
862 i += obd_import_flags2str(imp, page + i, count - i);
864 i += snprintf(page + i, count - i,
867 " failover_nids: [");
868 cfs_spin_lock(&imp->imp_lock);
870 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
871 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
872 libcfs_nid2str(conn->oic_conn->c_peer.nid));
875 cfs_spin_unlock(&imp->imp_lock);
876 i += snprintf(page + i, count - i,
878 " current_connection: %s\n"
879 " connection_attempts: %u\n"
881 " in-progress_invalidations: %u\n",
882 libcfs_nid2str(imp->imp_connection->c_peer.nid),
885 cfs_atomic_read(&imp->imp_inval_count));
887 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
888 if (ret.lc_count != 0) {
889 /* first argument to do_div MUST be __u64 */
890 __u64 sum = ret.lc_sum;
891 do_div(sum, ret.lc_count);
895 i += snprintf(page + i, count - i,
898 " unregistering: %u\n"
900 " avg_waittime: "LPU64" %s\n",
901 cfs_atomic_read(&imp->imp_inflight),
902 cfs_atomic_read(&imp->imp_unregistering),
903 cfs_atomic_read(&imp->imp_timeouts),
904 ret.lc_sum, ret.lc_units);
907 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
908 if (imp->imp_at.iat_portal[j] == 0)
910 k = max_t(unsigned int, k,
911 at_get(&imp->imp_at.iat_service_estimate[j]));
913 i += snprintf(page + i, count - i,
914 " service_estimates:\n"
915 " services: %u sec\n"
916 " network: %u sec\n",
918 at_get(&imp->imp_at.iat_net_latency));
920 i += snprintf(page + i, count - i,
922 " last_replay: "LPU64"\n"
923 " peer_committed: "LPU64"\n"
924 " last_checked: "LPU64"\n",
925 imp->imp_last_replay_transno,
926 imp->imp_peer_committed_transno,
927 imp->imp_last_transno_checked);
930 for (rw = 0; rw <= 1; rw++) {
931 lprocfs_stats_collect(obd->obd_svc_stats,
932 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
934 if (ret.lc_sum > 0 && ret.lc_count > 0) {
935 /* first argument to do_div MUST be __u64 */
936 __u64 sum = ret.lc_sum;
937 do_div(sum, ret.lc_count);
939 i += snprintf(page + i, count - i,
940 " %s_data_averages:\n"
941 " bytes_per_rpc: "LPU64"\n",
942 rw ? "write" : "read",
946 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
947 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
948 if (ret.lc_sum > 0 && ret.lc_count != 0) {
949 /* first argument to do_div MUST be __u64 */
950 __u64 sum = ret.lc_sum;
951 do_div(sum, ret.lc_count);
953 i += snprintf(page + i, count - i,
954 " %s_per_rpc: "LPU64"\n",
955 ret.lc_units, ret.lc_sum);
958 i += snprintf(page + i, count - i,
959 " MB_per_sec: %u.%.02u\n",
960 k / j, (100 * k / j) % 100);
964 LPROCFS_CLIMP_EXIT(obd);
968 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
969 int *eof, void *data)
971 struct obd_device *obd = (struct obd_device *)data;
972 struct obd_import *imp;
975 LASSERT(obd != NULL);
976 LPROCFS_CLIMP_CHECK(obd);
977 imp = obd->u.cli.cl_import;
980 i = snprintf(page, count, "current_state: %s\n",
981 ptlrpc_import_state_name(imp->imp_state));
982 i += snprintf(page + i, count - i,
984 k = imp->imp_state_hist_idx;
985 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
986 struct import_state_hist *ish =
987 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
988 if (ish->ish_state == 0)
990 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
992 ptlrpc_import_state_name(ish->ish_state));
995 LPROCFS_CLIMP_EXIT(obd);
999 int lprocfs_at_hist_helper(char *page, int count, int rc,
1000 struct adaptive_timeout *at)
1003 for (i = 0; i < AT_BINS; i++)
1004 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1005 rc += snprintf(page + rc, count - rc, "\n");
1009 /* See also ptlrpc_lprocfs_rd_timeouts */
1010 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1011 int *eof, void *data)
1013 struct obd_device *obd = (struct obd_device *)data;
1014 struct obd_import *imp;
1015 unsigned int cur, worst;
1020 LASSERT(obd != NULL);
1021 LPROCFS_CLIMP_CHECK(obd);
1022 imp = obd->u.cli.cl_import;
1025 now = cfs_time_current_sec();
1027 /* Some network health info for kicks */
1028 s2dhms(&ts, now - imp->imp_last_reply_time);
1029 rc += snprintf(page + rc, count - rc,
1030 "%-10s : %ld, "DHMS_FMT" ago\n",
1031 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1033 cur = at_get(&imp->imp_at.iat_net_latency);
1034 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1035 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1036 s2dhms(&ts, now - worstt);
1037 rc += snprintf(page + rc, count - rc,
1038 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1039 "network", cur, worst, worstt, DHMS_VARS(&ts));
1040 rc = lprocfs_at_hist_helper(page, count, rc,
1041 &imp->imp_at.iat_net_latency);
1043 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1044 if (imp->imp_at.iat_portal[i] == 0)
1046 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1047 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1048 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1049 s2dhms(&ts, now - worstt);
1050 rc += snprintf(page + rc, count - rc,
1051 "portal %-2d : cur %3u worst %3u (at %ld, "
1052 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1053 cur, worst, worstt, DHMS_VARS(&ts));
1054 rc = lprocfs_at_hist_helper(page, count, rc,
1055 &imp->imp_at.iat_service_estimate[i]);
1058 LPROCFS_CLIMP_EXIT(obd);
1062 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1063 int count, int *eof, void *data)
1065 struct obd_device *obd = data;
1069 LPROCFS_CLIMP_CHECK(obd);
1070 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1071 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1072 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1073 ret += snprintf(page + ret, count - ret, "\n");
1074 LPROCFS_CLIMP_EXIT(obd);
1077 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1079 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1080 int *eof, void *data)
1082 struct obd_device *obd = data;
1084 LASSERT(obd != NULL);
1086 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1089 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1090 int *eof, void *data)
1092 struct obd_type *class = (struct obd_type*) data;
1094 LASSERT(class != NULL);
1096 return snprintf(page, count, "%d\n", class->typ_refcnt);
1099 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1103 LASSERT(obd != NULL);
1104 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1105 LASSERT(obd->obd_type->typ_procroot != NULL);
1107 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1108 obd->obd_type->typ_procroot,
1110 if (IS_ERR(obd->obd_proc_entry)) {
1111 rc = PTR_ERR(obd->obd_proc_entry);
1112 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1113 obd->obd_proc_entry = NULL;
1118 int lprocfs_obd_cleanup(struct obd_device *obd)
1122 if (obd->obd_proc_exports_entry) {
1123 /* Should be no exports left */
1124 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1125 lprocfs_remove(&obd->obd_proc_exports_entry);
1126 obd->obd_proc_exports_entry = NULL;
1128 if (obd->obd_proc_entry) {
1129 lprocfs_remove(&obd->obd_proc_entry);
1130 obd->obd_proc_entry = NULL;
1135 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1137 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1138 client_stat->nid_proc, client_stat->nid_stats,
1139 client_stat->nid_brw_stats);
1141 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1142 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1143 atomic_read(&client_stat->nid_exp_ref_count));
1145 cfs_hlist_del_init(&client_stat->nid_hash);
1147 if (client_stat->nid_proc)
1148 lprocfs_remove(&client_stat->nid_proc);
1150 if (client_stat->nid_stats)
1151 lprocfs_free_stats(&client_stat->nid_stats);
1153 if (client_stat->nid_brw_stats)
1154 OBD_FREE_PTR(client_stat->nid_brw_stats);
1156 if (client_stat->nid_ldlm_stats)
1157 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1159 OBD_FREE_PTR(client_stat);
1164 void lprocfs_free_per_client_stats(struct obd_device *obd)
1166 struct nid_stat *stat;
1169 /* we need extra list - because hash_exit called to early */
1170 /* not need locking because all clients is died */
1171 while(!cfs_list_empty(&obd->obd_nid_stats)) {
1172 stat = cfs_list_entry(obd->obd_nid_stats.next,
1173 struct nid_stat, nid_list);
1174 cfs_list_del_init(&stat->nid_list);
1175 lprocfs_free_client_stats(stat);
1181 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1182 enum lprocfs_stats_flags flags)
1184 struct lprocfs_stats *stats;
1185 unsigned int percpusize;
1187 unsigned int num_cpu;
1192 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1195 num_cpu = cfs_num_possible_cpus();
1197 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1201 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1202 stats->ls_flags = flags;
1203 cfs_spin_lock_init(&stats->ls_lock);
1204 /* Use this lock only if there are no percpu areas */
1206 stats->ls_flags = 0;
1209 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1211 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1213 for (i = 0; i < num_cpu; i++) {
1214 OBD_ALLOC(stats->ls_percpu[i], percpusize);
1215 if (stats->ls_percpu[i] == NULL) {
1216 for (j = 0; j < i; j++) {
1217 OBD_FREE(stats->ls_percpu[j], percpusize);
1218 stats->ls_percpu[j] = NULL;
1223 if (stats->ls_percpu[0] == NULL) {
1224 OBD_FREE(stats, offsetof(typeof(*stats),
1225 ls_percpu[num_cpu]));
1229 stats->ls_num = num;
1233 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1235 struct lprocfs_stats *stats = *statsh;
1236 unsigned int num_cpu;
1237 unsigned int percpusize;
1240 if (stats == NULL || stats->ls_num == 0)
1244 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1247 num_cpu = cfs_num_possible_cpus();
1249 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1251 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1252 for (i = 0; i < num_cpu; i++)
1253 OBD_FREE(stats->ls_percpu[i], percpusize);
1254 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1257 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1259 struct lprocfs_counter *percpu_cntr;
1261 unsigned int num_cpu;
1263 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1265 for (i = 0; i < num_cpu; i++) {
1266 for (j = 0; j < stats->ls_num; j++) {
1267 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1268 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1269 percpu_cntr->lc_count = 0;
1270 percpu_cntr->lc_sum = 0;
1271 percpu_cntr->lc_min = LC_MIN_INIT;
1272 percpu_cntr->lc_max = 0;
1273 percpu_cntr->lc_sumsquare = 0;
1274 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1278 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1281 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1282 size_t len, loff_t *off)
1284 struct seq_file *seq = file->private_data;
1285 struct lprocfs_stats *stats = seq->private;
1287 lprocfs_clear_stats(stats);
1292 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1294 struct lprocfs_stats *stats = p->private;
1295 /* return 1st cpu location */
1296 return (*pos >= stats->ls_num) ? NULL :
1297 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1300 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1304 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1306 struct lprocfs_stats *stats = p->private;
1308 return (*pos >= stats->ls_num) ? NULL :
1309 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1312 /* seq file export of one lprocfs counter */
1313 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1315 struct lprocfs_stats *stats = p->private;
1316 struct lprocfs_counter *cntr = v;
1317 struct lprocfs_counter ret;
1320 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1322 cfs_gettimeofday(&now);
1323 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1324 "snapshot_time", now.tv_sec, now.tv_usec);
1328 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1330 lprocfs_stats_collect(stats, idx, &ret);
1332 if (ret.lc_count == 0)
1335 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1336 ret.lc_count, cntr->lc_units);
1341 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1342 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1343 ret.lc_min, ret.lc_max, ret.lc_sum);
1346 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1347 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1351 rc = seq_printf(p, "\n");
1353 return (rc < 0) ? rc : 0;
1356 struct seq_operations lprocfs_stats_seq_sops = {
1357 start: lprocfs_stats_seq_start,
1358 stop: lprocfs_stats_seq_stop,
1359 next: lprocfs_stats_seq_next,
1360 show: lprocfs_stats_seq_show,
1363 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1365 struct proc_dir_entry *dp = PDE(inode);
1366 struct seq_file *seq;
1369 if (LPROCFS_ENTRY_AND_CHECK(dp))
1372 rc = seq_open(file, &lprocfs_stats_seq_sops);
1377 seq = file->private_data;
1378 seq->private = dp->data;
1382 struct file_operations lprocfs_stats_seq_fops = {
1383 .owner = THIS_MODULE,
1384 .open = lprocfs_stats_seq_open,
1386 .write = lprocfs_stats_seq_write,
1387 .llseek = seq_lseek,
1388 .release = lprocfs_seq_release,
1391 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1392 struct lprocfs_stats *stats)
1394 struct proc_dir_entry *entry;
1395 LASSERT(root != NULL);
1397 LPROCFS_WRITE_ENTRY();
1398 entry = create_proc_entry(name, 0644, root);
1400 entry->proc_fops = &lprocfs_stats_seq_fops;
1401 entry->data = stats;
1404 LPROCFS_WRITE_EXIT();
1412 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1413 unsigned conf, const char *name, const char *units)
1415 struct lprocfs_counter *c;
1417 unsigned int num_cpu;
1419 LASSERT(stats != NULL);
1421 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1423 for (i = 0; i < num_cpu; i++) {
1424 c = &(stats->ls_percpu[i]->lp_cntr[index]);
1425 c->lc_config = conf;
1428 c->lc_min = LC_MIN_INIT;
1431 c->lc_units = units;
1434 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1436 EXPORT_SYMBOL(lprocfs_counter_init);
1438 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1440 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1441 LASSERT(coffset < stats->ls_num); \
1442 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1445 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1447 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1448 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1449 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1450 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1451 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1452 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1453 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1454 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1455 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1456 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1457 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1458 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1459 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1460 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1461 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1462 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1463 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1467 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1468 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1469 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1470 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1471 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1472 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1473 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1474 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1475 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1476 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1477 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1478 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1479 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1480 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1481 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1482 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1483 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1484 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1485 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1486 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1487 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1488 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1489 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1490 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1491 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1492 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1493 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1494 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1495 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1496 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1497 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1498 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1499 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1500 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1501 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1502 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1503 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1504 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1505 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1506 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1507 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1508 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1509 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1510 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1511 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1512 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1513 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1514 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1515 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1518 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1520 struct lprocfs_stats *stats;
1521 unsigned int num_stats;
1524 LASSERT(obd->obd_stats == NULL);
1525 LASSERT(obd->obd_proc_entry != NULL);
1526 LASSERT(obd->obd_cntr_base == 0);
1528 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1529 num_private_stats - 1 /* o_owner */;
1530 stats = lprocfs_alloc_stats(num_stats, 0);
1534 lprocfs_init_ops_stats(num_private_stats, stats);
1536 for (i = num_private_stats; i < num_stats; i++) {
1537 /* If this LBUGs, it is likely that an obd
1538 * operation was added to struct obd_ops in
1539 * <obd.h>, and that the corresponding line item
1540 * LPROCFS_OBD_OP_INIT(.., .., opname)
1541 * is missing from the list above. */
1542 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1543 "Missing obd_stat initializer obd_op "
1544 "operation at offset %d.\n", i - num_private_stats);
1546 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1548 lprocfs_free_stats(&stats);
1550 obd->obd_stats = stats;
1551 obd->obd_cntr_base = num_private_stats;
1556 void lprocfs_free_obd_stats(struct obd_device *obd)
1559 lprocfs_free_stats(&obd->obd_stats);
1562 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1564 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1565 LASSERT(coffset < stats->ls_num); \
1566 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1569 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1571 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1572 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1573 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1574 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1575 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1576 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1577 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1578 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1579 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1580 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1581 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1582 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1583 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1584 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1585 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1586 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1587 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1588 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1589 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1590 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1591 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1592 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1593 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1594 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1595 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1596 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1597 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1598 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1599 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1600 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1601 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1602 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1605 int lprocfs_alloc_md_stats(struct obd_device *obd,
1606 unsigned num_private_stats)
1608 struct lprocfs_stats *stats;
1609 unsigned int num_stats;
1612 LASSERT(obd->md_stats == NULL);
1613 LASSERT(obd->obd_proc_entry != NULL);
1614 LASSERT(obd->md_cntr_base == 0);
1616 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1618 stats = lprocfs_alloc_stats(num_stats, 0);
1622 lprocfs_init_mps_stats(num_private_stats, stats);
1624 for (i = num_private_stats; i < num_stats; i++) {
1625 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1626 CERROR("Missing md_stat initializer md_op "
1627 "operation at offset %d. Aborting.\n",
1628 i - num_private_stats);
1632 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1634 lprocfs_free_stats(&stats);
1636 obd->md_stats = stats;
1637 obd->md_cntr_base = num_private_stats;
1642 void lprocfs_free_md_stats(struct obd_device *obd)
1644 struct lprocfs_stats *stats = obd->md_stats;
1646 if (stats != NULL) {
1647 obd->md_stats = NULL;
1648 obd->md_cntr_base = 0;
1649 lprocfs_free_stats(&stats);
1653 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1655 lprocfs_counter_init(ldlm_stats,
1656 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1657 0, "ldlm_enqueue", "reqs");
1658 lprocfs_counter_init(ldlm_stats,
1659 LDLM_CONVERT - LDLM_FIRST_OPC,
1660 0, "ldlm_convert", "reqs");
1661 lprocfs_counter_init(ldlm_stats,
1662 LDLM_CANCEL - LDLM_FIRST_OPC,
1663 0, "ldlm_cancel", "reqs");
1664 lprocfs_counter_init(ldlm_stats,
1665 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1666 0, "ldlm_bl_callback", "reqs");
1667 lprocfs_counter_init(ldlm_stats,
1668 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1669 0, "ldlm_cp_callback", "reqs");
1670 lprocfs_counter_init(ldlm_stats,
1671 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1672 0, "ldlm_gl_callback", "reqs");
1675 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1676 int *eof, void *data)
1678 struct obd_export *exp = data;
1679 LASSERT(exp != NULL);
1681 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1684 struct exp_uuid_cb_data {
1692 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1693 int count, int *eof, int *len)
1695 cb_data->page = page;
1696 cb_data->count = count;
1701 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1702 cfs_hlist_node_t *hnode, void *cb_data)
1705 struct obd_export *exp = cfs_hash_object(hs, hnode);
1706 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1708 if (exp->exp_nid_stats)
1709 *data->len += snprintf((data->page + *data->len),
1710 data->count, "%s\n",
1711 obd_uuid2str(&exp->exp_client_uuid));
1715 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1716 int *eof, void *data)
1718 struct nid_stat *stats = (struct nid_stat *)data;
1719 struct exp_uuid_cb_data cb_data;
1720 struct obd_device *obd = stats->nid_obd;
1725 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1726 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1727 lprocfs_exp_print_uuid, &cb_data);
1728 return (*cb_data.len);
1731 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1732 cfs_hlist_node_t *hnode, void *cb_data)
1735 struct exp_uuid_cb_data *data = cb_data;
1736 struct obd_export *exp = cfs_hash_object(hs, hnode);
1738 if (exp->exp_lock_hash != NULL) {
1740 *data->len += cfs_hash_debug_header(data->page,
1743 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1750 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1751 int *eof, void *data)
1753 struct nid_stat *stats = (struct nid_stat *)data;
1754 struct exp_uuid_cb_data cb_data;
1755 struct obd_device *obd = stats->nid_obd;
1760 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1762 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1763 lprocfs_exp_print_hash, &cb_data);
1764 return (*cb_data.len);
1767 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1768 int count, int *eof, void *data)
1771 return snprintf(page, count, "%s\n",
1772 "Write into this file to clear all nid stats and "
1773 "stale nid entries");
1775 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1777 int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1779 struct nid_stat *stat = obj;
1783 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1784 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1785 /* object has only hash references. */
1786 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1787 cfs_list_move(&stat->nid_list, data);
1788 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1791 /* we has reference to object - only clear data*/
1792 if (stat->nid_stats)
1793 lprocfs_clear_stats(stat->nid_stats);
1795 if (stat->nid_brw_stats) {
1796 for (i = 0; i < BRW_LAST; i++)
1797 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1802 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1803 unsigned long count, void *data)
1805 struct obd_device *obd = (struct obd_device *)data;
1806 struct nid_stat *client_stat;
1807 CFS_LIST_HEAD(free_list);
1809 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1810 lprocfs_nid_stats_clear_write_cb, &free_list);
1812 while (!cfs_list_empty(&free_list)) {
1813 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1815 cfs_list_del_init(&client_stat->nid_list);
1816 lprocfs_free_client_stats(client_stat);
1821 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1823 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1825 struct nid_stat *new_stat, *old_stat;
1826 struct obd_device *obd = NULL;
1827 cfs_proc_dir_entry_t *entry;
1828 char *buffer = NULL;
1834 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1835 !exp->exp_obd->obd_nid_stats_hash)
1838 /* not test against zero because eric say:
1839 * You may only test nid against another nid, or LNET_NID_ANY.
1840 * Anything else is nonsense.*/
1841 if (!nid || *nid == LNET_NID_ANY)
1846 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1848 OBD_ALLOC_PTR(new_stat);
1849 if (new_stat == NULL)
1852 new_stat->nid = *nid;
1853 new_stat->nid_obd = exp->exp_obd;
1854 /* we need set default refcount to 1 to balance obd_disconnect */
1855 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1857 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1858 nid, &new_stat->nid_hash);
1859 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1860 old_stat, libcfs_nid2str(*nid),
1861 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1863 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1864 * been and will never be called. */
1865 if (exp->exp_nid_stats) {
1866 nidstat_putref(exp->exp_nid_stats);
1867 exp->exp_nid_stats = NULL;
1870 /* Return -EALREADY here so that we know that the /proc
1871 * entry already has been created */
1872 if (old_stat != new_stat) {
1873 exp->exp_nid_stats = old_stat;
1874 GOTO(destroy_new, rc = -EALREADY);
1876 /* not found - create */
1877 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1879 GOTO(destroy_new, rc = -ENOMEM);
1881 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1882 new_stat->nid_proc = lprocfs_register(buffer,
1883 obd->obd_proc_exports_entry,
1885 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1887 if (new_stat->nid_proc == NULL) {
1888 CERROR("Error making export directory for nid %s\n",
1889 libcfs_nid2str(*nid));
1890 GOTO(destroy_new_ns, rc = -ENOMEM);
1893 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1894 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1895 if (IS_ERR(entry)) {
1896 CWARN("Error adding the NID stats file\n");
1897 rc = PTR_ERR(entry);
1898 GOTO(destroy_new_ns, rc);
1901 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1902 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1903 if (IS_ERR(entry)) {
1904 CWARN("Error adding the hash file\n");
1905 rc = PTR_ERR(entry);
1906 GOTO(destroy_new_ns, rc);
1909 exp->exp_nid_stats = new_stat;
1911 /* protect competitive add to list, not need locking on destroy */
1912 cfs_spin_lock(&obd->obd_nid_lock);
1913 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1914 cfs_spin_unlock(&obd->obd_nid_lock);
1919 if (new_stat->nid_proc != NULL)
1920 lprocfs_remove(&new_stat->nid_proc);
1921 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1924 nidstat_putref(new_stat);
1925 OBD_FREE_PTR(new_stat);
1929 int lprocfs_exp_cleanup(struct obd_export *exp)
1931 struct nid_stat *stat = exp->exp_nid_stats;
1933 if(!stat || !exp->exp_obd)
1936 nidstat_putref(exp->exp_nid_stats);
1937 exp->exp_nid_stats = NULL;
1942 int lprocfs_write_helper(const char *buffer, unsigned long count,
1945 return lprocfs_write_frac_helper(buffer, count, val, 1);
1948 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1951 char kernbuf[20], *end, *pbuf;
1953 if (count > (sizeof(kernbuf) - 1))
1956 if (cfs_copy_from_user(kernbuf, buffer, count))
1959 kernbuf[count] = '\0';
1966 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1970 if (end != NULL && *end == '.') {
1971 int temp_val, pow = 1;
1975 if (strlen(pbuf) > 5)
1976 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1978 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1981 for (i = 0; i < (end - pbuf); i++)
1984 *val += temp_val / pow;
1990 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
1993 long decimal_val, frac_val;
1999 decimal_val = val / mult;
2000 prtn = snprintf(buffer, count, "%ld", decimal_val);
2001 frac_val = val % mult;
2003 if (prtn < (count - 4) && frac_val > 0) {
2005 int i, temp_mult = 1, frac_bits = 0;
2007 temp_frac = frac_val * 10;
2008 buffer[prtn++] = '.';
2009 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2010 /* only reserved 2 bits fraction */
2011 buffer[prtn++] ='0';
2016 * Need to think these cases :
2017 * 1. #echo x.00 > /proc/xxx output result : x
2018 * 2. #echo x.0x > /proc/xxx output result : x.0x
2019 * 3. #echo x.x0 > /proc/xxx output result : x.x
2020 * 4. #echo x.xx > /proc/xxx output result : x.xx
2021 * Only reserved 2 bits fraction.
2023 for (i = 0; i < (5 - prtn); i++)
2026 frac_bits = min((int)count - prtn, 3 - frac_bits);
2027 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2028 frac_val * temp_mult / mult);
2031 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2033 if (buffer[prtn] == '.') {
2040 buffer[prtn++] ='\n';
2044 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2046 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2049 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2050 __u64 *val, int mult)
2052 char kernbuf[22], *end, *pbuf;
2053 __u64 whole, frac = 0, units;
2054 unsigned frac_d = 1;
2056 if (count > (sizeof(kernbuf) - 1))
2059 if (cfs_copy_from_user(kernbuf, buffer, count))
2062 kernbuf[count] = '\0';
2069 whole = simple_strtoull(pbuf, &end, 10);
2073 if (end != NULL && *end == '.') {
2077 /* need to limit frac_d to a __u32 */
2078 if (strlen(pbuf) > 10)
2081 frac = simple_strtoull(pbuf, &end, 10);
2082 /* count decimal places */
2083 for (i = 0; i < (end - pbuf); i++)
2100 /* Specified units override the multiplier */
2102 mult = mult < 0 ? -units : units;
2105 do_div(frac, frac_d);
2106 *val = whole * mult + frac;
2110 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2111 struct file_operations *seq_fops, void *data)
2113 struct proc_dir_entry *entry;
2116 LPROCFS_WRITE_ENTRY();
2117 entry = create_proc_entry(name, mode, parent);
2119 entry->proc_fops = seq_fops;
2122 LPROCFS_WRITE_EXIT();
2129 EXPORT_SYMBOL(lprocfs_seq_create);
2131 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2133 struct file_operations *seq_fops,
2136 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2137 mode, seq_fops, data));
2139 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2141 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2143 if (value >= OBD_HIST_MAX)
2144 value = OBD_HIST_MAX - 1;
2146 cfs_spin_lock(&oh->oh_lock);
2147 oh->oh_buckets[value]++;
2148 cfs_spin_unlock(&oh->oh_lock);
2150 EXPORT_SYMBOL(lprocfs_oh_tally);
2152 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2156 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2159 lprocfs_oh_tally(oh, val);
2161 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2163 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2165 unsigned long ret = 0;
2168 for (i = 0; i < OBD_HIST_MAX; i++)
2169 ret += oh->oh_buckets[i];
2172 EXPORT_SYMBOL(lprocfs_oh_sum);
2174 void lprocfs_oh_clear(struct obd_histogram *oh)
2176 cfs_spin_lock(&oh->oh_lock);
2177 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2178 cfs_spin_unlock(&oh->oh_lock);
2180 EXPORT_SYMBOL(lprocfs_oh_clear);
2182 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2183 int count, int *eof, void *data)
2185 struct obd_device *obd = data;
2191 c += cfs_hash_debug_header(page, count);
2192 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2193 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2194 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2195 #ifdef HAVE_QUOTA_SUPPORT
2196 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2197 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2198 page + c, count - c);
2203 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2205 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2206 int count, int *eof, void *data)
2208 struct obd_device *obd = data;
2211 LASSERT(obd != NULL);
2212 LASSERT(count >= 0);
2214 /* Set start of user data returned to
2215 page + off since the user may have
2216 requested to read much smaller than
2217 what we need to read */
2218 *start = page + off;
2220 /* We know we are allocated a page here.
2221 Also we know that this function will
2222 not need to write more than a page
2223 so we can truncate at CFS_PAGE_SIZE. */
2224 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2226 /* Initialize the page */
2227 memset(page, 0, size);
2229 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2231 if (obd->obd_max_recoverable_clients == 0) {
2232 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2238 /* sampled unlocked, but really... */
2239 if (obd->obd_recovering == 0) {
2240 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2242 if (lprocfs_obd_snprintf(&page, size, &len,
2243 "recovery_start: %lu\n",
2244 obd->obd_recovery_start) <= 0)
2246 if (lprocfs_obd_snprintf(&page, size, &len,
2247 "recovery_duration: %lu\n",
2248 obd->obd_recovery_end -
2249 obd->obd_recovery_start) <= 0)
2251 /* Number of clients that have completed recovery */
2252 if (lprocfs_obd_snprintf(&page, size, &len,
2253 "completed_clients: %d/%d\n",
2254 obd->obd_max_recoverable_clients -
2255 obd->obd_stale_clients,
2256 obd->obd_max_recoverable_clients) <= 0)
2258 if (lprocfs_obd_snprintf(&page, size, &len,
2259 "replayed_requests: %d\n",
2260 obd->obd_replayed_requests) <= 0)
2262 if (lprocfs_obd_snprintf(&page, size, &len,
2263 "last_transno: "LPD64"\n",
2264 obd->obd_next_recovery_transno - 1)<=0)
2266 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2267 obd->obd_version_recov ? "ON" : "OFF")<=0)
2272 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2274 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2275 obd->obd_recovery_start) <= 0)
2277 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2278 cfs_time_current_sec() >= obd->obd_recovery_end ? 0 :
2279 obd->obd_recovery_end - cfs_time_current_sec()) <= 0)
2281 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2282 obd->obd_connected_clients,
2283 obd->obd_max_recoverable_clients) <= 0)
2285 /* Number of clients that have completed recovery */
2286 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2287 cfs_atomic_read(&obd->obd_req_replay_clients))
2290 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2291 cfs_atomic_read(&obd->obd_lock_replay_clients))
2294 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2295 obd->obd_connected_clients -
2296 cfs_atomic_read(&obd->obd_lock_replay_clients))
2299 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2300 obd->obd_stale_clients) <= 0)
2302 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2303 obd->obd_replayed_requests) <= 0)
2305 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2306 obd->obd_requests_queued_for_recovery) <= 0)
2309 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2310 obd->obd_next_recovery_transno) <= 0)
2316 return min(count, len - (int)off);
2318 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2320 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2321 int count, int *eof, void *data)
2323 struct obd_device *obd = (struct obd_device *)data;
2324 LASSERT(obd != NULL);
2326 return snprintf(page, count, "%d\n",
2327 obd->obd_recovery_timeout);
2329 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2331 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2332 unsigned long count, void *data)
2334 struct obd_device *obd = (struct obd_device *)data;
2336 LASSERT(obd != NULL);
2338 rc = lprocfs_write_helper(buffer, count, &val);
2342 obd->obd_recovery_timeout = val;
2345 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2347 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2348 int count, int *eof, void *data)
2350 struct obd_device *obd = data;
2351 LASSERT(obd != NULL);
2353 return snprintf(page, count, "%lu\n", obd->obd_recovery_time_hard);
2355 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2357 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2358 unsigned long count, void *data)
2360 struct obd_device *obd = data;
2362 LASSERT(obd != NULL);
2364 rc = lprocfs_write_helper(buffer, count, &val);
2368 obd->obd_recovery_time_hard = val;
2371 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2373 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2374 int count, int *eof, void *data)
2376 struct obd_device *obd = (struct obd_device *)data;
2378 LASSERT(obd != NULL);
2379 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2381 return snprintf(page, count, "%s\n",
2382 obd->u.obt.obt_vfsmnt->mnt_devname);
2384 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2386 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2387 int count, int *eof, void *data)
2389 struct obd_device *dev = data;
2390 struct client_obd *cli = &dev->u.cli;
2393 client_obd_list_lock(&cli->cl_loi_list_lock);
2394 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2395 client_obd_list_unlock(&cli->cl_loi_list_lock);
2398 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2400 int lprocfs_obd_wr_max_pages_per_rpc(struct file *file, const char *buffer,
2401 unsigned long count, void *data)
2403 struct obd_device *dev = data;
2404 struct client_obd *cli = &dev->u.cli;
2405 struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
2408 rc = lprocfs_write_helper(buffer, count, &val);
2412 LPROCFS_CLIMP_CHECK(dev);
2413 if (val < 1 || val > ocd->ocd_brw_size >> CFS_PAGE_SHIFT) {
2414 LPROCFS_CLIMP_EXIT(dev);
2417 client_obd_list_lock(&cli->cl_loi_list_lock);
2418 cli->cl_max_pages_per_rpc = val;
2419 client_obd_list_unlock(&cli->cl_loi_list_lock);
2421 LPROCFS_CLIMP_EXIT(dev);
2424 EXPORT_SYMBOL(lprocfs_obd_wr_max_pages_per_rpc);
2426 EXPORT_SYMBOL(lprocfs_register);
2427 EXPORT_SYMBOL(lprocfs_srch);
2428 EXPORT_SYMBOL(lprocfs_remove);
2429 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2430 EXPORT_SYMBOL(lprocfs_add_vars);
2431 EXPORT_SYMBOL(lprocfs_obd_setup);
2432 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2433 EXPORT_SYMBOL(lprocfs_add_simple);
2434 EXPORT_SYMBOL(lprocfs_add_symlink);
2435 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2436 EXPORT_SYMBOL(lprocfs_alloc_stats);
2437 EXPORT_SYMBOL(lprocfs_free_stats);
2438 EXPORT_SYMBOL(lprocfs_clear_stats);
2439 EXPORT_SYMBOL(lprocfs_register_stats);
2440 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2441 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2442 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2443 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2444 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2445 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2446 EXPORT_SYMBOL(lprocfs_free_md_stats);
2447 EXPORT_SYMBOL(lprocfs_exp_setup);
2448 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2450 EXPORT_SYMBOL(lprocfs_rd_u64);
2451 EXPORT_SYMBOL(lprocfs_rd_atomic);
2452 EXPORT_SYMBOL(lprocfs_wr_atomic);
2453 EXPORT_SYMBOL(lprocfs_rd_uint);
2454 EXPORT_SYMBOL(lprocfs_wr_uint);
2455 EXPORT_SYMBOL(lprocfs_rd_uuid);
2456 EXPORT_SYMBOL(lprocfs_rd_name);
2457 EXPORT_SYMBOL(lprocfs_rd_fstype);
2458 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2459 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2460 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2461 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2462 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2463 EXPORT_SYMBOL(lprocfs_rd_import);
2464 EXPORT_SYMBOL(lprocfs_rd_state);
2465 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2466 EXPORT_SYMBOL(lprocfs_rd_blksize);
2467 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2468 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2469 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2470 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2471 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2473 EXPORT_SYMBOL(lprocfs_write_helper);
2474 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2475 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2476 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2477 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2478 EXPORT_SYMBOL(lprocfs_stats_collect);