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.
32 * Copyright (c) 2011, Whamcloud, Inc.
35 * This file is part of Lustre, http://www.lustre.org/
36 * Lustre is a trademark of Sun Microsystems, Inc.
38 * lustre/obdclass/lprocfs_status.c
40 * Author: Hariharan Thantry <thantry@users.sourceforge.net>
44 # define EXPORT_SYMTAB
46 #define DEBUG_SUBSYSTEM S_CLASS
49 # include <liblustre.h>
52 #include <obd_class.h>
53 #include <lprocfs_status.h>
54 #include <lustre_fsfilt.h>
55 #include <lustre_log.h>
56 #include <lustre/lustre_idl.h>
60 static int lprocfs_no_percpu_stats = 0;
61 CFS_MODULE_PARM(lprocfs_no_percpu_stats, "i", int, 0644,
62 "Do not alloc percpu data for lprocfs stats");
64 #define MAX_STRING_SIZE 128
66 /* for bug 10866, global variable */
67 CFS_DECLARE_RWSEM(_lprocfs_lock);
68 EXPORT_SYMBOL(_lprocfs_lock);
70 int lprocfs_seq_release(struct inode *inode, struct file *file)
73 return seq_release(inode, file);
75 EXPORT_SYMBOL(lprocfs_seq_release);
77 static struct proc_dir_entry *__lprocfs_srch(struct proc_dir_entry *head,
80 struct proc_dir_entry *temp;
86 while (temp != NULL) {
87 if (strcmp(temp->name, name) == 0) {
96 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
99 struct proc_dir_entry *temp;
101 LPROCFS_SRCH_ENTRY();
102 temp = __lprocfs_srch(head, name);
107 /* lprocfs API calls */
109 /* Function that emulates snprintf but also has the side effect of advancing
110 the page pointer for the next write into the buffer, incrementing the total
111 length written to the buffer, and decrementing the size left in the
113 static int lprocfs_obd_snprintf(char **page, int end, int *len,
114 const char *format, ...)
122 va_start(list, format);
123 n = vsnprintf(*page, end - *len, format, list);
126 *page += n; *len += n;
130 cfs_proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
132 read_proc_t *read_proc,
133 write_proc_t *write_proc,
135 struct file_operations *fops)
137 cfs_proc_dir_entry_t *proc;
140 if (root == NULL || name == NULL)
141 return ERR_PTR(-EINVAL);
148 LPROCFS_WRITE_ENTRY();
149 proc = create_proc_entry(name, mode, root);
151 CERROR("LprocFS: No memory to create /proc entry %s", name);
152 LPROCFS_WRITE_EXIT();
153 return ERR_PTR(-ENOMEM);
155 proc->read_proc = read_proc;
156 proc->write_proc = write_proc;
159 proc->proc_fops = fops;
160 LPROCFS_WRITE_EXIT();
164 struct proc_dir_entry *lprocfs_add_symlink(const char *name,
165 struct proc_dir_entry *parent, const char *format, ...)
167 struct proc_dir_entry *entry;
171 if (parent == NULL || format == NULL)
174 OBD_ALLOC_WAIT(dest, MAX_STRING_SIZE + 1);
178 va_start(ap, format);
179 vsnprintf(dest, MAX_STRING_SIZE, format, ap);
182 entry = proc_symlink(name, parent, dest);
184 CERROR("LprocFS: Could not create symbolic link from %s to %s",
187 OBD_FREE(dest, MAX_STRING_SIZE + 1);
191 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
192 size_t size, loff_t *ppos)
194 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
195 char *page, *start = NULL;
196 int rc = 0, eof = 1, count;
198 if (*ppos >= CFS_PAGE_SIZE)
201 page = (char *)__get_free_page(GFP_KERNEL);
205 if (LPROCFS_ENTRY_AND_CHECK(dp)) {
210 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
212 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
218 /* for lustre proc read, the read count must be less than PAGE_SIZE */
227 start = page + *ppos;
228 } else if (start < page) {
232 count = (rc < size) ? rc : size;
233 if (cfs_copy_to_user(buf, start, count)) {
240 free_page((unsigned long)page);
244 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
245 size_t size, loff_t *ppos)
247 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
250 if (LPROCFS_ENTRY_AND_CHECK(dp))
253 rc = dp->write_proc(f, buf, size, dp->data);
258 static struct file_operations lprocfs_generic_fops = {
259 .owner = THIS_MODULE,
260 .read = lprocfs_fops_read,
261 .write = lprocfs_fops_write,
264 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
266 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
267 struct obd_device *obd = dp->data;
269 cfs_atomic_inc(&obd->obd_evict_inprogress);
274 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
276 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
277 struct obd_device *obd = dp->data;
279 cfs_atomic_dec(&obd->obd_evict_inprogress);
280 cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
285 struct file_operations lprocfs_evict_client_fops = {
286 .owner = THIS_MODULE,
287 .read = lprocfs_fops_read,
288 .write = lprocfs_fops_write,
289 .open = lprocfs_evict_client_open,
290 .release = lprocfs_evict_client_release,
292 EXPORT_SYMBOL(lprocfs_evict_client_fops);
297 * \param root [in] The parent proc entry on which new entry will be added.
298 * \param list [in] Array of proc entries to be added.
299 * \param data [in] The argument to be passed when entries read/write routines
300 * are called through /proc file.
302 * \retval 0 on success
305 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
310 if (root == NULL || list == NULL)
313 LPROCFS_WRITE_ENTRY();
314 while (list->name != NULL) {
315 struct proc_dir_entry *cur_root, *proc;
316 char *pathcopy, *cur, *next, pathbuf[64];
317 int pathsize = strlen(list->name) + 1;
322 /* need copy of path for strsep */
323 if (strlen(list->name) > sizeof(pathbuf) - 1) {
324 OBD_ALLOC(pathcopy, pathsize);
325 if (pathcopy == NULL)
326 GOTO(out, rc = -ENOMEM);
332 strcpy(pathcopy, list->name);
334 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
335 if (*cur =='\0') /* skip double/trailing "/" */
338 proc = __lprocfs_srch(cur_root, cur);
339 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
340 cur_root->name, cur, next,
341 (proc ? "exists" : "new"));
343 cur_root = (proc ? proc :
344 proc_mkdir(cur, cur_root));
345 } else if (proc == NULL) {
347 if (list->proc_mode != 0000) {
348 mode = list->proc_mode;
352 if (list->write_fptr)
355 proc = create_proc_entry(cur, mode, cur_root);
359 if (pathcopy != pathbuf)
360 OBD_FREE(pathcopy, pathsize);
362 if (cur_root == NULL || proc == NULL) {
363 CERROR("LprocFS: No memory to create /proc entry %s",
365 GOTO(out, rc = -ENOMEM);
369 proc->proc_fops = list->fops;
371 proc->proc_fops = &lprocfs_generic_fops;
372 proc->read_proc = list->read_fptr;
373 proc->write_proc = list->write_fptr;
374 proc->data = (list->data ? list->data : data);
378 LPROCFS_WRITE_EXIT();
382 void lprocfs_remove(struct proc_dir_entry **rooth)
384 struct proc_dir_entry *root = *rooth;
385 struct proc_dir_entry *temp = root;
386 struct proc_dir_entry *rm_entry;
387 struct proc_dir_entry *parent;
393 parent = root->parent;
394 LASSERT(parent != NULL);
395 LPROCFS_WRITE_ENTRY(); /* search vs remove race */
398 while (temp->subdir != NULL)
404 /* Memory corruption once caused this to fail, and
405 without this LASSERT we would loop here forever. */
406 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
407 "0x%p %s/%s len %d\n", rm_entry, temp->name,
408 rm_entry->name, (int)strlen(rm_entry->name));
410 #ifdef HAVE_PROCFS_USERS
411 /* if procfs uses user count to synchronize deletion of
412 * proc entry, there is no protection for rm_entry->data,
413 * then lprocfs_fops_read and lprocfs_fops_write maybe
414 * call proc_dir_entry->read_proc (or write_proc) with
415 * proc_dir_entry->data == NULL, then cause kernel Oops.
416 * see bug19706 for detailed information */
418 /* procfs won't free rm_entry->data if it isn't a LINK,
419 * and Lustre won't use rm_entry->data if it is a LINK */
420 if (S_ISLNK(rm_entry->mode))
421 rm_entry->data = NULL;
423 /* Now, the rm_entry->deleted flags is protected
424 * by _lprocfs_lock. */
425 rm_entry->data = NULL;
427 remove_proc_entry(rm_entry->name, temp);
431 LPROCFS_WRITE_EXIT();
434 void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
436 LASSERT(parent != NULL);
437 remove_proc_entry(name, parent);
440 struct proc_dir_entry *lprocfs_register(const char *name,
441 struct proc_dir_entry *parent,
442 struct lprocfs_vars *list, void *data)
444 struct proc_dir_entry *newchild;
446 newchild = lprocfs_srch(parent, name);
447 if (newchild != NULL) {
448 CERROR(" Lproc: Attempting to register %s more than once \n",
450 return ERR_PTR(-EALREADY);
453 newchild = proc_mkdir(name, parent);
454 if (newchild != NULL && list != NULL) {
455 int rc = lprocfs_add_vars(newchild, list, data);
457 lprocfs_remove(&newchild);
464 /* Generic callbacks */
465 int lprocfs_rd_uint(char *page, char **start, off_t off,
466 int count, int *eof, void *data)
468 unsigned int *temp = data;
469 return snprintf(page, count, "%u\n", *temp);
472 int lprocfs_wr_uint(struct file *file, const char *buffer,
473 unsigned long count, void *data)
476 char dummy[MAX_STRING_SIZE + 1], *end;
479 dummy[MAX_STRING_SIZE] = '\0';
480 if (cfs_copy_from_user(dummy, buffer, MAX_STRING_SIZE))
483 tmp = simple_strtoul(dummy, &end, 0);
487 *p = (unsigned int)tmp;
491 int lprocfs_rd_u64(char *page, char **start, off_t off,
492 int count, int *eof, void *data)
494 LASSERT(data != NULL);
496 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
499 int lprocfs_rd_atomic(char *page, char **start, off_t off,
500 int count, int *eof, void *data)
502 cfs_atomic_t *atom = data;
503 LASSERT(atom != NULL);
505 return snprintf(page, count, "%d\n", cfs_atomic_read(atom));
508 int lprocfs_wr_atomic(struct file *file, const char *buffer,
509 unsigned long count, void *data)
511 cfs_atomic_t *atm = data;
515 rc = lprocfs_write_helper(buffer, count, &val);
522 cfs_atomic_set(atm, val);
526 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
527 int *eof, void *data)
529 struct obd_device *obd = data;
531 LASSERT(obd != NULL);
533 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
536 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
537 int *eof, void *data)
539 struct obd_device *dev = data;
541 LASSERT(dev != NULL);
542 LASSERT(dev->obd_name != NULL);
544 return snprintf(page, count, "%s\n", dev->obd_name);
547 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
550 struct obd_device *obd = data;
552 LASSERT(obd != NULL);
553 LASSERT(obd->obd_fsops != NULL);
554 LASSERT(obd->obd_fsops->fs_type != NULL);
555 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
558 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
559 int *eof, void *data)
561 struct obd_statfs osfs;
562 int rc = obd_statfs(data, &osfs,
563 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
567 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
572 int lprocfs_rd_kbytestotal(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_blocks;
583 while (blk_size >>= 1)
587 rc = snprintf(page, count, LPU64"\n", result);
592 int lprocfs_rd_kbytesfree(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_bfree;
603 while (blk_size >>= 1)
607 rc = snprintf(page, count, LPU64"\n", result);
612 int lprocfs_rd_kbytesavail(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),
620 __u32 blk_size = osfs.os_bsize >> 10;
621 __u64 result = osfs.os_bavail;
623 while (blk_size >>= 1)
627 rc = snprintf(page, count, LPU64"\n", result);
632 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
633 int *eof, void *data)
635 struct obd_statfs osfs;
636 int rc = obd_statfs(data, &osfs,
637 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
641 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
647 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
648 int *eof, void *data)
650 struct obd_statfs osfs;
651 int rc = obd_statfs(data, &osfs,
652 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
656 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
661 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
662 int *eof, void *data)
664 struct obd_device *obd = data;
665 struct obd_import *imp;
666 char *imp_state_name = NULL;
669 LASSERT(obd != NULL);
670 LPROCFS_CLIMP_CHECK(obd);
671 imp = obd->u.cli.cl_import;
672 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
674 rc = snprintf(page, count, "%s\t%s%s\n",
675 obd2cli_tgt(obd), imp_state_name,
676 imp->imp_deactive ? "\tDEACTIVATED" : "");
678 LPROCFS_CLIMP_EXIT(obd);
682 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
683 int *eof, void *data)
685 struct obd_device *obd = data;
686 struct ptlrpc_connection *conn;
689 LASSERT(obd != NULL);
691 LPROCFS_CLIMP_CHECK(obd);
692 conn = obd->u.cli.cl_import->imp_connection;
694 if (conn && obd->u.cli.cl_import) {
695 rc = snprintf(page, count, "%s\n",
696 conn->c_remote_uuid.uuid);
698 rc = snprintf(page, count, "%s\n", "<none>");
701 LPROCFS_CLIMP_EXIT(obd);
705 /** add up per-cpu counters */
706 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
707 struct lprocfs_counter *cnt)
709 unsigned int num_cpu;
710 struct lprocfs_counter t;
711 struct lprocfs_counter *percpu_cntr;
714 memset(cnt, 0, sizeof(*cnt));
717 /* set count to 1 to avoid divide-by-zero errs in callers */
722 cnt->lc_min = LC_MIN_INIT;
724 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
726 for (i = 0; i < num_cpu; i++) {
727 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
730 centry = cfs_atomic_read(&percpu_cntr-> \
732 t.lc_count = percpu_cntr->lc_count;
733 t.lc_sum = percpu_cntr->lc_sum;
734 t.lc_min = percpu_cntr->lc_min;
735 t.lc_max = percpu_cntr->lc_max;
736 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
737 } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
739 centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
741 cnt->lc_count += t.lc_count;
742 cnt->lc_sum += t.lc_sum;
743 if (t.lc_min < cnt->lc_min)
744 cnt->lc_min = t.lc_min;
745 if (t.lc_max > cnt->lc_max)
746 cnt->lc_max = t.lc_max;
747 cnt->lc_sumsquare += t.lc_sumsquare;
750 cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
751 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
755 * Append a space separated list of current set flags to str.
757 #define flag2str(flag) \
758 if (imp->imp_##flag && max - len > 0) \
759 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
760 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
764 if (imp->imp_obd->obd_no_recov)
765 len += snprintf(str, max - len, "no_recov");
769 flag2str(replayable);
775 static const char *obd_connect_names[] = {
789 "join_file(obsolete)",
793 "remote_client_by_force",
802 "mds_mds_connection",
805 "alt_checksum_algorithm",
824 int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
829 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
831 ret += snprintf(page + ret, count - ret, "%s%s",
832 ret ? sep : "", obd_connect_names[i]);
834 if (flags & ~(mask - 1))
835 ret += snprintf(page + ret, count - ret,
836 "%sunknown flags "LPX64,
837 ret ? sep : "", flags & ~(mask - 1));
840 EXPORT_SYMBOL(obd_connect_flags2str);
842 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
843 int *eof, void *data)
845 struct lprocfs_counter ret;
846 struct obd_device *obd = (struct obd_device *)data;
847 struct obd_import *imp;
848 struct obd_import_conn *conn;
851 LASSERT(obd != NULL);
852 LPROCFS_CLIMP_CHECK(obd);
853 imp = obd->u.cli.cl_import;
856 i = snprintf(page, count,
865 ptlrpc_import_state_name(imp->imp_state),
866 imp->imp_connect_data.ocd_instance);
867 i += obd_connect_flags2str(page + i, count - i,
868 imp->imp_connect_data.ocd_connect_flags,
870 i += snprintf(page + i, count - i,
873 i += obd_import_flags2str(imp, page + i, count - i);
875 i += snprintf(page + i, count - i,
878 " failover_nids: [");
879 cfs_spin_lock(&imp->imp_lock);
881 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
882 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
883 libcfs_nid2str(conn->oic_conn->c_peer.nid));
886 cfs_spin_unlock(&imp->imp_lock);
887 i += snprintf(page + i, count - i,
889 " current_connection: %s\n"
890 " connection_attempts: %u\n"
892 " in-progress_invalidations: %u\n",
893 libcfs_nid2str(imp->imp_connection->c_peer.nid),
896 cfs_atomic_read(&imp->imp_inval_count));
898 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
899 if (ret.lc_count != 0) {
900 /* first argument to do_div MUST be __u64 */
901 __u64 sum = ret.lc_sum;
902 do_div(sum, ret.lc_count);
906 i += snprintf(page + i, count - i,
909 " unregistering: %u\n"
911 " avg_waittime: "LPU64" %s\n",
912 cfs_atomic_read(&imp->imp_inflight),
913 cfs_atomic_read(&imp->imp_unregistering),
914 cfs_atomic_read(&imp->imp_timeouts),
915 ret.lc_sum, ret.lc_units);
918 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
919 if (imp->imp_at.iat_portal[j] == 0)
921 k = max_t(unsigned int, k,
922 at_get(&imp->imp_at.iat_service_estimate[j]));
924 i += snprintf(page + i, count - i,
925 " service_estimates:\n"
926 " services: %u sec\n"
927 " network: %u sec\n",
929 at_get(&imp->imp_at.iat_net_latency));
931 i += snprintf(page + i, count - i,
933 " last_replay: "LPU64"\n"
934 " peer_committed: "LPU64"\n"
935 " last_checked: "LPU64"\n",
936 imp->imp_last_replay_transno,
937 imp->imp_peer_committed_transno,
938 imp->imp_last_transno_checked);
941 for (rw = 0; rw <= 1; rw++) {
942 lprocfs_stats_collect(obd->obd_svc_stats,
943 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
945 if (ret.lc_sum > 0 && ret.lc_count > 0) {
946 /* first argument to do_div MUST be __u64 */
947 __u64 sum = ret.lc_sum;
948 do_div(sum, ret.lc_count);
950 i += snprintf(page + i, count - i,
951 " %s_data_averages:\n"
952 " bytes_per_rpc: "LPU64"\n",
953 rw ? "write" : "read",
957 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
958 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
959 if (ret.lc_sum > 0 && ret.lc_count != 0) {
960 /* first argument to do_div MUST be __u64 */
961 __u64 sum = ret.lc_sum;
962 do_div(sum, ret.lc_count);
964 i += snprintf(page + i, count - i,
965 " %s_per_rpc: "LPU64"\n",
966 ret.lc_units, ret.lc_sum);
969 i += snprintf(page + i, count - i,
970 " MB_per_sec: %u.%.02u\n",
971 k / j, (100 * k / j) % 100);
975 LPROCFS_CLIMP_EXIT(obd);
979 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
980 int *eof, void *data)
982 struct obd_device *obd = (struct obd_device *)data;
983 struct obd_import *imp;
986 LASSERT(obd != NULL);
987 LPROCFS_CLIMP_CHECK(obd);
988 imp = obd->u.cli.cl_import;
991 i = snprintf(page, count, "current_state: %s\n",
992 ptlrpc_import_state_name(imp->imp_state));
993 i += snprintf(page + i, count - i,
995 k = imp->imp_state_hist_idx;
996 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
997 struct import_state_hist *ish =
998 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
999 if (ish->ish_state == 0)
1001 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
1003 ptlrpc_import_state_name(ish->ish_state));
1006 LPROCFS_CLIMP_EXIT(obd);
1010 int lprocfs_at_hist_helper(char *page, int count, int rc,
1011 struct adaptive_timeout *at)
1014 for (i = 0; i < AT_BINS; i++)
1015 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1016 rc += snprintf(page + rc, count - rc, "\n");
1020 /* See also ptlrpc_lprocfs_rd_timeouts */
1021 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1022 int *eof, void *data)
1024 struct obd_device *obd = (struct obd_device *)data;
1025 struct obd_import *imp;
1026 unsigned int cur, worst;
1031 LASSERT(obd != NULL);
1032 LPROCFS_CLIMP_CHECK(obd);
1033 imp = obd->u.cli.cl_import;
1036 now = cfs_time_current_sec();
1038 /* Some network health info for kicks */
1039 s2dhms(&ts, now - imp->imp_last_reply_time);
1040 rc += snprintf(page + rc, count - rc,
1041 "%-10s : %ld, "DHMS_FMT" ago\n",
1042 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1044 cur = at_get(&imp->imp_at.iat_net_latency);
1045 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1046 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1047 s2dhms(&ts, now - worstt);
1048 rc += snprintf(page + rc, count - rc,
1049 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1050 "network", cur, worst, worstt, DHMS_VARS(&ts));
1051 rc = lprocfs_at_hist_helper(page, count, rc,
1052 &imp->imp_at.iat_net_latency);
1054 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1055 if (imp->imp_at.iat_portal[i] == 0)
1057 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1058 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1059 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1060 s2dhms(&ts, now - worstt);
1061 rc += snprintf(page + rc, count - rc,
1062 "portal %-2d : cur %3u worst %3u (at %ld, "
1063 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1064 cur, worst, worstt, DHMS_VARS(&ts));
1065 rc = lprocfs_at_hist_helper(page, count, rc,
1066 &imp->imp_at.iat_service_estimate[i]);
1069 LPROCFS_CLIMP_EXIT(obd);
1073 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1074 int count, int *eof, void *data)
1076 struct obd_device *obd = data;
1080 LPROCFS_CLIMP_CHECK(obd);
1081 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1082 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1083 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1084 ret += snprintf(page + ret, count - ret, "\n");
1085 LPROCFS_CLIMP_EXIT(obd);
1088 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1090 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1091 int *eof, void *data)
1093 struct obd_device *obd = data;
1095 LASSERT(obd != NULL);
1097 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1100 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1101 int *eof, void *data)
1103 struct obd_type *class = (struct obd_type*) data;
1105 LASSERT(class != NULL);
1107 return snprintf(page, count, "%d\n", class->typ_refcnt);
1110 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1114 LASSERT(obd != NULL);
1115 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1116 LASSERT(obd->obd_type->typ_procroot != NULL);
1118 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1119 obd->obd_type->typ_procroot,
1121 if (IS_ERR(obd->obd_proc_entry)) {
1122 rc = PTR_ERR(obd->obd_proc_entry);
1123 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1124 obd->obd_proc_entry = NULL;
1129 int lprocfs_obd_cleanup(struct obd_device *obd)
1133 if (obd->obd_proc_exports_entry) {
1134 /* Should be no exports left */
1135 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1136 lprocfs_remove(&obd->obd_proc_exports_entry);
1137 obd->obd_proc_exports_entry = NULL;
1139 if (obd->obd_proc_entry) {
1140 lprocfs_remove(&obd->obd_proc_entry);
1141 obd->obd_proc_entry = NULL;
1146 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1148 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1149 client_stat->nid_proc, client_stat->nid_stats,
1150 client_stat->nid_brw_stats);
1152 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1153 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1154 atomic_read(&client_stat->nid_exp_ref_count));
1156 if (client_stat->nid_proc)
1157 lprocfs_remove(&client_stat->nid_proc);
1159 if (client_stat->nid_stats)
1160 lprocfs_free_stats(&client_stat->nid_stats);
1162 if (client_stat->nid_brw_stats)
1163 OBD_FREE_PTR(client_stat->nid_brw_stats);
1165 if (client_stat->nid_ldlm_stats)
1166 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1168 OBD_FREE_PTR(client_stat);
1173 void lprocfs_free_per_client_stats(struct obd_device *obd)
1175 cfs_hash_t *hash = obd->obd_nid_stats_hash;
1176 struct nid_stat *stat;
1179 /* we need extra list - because hash_exit called to early */
1180 /* not need locking because all clients is died */
1181 while (!cfs_list_empty(&obd->obd_nid_stats)) {
1182 stat = cfs_list_entry(obd->obd_nid_stats.next,
1183 struct nid_stat, nid_list);
1184 cfs_list_del_init(&stat->nid_list);
1185 cfs_hash_del(hash, &stat->nid, &stat->nid_hash);
1186 lprocfs_free_client_stats(stat);
1191 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1192 enum lprocfs_stats_flags flags)
1194 struct lprocfs_stats *stats;
1195 unsigned int percpusize;
1197 unsigned int num_cpu;
1202 if (lprocfs_no_percpu_stats != 0)
1203 flags |= LPROCFS_STATS_FLAG_NOPERCPU;
1205 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1208 num_cpu = cfs_num_possible_cpus();
1210 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1214 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1215 stats->ls_flags = flags;
1216 cfs_spin_lock_init(&stats->ls_lock);
1217 /* Use this lock only if there are no percpu areas */
1219 stats->ls_flags = 0;
1222 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1224 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1226 for (i = 0; i < num_cpu; i++) {
1227 OBD_ALLOC(stats->ls_percpu[i], percpusize);
1228 if (stats->ls_percpu[i] == NULL) {
1229 for (j = 0; j < i; j++) {
1230 OBD_FREE(stats->ls_percpu[j], percpusize);
1231 stats->ls_percpu[j] = NULL;
1236 if (stats->ls_percpu[0] == NULL) {
1237 OBD_FREE(stats, offsetof(typeof(*stats),
1238 ls_percpu[num_cpu]));
1242 stats->ls_num = num;
1246 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1248 struct lprocfs_stats *stats = *statsh;
1249 unsigned int num_cpu;
1250 unsigned int percpusize;
1253 if (stats == NULL || stats->ls_num == 0)
1257 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1260 num_cpu = cfs_num_possible_cpus();
1262 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1264 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1265 for (i = 0; i < num_cpu; i++)
1266 OBD_FREE(stats->ls_percpu[i], percpusize);
1267 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1270 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1272 struct lprocfs_counter *percpu_cntr;
1274 unsigned int num_cpu;
1276 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1278 for (i = 0; i < num_cpu; i++) {
1279 for (j = 0; j < stats->ls_num; j++) {
1280 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1281 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1282 percpu_cntr->lc_count = 0;
1283 percpu_cntr->lc_sum = 0;
1284 percpu_cntr->lc_min = LC_MIN_INIT;
1285 percpu_cntr->lc_max = 0;
1286 percpu_cntr->lc_sumsquare = 0;
1287 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1291 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1294 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1295 size_t len, loff_t *off)
1297 struct seq_file *seq = file->private_data;
1298 struct lprocfs_stats *stats = seq->private;
1300 lprocfs_clear_stats(stats);
1305 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1307 struct lprocfs_stats *stats = p->private;
1308 /* return 1st cpu location */
1309 return (*pos >= stats->ls_num) ? NULL :
1310 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1313 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1317 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1319 struct lprocfs_stats *stats = p->private;
1321 return (*pos >= stats->ls_num) ? NULL :
1322 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1325 /* seq file export of one lprocfs counter */
1326 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1328 struct lprocfs_stats *stats = p->private;
1329 struct lprocfs_counter *cntr = v;
1330 struct lprocfs_counter ret;
1333 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1335 cfs_gettimeofday(&now);
1336 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1337 "snapshot_time", now.tv_sec, now.tv_usec);
1341 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1343 lprocfs_stats_collect(stats, idx, &ret);
1345 if (ret.lc_count == 0)
1348 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1349 ret.lc_count, cntr->lc_units);
1354 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1355 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1356 ret.lc_min, ret.lc_max, ret.lc_sum);
1359 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1360 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1364 rc = seq_printf(p, "\n");
1366 return (rc < 0) ? rc : 0;
1369 struct seq_operations lprocfs_stats_seq_sops = {
1370 start: lprocfs_stats_seq_start,
1371 stop: lprocfs_stats_seq_stop,
1372 next: lprocfs_stats_seq_next,
1373 show: lprocfs_stats_seq_show,
1376 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1378 struct proc_dir_entry *dp = PDE(inode);
1379 struct seq_file *seq;
1382 if (LPROCFS_ENTRY_AND_CHECK(dp))
1385 rc = seq_open(file, &lprocfs_stats_seq_sops);
1390 seq = file->private_data;
1391 seq->private = dp->data;
1395 struct file_operations lprocfs_stats_seq_fops = {
1396 .owner = THIS_MODULE,
1397 .open = lprocfs_stats_seq_open,
1399 .write = lprocfs_stats_seq_write,
1400 .llseek = seq_lseek,
1401 .release = lprocfs_seq_release,
1404 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1405 struct lprocfs_stats *stats)
1407 struct proc_dir_entry *entry;
1408 LASSERT(root != NULL);
1410 LPROCFS_WRITE_ENTRY();
1411 entry = create_proc_entry(name, 0644, root);
1413 entry->proc_fops = &lprocfs_stats_seq_fops;
1414 entry->data = stats;
1417 LPROCFS_WRITE_EXIT();
1425 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1426 unsigned conf, const char *name, const char *units)
1428 struct lprocfs_counter *c;
1430 unsigned int num_cpu;
1432 LASSERT(stats != NULL);
1434 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1436 for (i = 0; i < num_cpu; i++) {
1437 c = &(stats->ls_percpu[i]->lp_cntr[index]);
1438 c->lc_config = conf;
1441 c->lc_min = LC_MIN_INIT;
1444 c->lc_units = units;
1447 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1449 EXPORT_SYMBOL(lprocfs_counter_init);
1451 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1453 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1454 LASSERT(coffset < stats->ls_num); \
1455 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1458 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1460 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1461 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1462 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1463 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1467 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1468 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1469 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1470 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1471 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1472 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1473 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1474 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1475 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1476 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1477 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1478 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1479 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1480 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1481 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1482 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1483 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1484 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1485 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1486 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1487 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1488 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1489 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1490 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1491 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1492 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1493 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1494 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1495 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1496 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1497 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1498 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1499 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1500 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1501 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1502 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1503 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1504 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1505 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1506 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1507 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1508 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1509 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1510 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1511 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1512 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1513 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1514 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1515 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1516 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1517 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1518 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1519 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1520 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1521 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1522 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1523 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1524 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1525 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1526 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1527 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1528 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1531 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1533 struct lprocfs_stats *stats;
1534 unsigned int num_stats;
1537 LASSERT(obd->obd_stats == NULL);
1538 LASSERT(obd->obd_proc_entry != NULL);
1539 LASSERT(obd->obd_cntr_base == 0);
1541 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1542 num_private_stats - 1 /* o_owner */;
1543 stats = lprocfs_alloc_stats(num_stats, 0);
1547 lprocfs_init_ops_stats(num_private_stats, stats);
1549 for (i = num_private_stats; i < num_stats; i++) {
1550 /* If this LBUGs, it is likely that an obd
1551 * operation was added to struct obd_ops in
1552 * <obd.h>, and that the corresponding line item
1553 * LPROCFS_OBD_OP_INIT(.., .., opname)
1554 * is missing from the list above. */
1555 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1556 "Missing obd_stat initializer obd_op "
1557 "operation at offset %d.\n", i - num_private_stats);
1559 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1561 lprocfs_free_stats(&stats);
1563 obd->obd_stats = stats;
1564 obd->obd_cntr_base = num_private_stats;
1569 void lprocfs_free_obd_stats(struct obd_device *obd)
1572 lprocfs_free_stats(&obd->obd_stats);
1575 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1577 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1578 LASSERT(coffset < stats->ls_num); \
1579 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1582 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1584 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1585 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1586 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1587 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1588 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1589 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1590 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1591 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1592 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1593 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1594 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1595 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1596 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1597 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1598 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1599 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1600 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1601 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1602 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1603 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1604 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1605 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1606 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1607 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1608 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1609 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1610 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1611 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1612 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1613 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1614 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1615 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1618 int lprocfs_alloc_md_stats(struct obd_device *obd,
1619 unsigned num_private_stats)
1621 struct lprocfs_stats *stats;
1622 unsigned int num_stats;
1625 LASSERT(obd->md_stats == NULL);
1626 LASSERT(obd->obd_proc_entry != NULL);
1627 LASSERT(obd->md_cntr_base == 0);
1629 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1631 stats = lprocfs_alloc_stats(num_stats, 0);
1635 lprocfs_init_mps_stats(num_private_stats, stats);
1637 for (i = num_private_stats; i < num_stats; i++) {
1638 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1639 CERROR("Missing md_stat initializer md_op "
1640 "operation at offset %d. Aborting.\n",
1641 i - num_private_stats);
1645 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1647 lprocfs_free_stats(&stats);
1649 obd->md_stats = stats;
1650 obd->md_cntr_base = num_private_stats;
1655 void lprocfs_free_md_stats(struct obd_device *obd)
1657 struct lprocfs_stats *stats = obd->md_stats;
1659 if (stats != NULL) {
1660 obd->md_stats = NULL;
1661 obd->md_cntr_base = 0;
1662 lprocfs_free_stats(&stats);
1666 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1668 lprocfs_counter_init(ldlm_stats,
1669 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1670 0, "ldlm_enqueue", "reqs");
1671 lprocfs_counter_init(ldlm_stats,
1672 LDLM_CONVERT - LDLM_FIRST_OPC,
1673 0, "ldlm_convert", "reqs");
1674 lprocfs_counter_init(ldlm_stats,
1675 LDLM_CANCEL - LDLM_FIRST_OPC,
1676 0, "ldlm_cancel", "reqs");
1677 lprocfs_counter_init(ldlm_stats,
1678 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1679 0, "ldlm_bl_callback", "reqs");
1680 lprocfs_counter_init(ldlm_stats,
1681 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1682 0, "ldlm_cp_callback", "reqs");
1683 lprocfs_counter_init(ldlm_stats,
1684 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1685 0, "ldlm_gl_callback", "reqs");
1688 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1689 int *eof, void *data)
1691 struct obd_export *exp = data;
1692 LASSERT(exp != NULL);
1694 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1697 struct exp_uuid_cb_data {
1705 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1706 int count, int *eof, int *len)
1708 cb_data->page = page;
1709 cb_data->count = count;
1714 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1715 cfs_hlist_node_t *hnode, void *cb_data)
1718 struct obd_export *exp = cfs_hash_object(hs, hnode);
1719 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1721 if (exp->exp_nid_stats)
1722 *data->len += snprintf((data->page + *data->len),
1723 data->count, "%s\n",
1724 obd_uuid2str(&exp->exp_client_uuid));
1728 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1729 int *eof, void *data)
1731 struct nid_stat *stats = (struct nid_stat *)data;
1732 struct exp_uuid_cb_data cb_data;
1733 struct obd_device *obd = stats->nid_obd;
1738 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1739 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1740 lprocfs_exp_print_uuid, &cb_data);
1741 return (*cb_data.len);
1744 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1745 cfs_hlist_node_t *hnode, void *cb_data)
1748 struct exp_uuid_cb_data *data = cb_data;
1749 struct obd_export *exp = cfs_hash_object(hs, hnode);
1751 if (exp->exp_lock_hash != NULL) {
1753 *data->len += cfs_hash_debug_header(data->page,
1756 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1763 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1764 int *eof, void *data)
1766 struct nid_stat *stats = (struct nid_stat *)data;
1767 struct exp_uuid_cb_data cb_data;
1768 struct obd_device *obd = stats->nid_obd;
1773 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1775 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1776 lprocfs_exp_print_hash, &cb_data);
1777 return (*cb_data.len);
1780 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1781 int count, int *eof, void *data)
1784 return snprintf(page, count, "%s\n",
1785 "Write into this file to clear all nid stats and "
1786 "stale nid entries");
1788 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1790 static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1792 struct nid_stat *stat = obj;
1796 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1797 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1798 /* object has only hash references. */
1799 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1800 cfs_list_move(&stat->nid_list, data);
1801 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1804 /* we has reference to object - only clear data*/
1805 if (stat->nid_stats)
1806 lprocfs_clear_stats(stat->nid_stats);
1808 if (stat->nid_brw_stats) {
1809 for (i = 0; i < BRW_LAST; i++)
1810 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1815 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1816 unsigned long count, void *data)
1818 struct obd_device *obd = (struct obd_device *)data;
1819 struct nid_stat *client_stat;
1820 CFS_LIST_HEAD(free_list);
1822 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1823 lprocfs_nid_stats_clear_write_cb, &free_list);
1825 while (!cfs_list_empty(&free_list)) {
1826 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1828 cfs_list_del_init(&client_stat->nid_list);
1829 lprocfs_free_client_stats(client_stat);
1834 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1836 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1838 struct nid_stat *new_stat, *old_stat;
1839 struct obd_device *obd = NULL;
1840 cfs_proc_dir_entry_t *entry;
1841 char *buffer = NULL;
1847 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1848 !exp->exp_obd->obd_nid_stats_hash)
1851 /* not test against zero because eric say:
1852 * You may only test nid against another nid, or LNET_NID_ANY.
1853 * Anything else is nonsense.*/
1854 if (!nid || *nid == LNET_NID_ANY)
1859 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1861 OBD_ALLOC_PTR(new_stat);
1862 if (new_stat == NULL)
1865 new_stat->nid = *nid;
1866 new_stat->nid_obd = exp->exp_obd;
1867 /* we need set default refcount to 1 to balance obd_disconnect */
1868 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1870 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1871 nid, &new_stat->nid_hash);
1872 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1873 old_stat, libcfs_nid2str(*nid),
1874 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1876 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1877 * been and will never be called. */
1878 if (exp->exp_nid_stats) {
1879 nidstat_putref(exp->exp_nid_stats);
1880 exp->exp_nid_stats = NULL;
1883 /* Return -EALREADY here so that we know that the /proc
1884 * entry already has been created */
1885 if (old_stat != new_stat) {
1886 exp->exp_nid_stats = old_stat;
1887 GOTO(destroy_new, rc = -EALREADY);
1889 /* not found - create */
1890 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1892 GOTO(destroy_new, rc = -ENOMEM);
1894 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1895 new_stat->nid_proc = lprocfs_register(buffer,
1896 obd->obd_proc_exports_entry,
1898 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1900 if (new_stat->nid_proc == NULL) {
1901 CERROR("Error making export directory for nid %s\n",
1902 libcfs_nid2str(*nid));
1903 GOTO(destroy_new_ns, rc = -ENOMEM);
1906 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1907 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1908 if (IS_ERR(entry)) {
1909 CWARN("Error adding the NID stats file\n");
1910 rc = PTR_ERR(entry);
1911 GOTO(destroy_new_ns, rc);
1914 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1915 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1916 if (IS_ERR(entry)) {
1917 CWARN("Error adding the hash file\n");
1918 rc = PTR_ERR(entry);
1919 GOTO(destroy_new_ns, rc);
1922 exp->exp_nid_stats = new_stat;
1924 /* protect competitive add to list, not need locking on destroy */
1925 cfs_spin_lock(&obd->obd_nid_lock);
1926 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1927 cfs_spin_unlock(&obd->obd_nid_lock);
1932 if (new_stat->nid_proc != NULL)
1933 lprocfs_remove(&new_stat->nid_proc);
1934 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1937 nidstat_putref(new_stat);
1938 OBD_FREE_PTR(new_stat);
1942 int lprocfs_exp_cleanup(struct obd_export *exp)
1944 struct nid_stat *stat = exp->exp_nid_stats;
1946 if(!stat || !exp->exp_obd)
1949 nidstat_putref(exp->exp_nid_stats);
1950 exp->exp_nid_stats = NULL;
1955 int lprocfs_write_helper(const char *buffer, unsigned long count,
1958 return lprocfs_write_frac_helper(buffer, count, val, 1);
1961 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1964 char kernbuf[20], *end, *pbuf;
1966 if (count > (sizeof(kernbuf) - 1))
1969 if (cfs_copy_from_user(kernbuf, buffer, count))
1972 kernbuf[count] = '\0';
1979 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1983 if (end != NULL && *end == '.') {
1984 int temp_val, pow = 1;
1988 if (strlen(pbuf) > 5)
1989 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1991 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1994 for (i = 0; i < (end - pbuf); i++)
1997 *val += temp_val / pow;
2003 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
2006 long decimal_val, frac_val;
2012 decimal_val = val / mult;
2013 prtn = snprintf(buffer, count, "%ld", decimal_val);
2014 frac_val = val % mult;
2016 if (prtn < (count - 4) && frac_val > 0) {
2018 int i, temp_mult = 1, frac_bits = 0;
2020 temp_frac = frac_val * 10;
2021 buffer[prtn++] = '.';
2022 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2023 /* only reserved 2 bits fraction */
2024 buffer[prtn++] ='0';
2029 * Need to think these cases :
2030 * 1. #echo x.00 > /proc/xxx output result : x
2031 * 2. #echo x.0x > /proc/xxx output result : x.0x
2032 * 3. #echo x.x0 > /proc/xxx output result : x.x
2033 * 4. #echo x.xx > /proc/xxx output result : x.xx
2034 * Only reserved 2 bits fraction.
2036 for (i = 0; i < (5 - prtn); i++)
2039 frac_bits = min((int)count - prtn, 3 - frac_bits);
2040 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2041 frac_val * temp_mult / mult);
2044 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2046 if (buffer[prtn] == '.') {
2053 buffer[prtn++] ='\n';
2057 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2059 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2062 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2063 __u64 *val, int mult)
2065 char kernbuf[22], *end, *pbuf;
2066 __u64 whole, frac = 0, units;
2067 unsigned frac_d = 1;
2069 if (count > (sizeof(kernbuf) - 1))
2072 if (cfs_copy_from_user(kernbuf, buffer, count))
2075 kernbuf[count] = '\0';
2082 whole = simple_strtoull(pbuf, &end, 10);
2086 if (end != NULL && *end == '.') {
2090 /* need to limit frac_d to a __u32 */
2091 if (strlen(pbuf) > 10)
2094 frac = simple_strtoull(pbuf, &end, 10);
2095 /* count decimal places */
2096 for (i = 0; i < (end - pbuf); i++)
2113 /* Specified units override the multiplier */
2115 mult = mult < 0 ? -units : units;
2118 do_div(frac, frac_d);
2119 *val = whole * mult + frac;
2123 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2124 struct file_operations *seq_fops, void *data)
2126 struct proc_dir_entry *entry;
2129 LPROCFS_WRITE_ENTRY();
2130 entry = create_proc_entry(name, mode, parent);
2132 entry->proc_fops = seq_fops;
2135 LPROCFS_WRITE_EXIT();
2142 EXPORT_SYMBOL(lprocfs_seq_create);
2144 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2146 struct file_operations *seq_fops,
2149 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2150 mode, seq_fops, data));
2152 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2154 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2156 if (value >= OBD_HIST_MAX)
2157 value = OBD_HIST_MAX - 1;
2159 cfs_spin_lock(&oh->oh_lock);
2160 oh->oh_buckets[value]++;
2161 cfs_spin_unlock(&oh->oh_lock);
2163 EXPORT_SYMBOL(lprocfs_oh_tally);
2165 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2169 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2172 lprocfs_oh_tally(oh, val);
2174 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2176 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2178 unsigned long ret = 0;
2181 for (i = 0; i < OBD_HIST_MAX; i++)
2182 ret += oh->oh_buckets[i];
2185 EXPORT_SYMBOL(lprocfs_oh_sum);
2187 void lprocfs_oh_clear(struct obd_histogram *oh)
2189 cfs_spin_lock(&oh->oh_lock);
2190 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2191 cfs_spin_unlock(&oh->oh_lock);
2193 EXPORT_SYMBOL(lprocfs_oh_clear);
2195 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2196 int count, int *eof, void *data)
2198 struct obd_device *obd = data;
2204 c += cfs_hash_debug_header(page, count);
2205 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2206 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2207 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2208 #ifdef HAVE_QUOTA_SUPPORT
2209 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2210 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2211 page + c, count - c);
2216 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2218 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2219 int count, int *eof, void *data)
2221 struct obd_device *obd = data;
2224 LASSERT(obd != NULL);
2225 LASSERT(count >= 0);
2227 /* Set start of user data returned to
2228 page + off since the user may have
2229 requested to read much smaller than
2230 what we need to read */
2231 *start = page + off;
2233 /* We know we are allocated a page here.
2234 Also we know that this function will
2235 not need to write more than a page
2236 so we can truncate at CFS_PAGE_SIZE. */
2237 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2239 /* Initialize the page */
2240 memset(page, 0, size);
2242 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2244 if (obd->obd_max_recoverable_clients == 0) {
2245 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2251 /* sampled unlocked, but really... */
2252 if (obd->obd_recovering == 0) {
2253 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2255 if (lprocfs_obd_snprintf(&page, size, &len,
2256 "recovery_start: %lu\n",
2257 obd->obd_recovery_start) <= 0)
2259 if (lprocfs_obd_snprintf(&page, size, &len,
2260 "recovery_duration: %lu\n",
2261 obd->obd_recovery_end -
2262 obd->obd_recovery_start) <= 0)
2264 /* Number of clients that have completed recovery */
2265 if (lprocfs_obd_snprintf(&page, size, &len,
2266 "completed_clients: %d/%d\n",
2267 obd->obd_max_recoverable_clients -
2268 obd->obd_stale_clients,
2269 obd->obd_max_recoverable_clients) <= 0)
2271 if (lprocfs_obd_snprintf(&page, size, &len,
2272 "replayed_requests: %d\n",
2273 obd->obd_replayed_requests) <= 0)
2275 if (lprocfs_obd_snprintf(&page, size, &len,
2276 "last_transno: "LPD64"\n",
2277 obd->obd_next_recovery_transno - 1)<=0)
2279 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2280 obd->obd_version_recov ? "ON" : "OFF")<=0)
2282 if (lprocfs_obd_snprintf(&page, size, &len, "IR: %s\n",
2283 obd->obd_no_ir ? "OFF" : "ON") <= 0)
2288 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2290 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2291 obd->obd_recovery_start) <= 0)
2293 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2294 cfs_time_current_sec() >=
2295 obd->obd_recovery_start +
2296 obd->obd_recovery_timeout ? 0 :
2297 obd->obd_recovery_start +
2298 obd->obd_recovery_timeout -
2299 cfs_time_current_sec()) <= 0)
2301 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2302 cfs_atomic_read(&obd->obd_connected_clients),
2303 obd->obd_max_recoverable_clients) <= 0)
2305 /* Number of clients that have completed recovery */
2306 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2307 cfs_atomic_read(&obd->obd_req_replay_clients))
2310 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2311 cfs_atomic_read(&obd->obd_lock_replay_clients))
2314 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2315 cfs_atomic_read(&obd->obd_connected_clients) -
2316 cfs_atomic_read(&obd->obd_lock_replay_clients))
2319 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2320 obd->obd_stale_clients) <= 0)
2322 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2323 obd->obd_replayed_requests) <= 0)
2325 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2326 obd->obd_requests_queued_for_recovery) <= 0)
2329 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2330 obd->obd_next_recovery_transno) <= 0)
2336 return min(count, len - (int)off);
2338 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2340 int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off,
2341 int count, int *eof, void *data)
2343 struct obd_device *obd = (struct obd_device *)data;
2344 LASSERT(obd != NULL);
2346 return snprintf(page, count, "%d\n",
2347 obd->obd_recovery_ir_factor);
2349 EXPORT_SYMBOL(lprocfs_obd_rd_ir_factor);
2351 int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer,
2352 unsigned long count, void *data)
2354 struct obd_device *obd = (struct obd_device *)data;
2356 LASSERT(obd != NULL);
2358 rc = lprocfs_write_helper(buffer, count, &val);
2362 if (val < OBD_IR_FACTOR_MIN || val > OBD_IR_FACTOR_MAX)
2365 obd->obd_recovery_ir_factor = val;
2368 EXPORT_SYMBOL(lprocfs_obd_wr_ir_factor);
2370 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2371 int count, int *eof, void *data)
2373 struct obd_device *obd = (struct obd_device *)data;
2374 LASSERT(obd != NULL);
2376 return snprintf(page, count, "%d\n",
2377 obd->obd_recovery_timeout);
2379 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2381 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2382 unsigned long count, void *data)
2384 struct obd_device *obd = (struct obd_device *)data;
2386 LASSERT(obd != NULL);
2388 rc = lprocfs_write_helper(buffer, count, &val);
2392 obd->obd_recovery_timeout = val;
2395 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2397 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2398 int count, int *eof, void *data)
2400 struct obd_device *obd = data;
2401 LASSERT(obd != NULL);
2403 return snprintf(page, count, "%u\n", obd->obd_recovery_time_hard);
2405 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2407 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2408 unsigned long count, void *data)
2410 struct obd_device *obd = data;
2412 LASSERT(obd != NULL);
2414 rc = lprocfs_write_helper(buffer, count, &val);
2418 obd->obd_recovery_time_hard = val;
2421 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2423 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2424 int count, int *eof, void *data)
2426 struct obd_device *obd = (struct obd_device *)data;
2428 LASSERT(obd != NULL);
2429 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2431 return snprintf(page, count, "%s\n",
2432 obd->u.obt.obt_vfsmnt->mnt_devname);
2434 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2436 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2437 int count, int *eof, void *data)
2439 struct obd_device *dev = data;
2440 struct client_obd *cli = &dev->u.cli;
2443 client_obd_list_lock(&cli->cl_loi_list_lock);
2444 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2445 client_obd_list_unlock(&cli->cl_loi_list_lock);
2448 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2450 int lprocfs_obd_wr_max_pages_per_rpc(struct file *file, const char *buffer,
2451 unsigned long count, void *data)
2453 struct obd_device *dev = data;
2454 struct client_obd *cli = &dev->u.cli;
2455 struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
2458 rc = lprocfs_write_helper(buffer, count, &val);
2462 LPROCFS_CLIMP_CHECK(dev);
2463 if (val < 1 || val > ocd->ocd_brw_size >> CFS_PAGE_SHIFT) {
2464 LPROCFS_CLIMP_EXIT(dev);
2467 client_obd_list_lock(&cli->cl_loi_list_lock);
2468 cli->cl_max_pages_per_rpc = val;
2469 client_obd_list_unlock(&cli->cl_loi_list_lock);
2471 LPROCFS_CLIMP_EXIT(dev);
2474 EXPORT_SYMBOL(lprocfs_obd_wr_max_pages_per_rpc);
2476 int lprocfs_target_rd_instance(char *page, char **start, off_t off,
2477 int count, int *eof, void *data)
2479 struct obd_device *obd = (struct obd_device *)data;
2480 struct obd_device_target *target = &obd->u.obt;
2482 LASSERT(obd != NULL);
2483 LASSERT(target->obt_magic == OBT_MAGIC);
2485 return snprintf(page, count, "%u\n", obd->u.obt.obt_instance);
2487 EXPORT_SYMBOL(lprocfs_target_rd_instance);
2489 EXPORT_SYMBOL(lprocfs_register);
2490 EXPORT_SYMBOL(lprocfs_srch);
2491 EXPORT_SYMBOL(lprocfs_remove);
2492 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2493 EXPORT_SYMBOL(lprocfs_add_vars);
2494 EXPORT_SYMBOL(lprocfs_obd_setup);
2495 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2496 EXPORT_SYMBOL(lprocfs_add_simple);
2497 EXPORT_SYMBOL(lprocfs_add_symlink);
2498 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2499 EXPORT_SYMBOL(lprocfs_alloc_stats);
2500 EXPORT_SYMBOL(lprocfs_free_stats);
2501 EXPORT_SYMBOL(lprocfs_clear_stats);
2502 EXPORT_SYMBOL(lprocfs_register_stats);
2503 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2504 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2505 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2506 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2507 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2508 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2509 EXPORT_SYMBOL(lprocfs_free_md_stats);
2510 EXPORT_SYMBOL(lprocfs_exp_setup);
2511 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2513 EXPORT_SYMBOL(lprocfs_rd_u64);
2514 EXPORT_SYMBOL(lprocfs_rd_atomic);
2515 EXPORT_SYMBOL(lprocfs_wr_atomic);
2516 EXPORT_SYMBOL(lprocfs_rd_uint);
2517 EXPORT_SYMBOL(lprocfs_wr_uint);
2518 EXPORT_SYMBOL(lprocfs_rd_uuid);
2519 EXPORT_SYMBOL(lprocfs_rd_name);
2520 EXPORT_SYMBOL(lprocfs_rd_fstype);
2521 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2522 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2523 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2524 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2525 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2526 EXPORT_SYMBOL(lprocfs_rd_import);
2527 EXPORT_SYMBOL(lprocfs_rd_state);
2528 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2529 EXPORT_SYMBOL(lprocfs_rd_blksize);
2530 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2531 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2532 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2533 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2534 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2536 EXPORT_SYMBOL(lprocfs_write_helper);
2537 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2538 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2539 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2540 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2541 EXPORT_SYMBOL(lprocfs_stats_collect);