4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, Whamcloud, Inc.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/obdclass/lprocfs_status.c
38 * Author: Hariharan Thantry <thantry@users.sourceforge.net>
41 #define DEBUG_SUBSYSTEM S_CLASS
44 # include <liblustre.h>
47 #include <obd_class.h>
48 #include <lprocfs_status.h>
49 #include <lustre_fsfilt.h>
50 #include <lustre_log.h>
51 #include <lustre/lustre_idl.h>
55 static int lprocfs_no_percpu_stats = 0;
56 CFS_MODULE_PARM(lprocfs_no_percpu_stats, "i", int, 0644,
57 "Do not alloc percpu data for lprocfs stats");
59 #define MAX_STRING_SIZE 128
61 /* for bug 10866, global variable */
62 CFS_DECLARE_RWSEM(_lprocfs_lock);
63 EXPORT_SYMBOL(_lprocfs_lock);
65 int lprocfs_seq_release(struct inode *inode, struct file *file)
68 return seq_release(inode, file);
70 EXPORT_SYMBOL(lprocfs_seq_release);
72 static struct proc_dir_entry *__lprocfs_srch(struct proc_dir_entry *head,
75 struct proc_dir_entry *temp;
81 while (temp != NULL) {
82 if (strcmp(temp->name, name) == 0) {
91 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
94 struct proc_dir_entry *temp;
97 temp = __lprocfs_srch(head, name);
102 /* lprocfs API calls */
104 /* Function that emulates snprintf but also has the side effect of advancing
105 the page pointer for the next write into the buffer, incrementing the total
106 length written to the buffer, and decrementing the size left in the
108 static int lprocfs_obd_snprintf(char **page, int end, int *len,
109 const char *format, ...)
117 va_start(list, format);
118 n = vsnprintf(*page, end - *len, format, list);
121 *page += n; *len += n;
125 cfs_proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
127 read_proc_t *read_proc,
128 write_proc_t *write_proc,
130 struct file_operations *fops)
132 cfs_proc_dir_entry_t *proc;
135 if (root == NULL || name == NULL)
136 return ERR_PTR(-EINVAL);
143 LPROCFS_WRITE_ENTRY();
144 proc = create_proc_entry(name, mode, root);
146 CERROR("LprocFS: No memory to create /proc entry %s", name);
147 LPROCFS_WRITE_EXIT();
148 return ERR_PTR(-ENOMEM);
150 proc->read_proc = read_proc;
151 proc->write_proc = write_proc;
154 proc->proc_fops = fops;
155 LPROCFS_WRITE_EXIT();
159 struct proc_dir_entry *lprocfs_add_symlink(const char *name,
160 struct proc_dir_entry *parent, const char *format, ...)
162 struct proc_dir_entry *entry;
166 if (parent == NULL || format == NULL)
169 OBD_ALLOC_WAIT(dest, MAX_STRING_SIZE + 1);
173 va_start(ap, format);
174 vsnprintf(dest, MAX_STRING_SIZE, format, ap);
177 entry = proc_symlink(name, parent, dest);
179 CERROR("LprocFS: Could not create symbolic link from %s to %s",
182 OBD_FREE(dest, MAX_STRING_SIZE + 1);
186 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
187 size_t size, loff_t *ppos)
189 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
190 char *page, *start = NULL;
191 int rc = 0, eof = 1, count;
193 if (*ppos >= CFS_PAGE_SIZE)
196 page = (char *)__get_free_page(GFP_KERNEL);
200 if (LPROCFS_ENTRY_AND_CHECK(dp)) {
205 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
207 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
213 /* for lustre proc read, the read count must be less than PAGE_SIZE */
222 start = page + *ppos;
223 } else if (start < page) {
227 count = (rc < size) ? rc : size;
228 if (cfs_copy_to_user(buf, start, count)) {
235 free_page((unsigned long)page);
239 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
240 size_t size, loff_t *ppos)
242 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
245 if (LPROCFS_ENTRY_AND_CHECK(dp))
248 rc = dp->write_proc(f, buf, size, dp->data);
253 static struct file_operations lprocfs_generic_fops = {
254 .owner = THIS_MODULE,
255 .read = lprocfs_fops_read,
256 .write = lprocfs_fops_write,
259 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
261 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
262 struct obd_device *obd = dp->data;
264 cfs_atomic_inc(&obd->obd_evict_inprogress);
269 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
271 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
272 struct obd_device *obd = dp->data;
274 cfs_atomic_dec(&obd->obd_evict_inprogress);
275 cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
280 struct file_operations lprocfs_evict_client_fops = {
281 .owner = THIS_MODULE,
282 .read = lprocfs_fops_read,
283 .write = lprocfs_fops_write,
284 .open = lprocfs_evict_client_open,
285 .release = lprocfs_evict_client_release,
287 EXPORT_SYMBOL(lprocfs_evict_client_fops);
292 * \param root [in] The parent proc entry on which new entry will be added.
293 * \param list [in] Array of proc entries to be added.
294 * \param data [in] The argument to be passed when entries read/write routines
295 * are called through /proc file.
297 * \retval 0 on success
300 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
305 if (root == NULL || list == NULL)
308 LPROCFS_WRITE_ENTRY();
309 while (list->name != NULL) {
310 struct proc_dir_entry *cur_root, *proc;
311 char *pathcopy, *cur, *next, pathbuf[64];
312 int pathsize = strlen(list->name) + 1;
317 /* need copy of path for strsep */
318 if (strlen(list->name) > sizeof(pathbuf) - 1) {
319 OBD_ALLOC(pathcopy, pathsize);
320 if (pathcopy == NULL)
321 GOTO(out, rc = -ENOMEM);
327 strcpy(pathcopy, list->name);
329 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
330 if (*cur =='\0') /* skip double/trailing "/" */
333 proc = __lprocfs_srch(cur_root, cur);
334 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
335 cur_root->name, cur, next,
336 (proc ? "exists" : "new"));
338 cur_root = (proc ? proc :
339 proc_mkdir(cur, cur_root));
340 } else if (proc == NULL) {
342 if (list->proc_mode != 0000) {
343 mode = list->proc_mode;
347 if (list->write_fptr)
350 proc = create_proc_entry(cur, mode, cur_root);
354 if (pathcopy != pathbuf)
355 OBD_FREE(pathcopy, pathsize);
357 if (cur_root == NULL || proc == NULL) {
358 CERROR("LprocFS: No memory to create /proc entry %s",
360 GOTO(out, rc = -ENOMEM);
364 proc->proc_fops = list->fops;
366 proc->proc_fops = &lprocfs_generic_fops;
367 proc->read_proc = list->read_fptr;
368 proc->write_proc = list->write_fptr;
369 proc->data = (list->data ? list->data : data);
373 LPROCFS_WRITE_EXIT();
377 void lprocfs_remove(struct proc_dir_entry **rooth)
379 struct proc_dir_entry *root = *rooth;
380 struct proc_dir_entry *temp = root;
381 struct proc_dir_entry *rm_entry;
382 struct proc_dir_entry *parent;
388 parent = root->parent;
389 LASSERT(parent != NULL);
390 LPROCFS_WRITE_ENTRY(); /* search vs remove race */
393 while (temp->subdir != NULL)
399 /* Memory corruption once caused this to fail, and
400 without this LASSERT we would loop here forever. */
401 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
402 "0x%p %s/%s len %d\n", rm_entry, temp->name,
403 rm_entry->name, (int)strlen(rm_entry->name));
405 #ifdef HAVE_PROCFS_USERS
406 /* if procfs uses user count to synchronize deletion of
407 * proc entry, there is no protection for rm_entry->data,
408 * then lprocfs_fops_read and lprocfs_fops_write maybe
409 * call proc_dir_entry->read_proc (or write_proc) with
410 * proc_dir_entry->data == NULL, then cause kernel Oops.
411 * see bug19706 for detailed information */
413 /* procfs won't free rm_entry->data if it isn't a LINK,
414 * and Lustre won't use rm_entry->data if it is a LINK */
415 if (S_ISLNK(rm_entry->mode))
416 rm_entry->data = NULL;
418 /* Now, the rm_entry->deleted flags is protected
419 * by _lprocfs_lock. */
420 rm_entry->data = NULL;
422 remove_proc_entry(rm_entry->name, temp);
426 LPROCFS_WRITE_EXIT();
429 void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
431 LASSERT(parent != NULL);
432 remove_proc_entry(name, parent);
435 struct proc_dir_entry *lprocfs_register(const char *name,
436 struct proc_dir_entry *parent,
437 struct lprocfs_vars *list, void *data)
439 struct proc_dir_entry *newchild;
441 newchild = lprocfs_srch(parent, name);
442 if (newchild != NULL) {
443 CERROR(" Lproc: Attempting to register %s more than once \n",
445 return ERR_PTR(-EALREADY);
448 newchild = proc_mkdir(name, parent);
449 if (newchild != NULL && list != NULL) {
450 int rc = lprocfs_add_vars(newchild, list, data);
452 lprocfs_remove(&newchild);
459 /* Generic callbacks */
460 int lprocfs_rd_uint(char *page, char **start, off_t off,
461 int count, int *eof, void *data)
463 unsigned int *temp = data;
464 return snprintf(page, count, "%u\n", *temp);
467 int lprocfs_wr_uint(struct file *file, const char *buffer,
468 unsigned long count, void *data)
471 char dummy[MAX_STRING_SIZE + 1], *end;
474 dummy[MAX_STRING_SIZE] = '\0';
475 if (cfs_copy_from_user(dummy, buffer, MAX_STRING_SIZE))
478 tmp = simple_strtoul(dummy, &end, 0);
482 *p = (unsigned int)tmp;
486 int lprocfs_rd_u64(char *page, char **start, off_t off,
487 int count, int *eof, void *data)
489 LASSERT(data != NULL);
491 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
494 int lprocfs_rd_atomic(char *page, char **start, off_t off,
495 int count, int *eof, void *data)
497 cfs_atomic_t *atom = data;
498 LASSERT(atom != NULL);
500 return snprintf(page, count, "%d\n", cfs_atomic_read(atom));
503 int lprocfs_wr_atomic(struct file *file, const char *buffer,
504 unsigned long count, void *data)
506 cfs_atomic_t *atm = data;
510 rc = lprocfs_write_helper(buffer, count, &val);
517 cfs_atomic_set(atm, val);
521 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
522 int *eof, void *data)
524 struct obd_device *obd = data;
526 LASSERT(obd != NULL);
528 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
531 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
532 int *eof, void *data)
534 struct obd_device *dev = data;
536 LASSERT(dev != NULL);
537 LASSERT(dev->obd_name != NULL);
539 return snprintf(page, count, "%s\n", dev->obd_name);
542 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
545 struct obd_device *obd = data;
547 LASSERT(obd != NULL);
548 LASSERT(obd->obd_fsops != NULL);
549 LASSERT(obd->obd_fsops->fs_type != NULL);
550 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
553 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
554 int *eof, void *data)
556 struct obd_device *obd = data;
557 struct obd_statfs osfs;
558 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
559 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
563 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
568 int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
569 int *eof, void *data)
571 struct obd_device *obd = data;
572 struct obd_statfs osfs;
573 int rc = obd_statfs(NULL, obd->obd_self_export, &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_device *obd = data;
593 struct obd_statfs osfs;
594 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
595 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
598 __u32 blk_size = osfs.os_bsize >> 10;
599 __u64 result = osfs.os_bfree;
601 while (blk_size >>= 1)
605 rc = snprintf(page, count, LPU64"\n", result);
610 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
611 int *eof, void *data)
613 struct obd_device *obd = data;
614 struct obd_statfs osfs;
615 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
616 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
619 __u32 blk_size = osfs.os_bsize >> 10;
620 __u64 result = osfs.os_bavail;
622 while (blk_size >>= 1)
626 rc = snprintf(page, count, LPU64"\n", result);
631 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
632 int *eof, void *data)
634 struct obd_device *obd = data;
635 struct obd_statfs osfs;
636 int rc = obd_statfs(NULL, obd->obd_self_export, &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_device *obd = data;
651 struct obd_statfs osfs;
652 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
653 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
657 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
662 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
663 int *eof, void *data)
665 struct obd_device *obd = data;
666 struct obd_import *imp;
667 char *imp_state_name = NULL;
670 LASSERT(obd != NULL);
671 LPROCFS_CLIMP_CHECK(obd);
672 imp = obd->u.cli.cl_import;
673 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
675 rc = snprintf(page, count, "%s\t%s%s\n",
676 obd2cli_tgt(obd), imp_state_name,
677 imp->imp_deactive ? "\tDEACTIVATED" : "");
679 LPROCFS_CLIMP_EXIT(obd);
683 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
684 int *eof, void *data)
686 struct obd_device *obd = data;
687 struct ptlrpc_connection *conn;
690 LASSERT(obd != NULL);
692 LPROCFS_CLIMP_CHECK(obd);
693 conn = obd->u.cli.cl_import->imp_connection;
695 if (conn && obd->u.cli.cl_import) {
696 rc = snprintf(page, count, "%s\n",
697 conn->c_remote_uuid.uuid);
699 rc = snprintf(page, count, "%s\n", "<none>");
702 LPROCFS_CLIMP_EXIT(obd);
706 /** add up per-cpu counters */
707 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
708 struct lprocfs_counter *cnt)
710 unsigned int num_entry;
711 struct lprocfs_counter t;
712 struct lprocfs_counter *percpu_cntr;
715 unsigned long flags = 0;
717 memset(cnt, 0, sizeof(*cnt));
720 /* set count to 1 to avoid divide-by-zero errs in callers */
725 cnt->lc_min = LC_MIN_INIT;
727 num_entry = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
729 for (i = 0; i < num_entry; i++) {
730 if (stats->ls_percpu[i] == NULL)
732 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
735 centry = cfs_atomic_read(&percpu_cntr-> \
737 t.lc_count = percpu_cntr->lc_count;
738 t.lc_sum = percpu_cntr->lc_sum;
739 t.lc_min = percpu_cntr->lc_min;
740 t.lc_max = percpu_cntr->lc_max;
741 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
742 } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
744 centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
746 cnt->lc_count += t.lc_count;
747 cnt->lc_sum += t.lc_sum;
748 if (t.lc_min < cnt->lc_min)
749 cnt->lc_min = t.lc_min;
750 if (t.lc_max > cnt->lc_max)
751 cnt->lc_max = t.lc_max;
752 cnt->lc_sumsquare += t.lc_sumsquare;
755 cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
756 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
760 * Append a space separated list of current set flags to str.
762 #define flag2str(flag) \
763 if (imp->imp_##flag && max - len > 0) \
764 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
765 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
769 if (imp->imp_obd->obd_no_recov)
770 len += snprintf(str, max - len, "no_recov");
774 flag2str(replayable);
780 static const char *obd_connect_names[] = {
794 "join_file(obsolete)",
798 "remote_client_by_force",
807 "mds_mds_connection",
810 "alt_checksum_algorithm",
829 int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
834 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
836 ret += snprintf(page + ret, count - ret, "%s%s",
837 ret ? sep : "", obd_connect_names[i]);
839 if (flags & ~(mask - 1))
840 ret += snprintf(page + ret, count - ret,
841 "%sunknown flags "LPX64,
842 ret ? sep : "", flags & ~(mask - 1));
845 EXPORT_SYMBOL(obd_connect_flags2str);
847 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
848 int *eof, void *data)
850 struct lprocfs_counter ret;
851 struct obd_device *obd = (struct obd_device *)data;
852 struct obd_import *imp;
853 struct obd_import_conn *conn;
856 LASSERT(obd != NULL);
857 LPROCFS_CLIMP_CHECK(obd);
858 imp = obd->u.cli.cl_import;
861 i = snprintf(page, count,
870 ptlrpc_import_state_name(imp->imp_state),
871 imp->imp_connect_data.ocd_instance);
872 i += obd_connect_flags2str(page + i, count - i,
873 imp->imp_connect_data.ocd_connect_flags,
875 i += snprintf(page + i, count - i,
878 i += obd_import_flags2str(imp, page + i, count - i);
880 i += snprintf(page + i, count - i,
883 " failover_nids: [");
884 cfs_spin_lock(&imp->imp_lock);
886 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
887 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
888 libcfs_nid2str(conn->oic_conn->c_peer.nid));
891 cfs_spin_unlock(&imp->imp_lock);
892 i += snprintf(page + i, count - i,
894 " current_connection: %s\n"
895 " connection_attempts: %u\n"
897 " in-progress_invalidations: %u\n",
898 libcfs_nid2str(imp->imp_connection->c_peer.nid),
901 cfs_atomic_read(&imp->imp_inval_count));
903 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
904 if (ret.lc_count != 0) {
905 /* first argument to do_div MUST be __u64 */
906 __u64 sum = ret.lc_sum;
907 do_div(sum, ret.lc_count);
911 i += snprintf(page + i, count - i,
914 " unregistering: %u\n"
916 " avg_waittime: "LPU64" %s\n",
917 cfs_atomic_read(&imp->imp_inflight),
918 cfs_atomic_read(&imp->imp_unregistering),
919 cfs_atomic_read(&imp->imp_timeouts),
920 ret.lc_sum, ret.lc_units);
923 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
924 if (imp->imp_at.iat_portal[j] == 0)
926 k = max_t(unsigned int, k,
927 at_get(&imp->imp_at.iat_service_estimate[j]));
929 i += snprintf(page + i, count - i,
930 " service_estimates:\n"
931 " services: %u sec\n"
932 " network: %u sec\n",
934 at_get(&imp->imp_at.iat_net_latency));
936 i += snprintf(page + i, count - i,
938 " last_replay: "LPU64"\n"
939 " peer_committed: "LPU64"\n"
940 " last_checked: "LPU64"\n",
941 imp->imp_last_replay_transno,
942 imp->imp_peer_committed_transno,
943 imp->imp_last_transno_checked);
946 for (rw = 0; rw <= 1; rw++) {
947 lprocfs_stats_collect(obd->obd_svc_stats,
948 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
950 if (ret.lc_sum > 0 && ret.lc_count > 0) {
951 /* first argument to do_div MUST be __u64 */
952 __u64 sum = ret.lc_sum;
953 do_div(sum, ret.lc_count);
955 i += snprintf(page + i, count - i,
956 " %s_data_averages:\n"
957 " bytes_per_rpc: "LPU64"\n",
958 rw ? "write" : "read",
962 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
963 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
964 if (ret.lc_sum > 0 && ret.lc_count != 0) {
965 /* first argument to do_div MUST be __u64 */
966 __u64 sum = ret.lc_sum;
967 do_div(sum, ret.lc_count);
969 i += snprintf(page + i, count - i,
970 " %s_per_rpc: "LPU64"\n",
971 ret.lc_units, ret.lc_sum);
974 i += snprintf(page + i, count - i,
975 " MB_per_sec: %u.%.02u\n",
976 k / j, (100 * k / j) % 100);
980 LPROCFS_CLIMP_EXIT(obd);
984 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
985 int *eof, void *data)
987 struct obd_device *obd = (struct obd_device *)data;
988 struct obd_import *imp;
991 LASSERT(obd != NULL);
992 LPROCFS_CLIMP_CHECK(obd);
993 imp = obd->u.cli.cl_import;
996 i = snprintf(page, count, "current_state: %s\n",
997 ptlrpc_import_state_name(imp->imp_state));
998 i += snprintf(page + i, count - i,
1000 k = imp->imp_state_hist_idx;
1001 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
1002 struct import_state_hist *ish =
1003 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
1004 if (ish->ish_state == 0)
1006 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
1008 ptlrpc_import_state_name(ish->ish_state));
1011 LPROCFS_CLIMP_EXIT(obd);
1015 int lprocfs_at_hist_helper(char *page, int count, int rc,
1016 struct adaptive_timeout *at)
1019 for (i = 0; i < AT_BINS; i++)
1020 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1021 rc += snprintf(page + rc, count - rc, "\n");
1025 /* See also ptlrpc_lprocfs_rd_timeouts */
1026 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1027 int *eof, void *data)
1029 struct obd_device *obd = (struct obd_device *)data;
1030 struct obd_import *imp;
1031 unsigned int cur, worst;
1036 LASSERT(obd != NULL);
1037 LPROCFS_CLIMP_CHECK(obd);
1038 imp = obd->u.cli.cl_import;
1041 now = cfs_time_current_sec();
1043 /* Some network health info for kicks */
1044 s2dhms(&ts, now - imp->imp_last_reply_time);
1045 rc += snprintf(page + rc, count - rc,
1046 "%-10s : %ld, "DHMS_FMT" ago\n",
1047 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1049 cur = at_get(&imp->imp_at.iat_net_latency);
1050 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1051 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1052 s2dhms(&ts, now - worstt);
1053 rc += snprintf(page + rc, count - rc,
1054 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1055 "network", cur, worst, worstt, DHMS_VARS(&ts));
1056 rc = lprocfs_at_hist_helper(page, count, rc,
1057 &imp->imp_at.iat_net_latency);
1059 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1060 if (imp->imp_at.iat_portal[i] == 0)
1062 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1063 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1064 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1065 s2dhms(&ts, now - worstt);
1066 rc += snprintf(page + rc, count - rc,
1067 "portal %-2d : cur %3u worst %3u (at %ld, "
1068 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1069 cur, worst, worstt, DHMS_VARS(&ts));
1070 rc = lprocfs_at_hist_helper(page, count, rc,
1071 &imp->imp_at.iat_service_estimate[i]);
1074 LPROCFS_CLIMP_EXIT(obd);
1078 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1079 int count, int *eof, void *data)
1081 struct obd_device *obd = data;
1085 LPROCFS_CLIMP_CHECK(obd);
1086 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1087 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1088 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1089 ret += snprintf(page + ret, count - ret, "\n");
1090 LPROCFS_CLIMP_EXIT(obd);
1093 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1095 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1096 int *eof, void *data)
1098 struct obd_device *obd = data;
1100 LASSERT(obd != NULL);
1102 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1105 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1106 int *eof, void *data)
1108 struct obd_type *class = (struct obd_type*) data;
1110 LASSERT(class != NULL);
1112 return snprintf(page, count, "%d\n", class->typ_refcnt);
1115 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1119 LASSERT(obd != NULL);
1120 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1121 LASSERT(obd->obd_type->typ_procroot != NULL);
1123 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1124 obd->obd_type->typ_procroot,
1126 if (IS_ERR(obd->obd_proc_entry)) {
1127 rc = PTR_ERR(obd->obd_proc_entry);
1128 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1129 obd->obd_proc_entry = NULL;
1134 int lprocfs_obd_cleanup(struct obd_device *obd)
1138 if (obd->obd_proc_exports_entry) {
1139 /* Should be no exports left */
1140 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1141 lprocfs_remove(&obd->obd_proc_exports_entry);
1142 obd->obd_proc_exports_entry = NULL;
1144 if (obd->obd_proc_entry) {
1145 lprocfs_remove(&obd->obd_proc_entry);
1146 obd->obd_proc_entry = NULL;
1151 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1153 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1154 client_stat->nid_proc, client_stat->nid_stats,
1155 client_stat->nid_brw_stats);
1157 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1158 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1159 atomic_read(&client_stat->nid_exp_ref_count));
1161 if (client_stat->nid_proc)
1162 lprocfs_remove(&client_stat->nid_proc);
1164 if (client_stat->nid_stats)
1165 lprocfs_free_stats(&client_stat->nid_stats);
1167 if (client_stat->nid_brw_stats)
1168 OBD_FREE_PTR(client_stat->nid_brw_stats);
1170 if (client_stat->nid_ldlm_stats)
1171 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1173 OBD_FREE_PTR(client_stat);
1178 void lprocfs_free_per_client_stats(struct obd_device *obd)
1180 cfs_hash_t *hash = obd->obd_nid_stats_hash;
1181 struct nid_stat *stat;
1184 /* we need extra list - because hash_exit called to early */
1185 /* not need locking because all clients is died */
1186 while (!cfs_list_empty(&obd->obd_nid_stats)) {
1187 stat = cfs_list_entry(obd->obd_nid_stats.next,
1188 struct nid_stat, nid_list);
1189 cfs_list_del_init(&stat->nid_list);
1190 cfs_hash_del(hash, &stat->nid, &stat->nid_hash);
1191 lprocfs_free_client_stats(stat);
1196 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1197 enum lprocfs_stats_flags flags)
1199 struct lprocfs_stats *stats;
1200 unsigned int percpusize;
1201 unsigned int num_entry;
1206 if (lprocfs_no_percpu_stats != 0)
1207 flags |= LPROCFS_STATS_FLAG_NOPERCPU;
1209 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1212 num_entry = cfs_num_possible_cpus() + 1;
1214 /* alloc percpu pointers for all possible cpu slots */
1215 OBD_ALLOC(stats, offsetof(struct lprocfs_stats, ls_percpu[num_entry]));
1219 stats->ls_num = num;
1220 stats->ls_biggest_alloc_num = 1;
1221 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1222 stats->ls_flags = flags;
1223 cfs_spin_lock_init(&stats->ls_lock);
1224 /* Use this lock only if there are no percpu areas */
1226 stats->ls_flags = 0;
1229 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1231 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1233 /* for no percpu area, the 0th entry is for real use,
1234 * for percpu area, the 0th entry is for intialized entry template */
1235 OBD_ALLOC(stats->ls_percpu[0], percpusize);
1236 if (stats->ls_percpu[0] == NULL) {
1238 offsetof(struct lprocfs_stats, ls_percpu[num_entry]));
1244 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1246 struct lprocfs_stats *stats = *statsh;
1247 unsigned int num_entry;
1248 unsigned int percpusize;
1251 if (stats == NULL || stats->ls_num == 0)
1255 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1258 num_entry = cfs_num_possible_cpus() + 1;
1260 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1262 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1263 for (i = 0; i < num_entry; i++)
1264 if (stats->ls_percpu[i] != NULL)
1265 OBD_FREE(stats->ls_percpu[i], percpusize);
1266 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_entry]));
1269 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1271 struct lprocfs_counter *percpu_cntr;
1274 unsigned int num_entry;
1275 unsigned long flags = 0;
1277 num_entry = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
1279 for (i = 0; i < num_entry; i++) {
1280 if (stats->ls_percpu[i] == NULL)
1282 for (j = 0; j < stats->ls_num; j++) {
1283 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1284 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1285 percpu_cntr->lc_count = 0;
1286 percpu_cntr->lc_sum = 0;
1287 percpu_cntr->lc_min = LC_MIN_INIT;
1288 percpu_cntr->lc_max = 0;
1289 percpu_cntr->lc_sumsquare = 0;
1290 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1294 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
1297 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1298 size_t len, loff_t *off)
1300 struct seq_file *seq = file->private_data;
1301 struct lprocfs_stats *stats = seq->private;
1303 lprocfs_clear_stats(stats);
1308 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1310 struct lprocfs_stats *stats = p->private;
1311 /* return 1st cpu location */
1312 return (*pos >= stats->ls_num) ? NULL :
1313 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1316 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1320 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1322 struct lprocfs_stats *stats = p->private;
1324 return (*pos >= stats->ls_num) ? NULL :
1325 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1328 /* seq file export of one lprocfs counter */
1329 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1331 struct lprocfs_stats *stats = p->private;
1332 struct lprocfs_counter *cntr = v;
1333 struct lprocfs_counter ret;
1336 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1338 cfs_gettimeofday(&now);
1339 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1340 "snapshot_time", now.tv_sec, now.tv_usec);
1344 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1346 lprocfs_stats_collect(stats, idx, &ret);
1348 if (ret.lc_count == 0)
1351 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1352 ret.lc_count, cntr->lc_units);
1357 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1358 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1359 ret.lc_min, ret.lc_max, ret.lc_sum);
1362 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1363 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1367 rc = seq_printf(p, "\n");
1369 return (rc < 0) ? rc : 0;
1372 struct seq_operations lprocfs_stats_seq_sops = {
1373 start: lprocfs_stats_seq_start,
1374 stop: lprocfs_stats_seq_stop,
1375 next: lprocfs_stats_seq_next,
1376 show: lprocfs_stats_seq_show,
1379 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1381 struct proc_dir_entry *dp = PDE(inode);
1382 struct seq_file *seq;
1385 if (LPROCFS_ENTRY_AND_CHECK(dp))
1388 rc = seq_open(file, &lprocfs_stats_seq_sops);
1393 seq = file->private_data;
1394 seq->private = dp->data;
1398 struct file_operations lprocfs_stats_seq_fops = {
1399 .owner = THIS_MODULE,
1400 .open = lprocfs_stats_seq_open,
1402 .write = lprocfs_stats_seq_write,
1403 .llseek = seq_lseek,
1404 .release = lprocfs_seq_release,
1407 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1408 struct lprocfs_stats *stats)
1410 struct proc_dir_entry *entry;
1411 LASSERT(root != NULL);
1413 LPROCFS_WRITE_ENTRY();
1414 entry = create_proc_entry(name, 0644, root);
1416 entry->proc_fops = &lprocfs_stats_seq_fops;
1417 entry->data = stats;
1420 LPROCFS_WRITE_EXIT();
1428 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1429 unsigned conf, const char *name, const char *units)
1431 struct lprocfs_counter *c = &(stats->ls_percpu[0]->lp_cntr[index]);
1432 unsigned long flags = 0;
1434 LASSERT(stats != NULL);
1435 LASSERT(stats->ls_percpu[0] != NULL);
1437 lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
1438 c->lc_config = conf;
1441 c->lc_min = LC_MIN_INIT;
1444 c->lc_units = units;
1445 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
1447 EXPORT_SYMBOL(lprocfs_counter_init);
1449 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1451 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1452 LASSERT(coffset < stats->ls_num); \
1453 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1456 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1458 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1459 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1460 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1461 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1462 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1463 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1467 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1468 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1469 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1470 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1471 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1472 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1473 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1474 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1475 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1476 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1477 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1478 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1479 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1480 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1481 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1482 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1483 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1484 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1485 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1486 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1487 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1488 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1489 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1490 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1491 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1492 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1493 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1494 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1495 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1496 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1497 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1498 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1499 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1500 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1501 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1502 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1503 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1504 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1505 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1506 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1507 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1508 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1509 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1510 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1511 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1512 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1513 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1514 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1515 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1516 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1517 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1518 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1519 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1520 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1521 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1522 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1523 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1524 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1525 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1526 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1529 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1531 struct lprocfs_stats *stats;
1532 unsigned int num_stats;
1535 LASSERT(obd->obd_stats == NULL);
1536 LASSERT(obd->obd_proc_entry != NULL);
1537 LASSERT(obd->obd_cntr_base == 0);
1539 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1540 num_private_stats - 1 /* o_owner */;
1541 stats = lprocfs_alloc_stats(num_stats, 0);
1545 lprocfs_init_ops_stats(num_private_stats, stats);
1547 for (i = num_private_stats; i < num_stats; i++) {
1548 /* If this LBUGs, it is likely that an obd
1549 * operation was added to struct obd_ops in
1550 * <obd.h>, and that the corresponding line item
1551 * LPROCFS_OBD_OP_INIT(.., .., opname)
1552 * is missing from the list above. */
1553 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1554 "Missing obd_stat initializer obd_op "
1555 "operation at offset %d.\n", i - num_private_stats);
1557 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1559 lprocfs_free_stats(&stats);
1561 obd->obd_stats = stats;
1562 obd->obd_cntr_base = num_private_stats;
1567 void lprocfs_free_obd_stats(struct obd_device *obd)
1570 lprocfs_free_stats(&obd->obd_stats);
1573 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1575 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1576 LASSERT(coffset < stats->ls_num); \
1577 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1580 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1582 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1583 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1584 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1585 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1586 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1587 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1588 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1589 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1590 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1591 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1592 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1593 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1594 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1595 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1596 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1597 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1598 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1599 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1600 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1601 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1602 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1603 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1604 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1605 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1606 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1607 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1608 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1609 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1610 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1611 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1612 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1613 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1616 int lprocfs_alloc_md_stats(struct obd_device *obd,
1617 unsigned num_private_stats)
1619 struct lprocfs_stats *stats;
1620 unsigned int num_stats;
1623 LASSERT(obd->md_stats == NULL);
1624 LASSERT(obd->obd_proc_entry != NULL);
1625 LASSERT(obd->md_cntr_base == 0);
1627 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1629 stats = lprocfs_alloc_stats(num_stats, 0);
1633 lprocfs_init_mps_stats(num_private_stats, stats);
1635 for (i = num_private_stats; i < num_stats; i++) {
1636 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1637 CERROR("Missing md_stat initializer md_op "
1638 "operation at offset %d. Aborting.\n",
1639 i - num_private_stats);
1643 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1645 lprocfs_free_stats(&stats);
1647 obd->md_stats = stats;
1648 obd->md_cntr_base = num_private_stats;
1653 void lprocfs_free_md_stats(struct obd_device *obd)
1655 struct lprocfs_stats *stats = obd->md_stats;
1657 if (stats != NULL) {
1658 obd->md_stats = NULL;
1659 obd->md_cntr_base = 0;
1660 lprocfs_free_stats(&stats);
1664 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1666 lprocfs_counter_init(ldlm_stats,
1667 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1668 0, "ldlm_enqueue", "reqs");
1669 lprocfs_counter_init(ldlm_stats,
1670 LDLM_CONVERT - LDLM_FIRST_OPC,
1671 0, "ldlm_convert", "reqs");
1672 lprocfs_counter_init(ldlm_stats,
1673 LDLM_CANCEL - LDLM_FIRST_OPC,
1674 0, "ldlm_cancel", "reqs");
1675 lprocfs_counter_init(ldlm_stats,
1676 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1677 0, "ldlm_bl_callback", "reqs");
1678 lprocfs_counter_init(ldlm_stats,
1679 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1680 0, "ldlm_cp_callback", "reqs");
1681 lprocfs_counter_init(ldlm_stats,
1682 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1683 0, "ldlm_gl_callback", "reqs");
1686 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1687 int *eof, void *data)
1689 struct obd_export *exp = data;
1690 LASSERT(exp != NULL);
1692 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1695 struct exp_uuid_cb_data {
1703 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1704 int count, int *eof, int *len)
1706 cb_data->page = page;
1707 cb_data->count = count;
1712 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1713 cfs_hlist_node_t *hnode, void *cb_data)
1716 struct obd_export *exp = cfs_hash_object(hs, hnode);
1717 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1719 if (exp->exp_nid_stats)
1720 *data->len += snprintf((data->page + *data->len),
1721 data->count, "%s\n",
1722 obd_uuid2str(&exp->exp_client_uuid));
1726 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1727 int *eof, void *data)
1729 struct nid_stat *stats = (struct nid_stat *)data;
1730 struct exp_uuid_cb_data cb_data;
1731 struct obd_device *obd = stats->nid_obd;
1736 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1737 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1738 lprocfs_exp_print_uuid, &cb_data);
1739 return (*cb_data.len);
1742 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1743 cfs_hlist_node_t *hnode, void *cb_data)
1746 struct exp_uuid_cb_data *data = cb_data;
1747 struct obd_export *exp = cfs_hash_object(hs, hnode);
1749 if (exp->exp_lock_hash != NULL) {
1751 *data->len += cfs_hash_debug_header(data->page,
1754 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1761 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1762 int *eof, void *data)
1764 struct nid_stat *stats = (struct nid_stat *)data;
1765 struct exp_uuid_cb_data cb_data;
1766 struct obd_device *obd = stats->nid_obd;
1771 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1773 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1774 lprocfs_exp_print_hash, &cb_data);
1775 return (*cb_data.len);
1778 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1779 int count, int *eof, void *data)
1782 return snprintf(page, count, "%s\n",
1783 "Write into this file to clear all nid stats and "
1784 "stale nid entries");
1786 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1788 static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1790 struct nid_stat *stat = obj;
1794 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1795 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1796 /* object has only hash references. */
1797 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1798 cfs_list_move(&stat->nid_list, data);
1799 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1802 /* we has reference to object - only clear data*/
1803 if (stat->nid_stats)
1804 lprocfs_clear_stats(stat->nid_stats);
1806 if (stat->nid_brw_stats) {
1807 for (i = 0; i < BRW_LAST; i++)
1808 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1813 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1814 unsigned long count, void *data)
1816 struct obd_device *obd = (struct obd_device *)data;
1817 struct nid_stat *client_stat;
1818 CFS_LIST_HEAD(free_list);
1820 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1821 lprocfs_nid_stats_clear_write_cb, &free_list);
1823 while (!cfs_list_empty(&free_list)) {
1824 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1826 cfs_list_del_init(&client_stat->nid_list);
1827 lprocfs_free_client_stats(client_stat);
1832 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1834 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1836 struct nid_stat *new_stat, *old_stat;
1837 struct obd_device *obd = NULL;
1838 cfs_proc_dir_entry_t *entry;
1839 char *buffer = NULL;
1845 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1846 !exp->exp_obd->obd_nid_stats_hash)
1849 /* not test against zero because eric say:
1850 * You may only test nid against another nid, or LNET_NID_ANY.
1851 * Anything else is nonsense.*/
1852 if (!nid || *nid == LNET_NID_ANY)
1857 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1859 OBD_ALLOC_PTR(new_stat);
1860 if (new_stat == NULL)
1863 new_stat->nid = *nid;
1864 new_stat->nid_obd = exp->exp_obd;
1865 /* we need set default refcount to 1 to balance obd_disconnect */
1866 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1868 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1869 nid, &new_stat->nid_hash);
1870 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1871 old_stat, libcfs_nid2str(*nid),
1872 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1874 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1875 * been and will never be called. */
1876 if (exp->exp_nid_stats) {
1877 nidstat_putref(exp->exp_nid_stats);
1878 exp->exp_nid_stats = NULL;
1881 /* Return -EALREADY here so that we know that the /proc
1882 * entry already has been created */
1883 if (old_stat != new_stat) {
1884 exp->exp_nid_stats = old_stat;
1885 GOTO(destroy_new, rc = -EALREADY);
1887 /* not found - create */
1888 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1890 GOTO(destroy_new, rc = -ENOMEM);
1892 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1893 new_stat->nid_proc = lprocfs_register(buffer,
1894 obd->obd_proc_exports_entry,
1896 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1898 if (new_stat->nid_proc == NULL) {
1899 CERROR("Error making export directory for nid %s\n",
1900 libcfs_nid2str(*nid));
1901 GOTO(destroy_new_ns, rc = -ENOMEM);
1904 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1905 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1906 if (IS_ERR(entry)) {
1907 CWARN("Error adding the NID stats file\n");
1908 rc = PTR_ERR(entry);
1909 GOTO(destroy_new_ns, rc);
1912 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1913 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1914 if (IS_ERR(entry)) {
1915 CWARN("Error adding the hash file\n");
1916 rc = PTR_ERR(entry);
1917 GOTO(destroy_new_ns, rc);
1920 exp->exp_nid_stats = new_stat;
1922 /* protect competitive add to list, not need locking on destroy */
1923 cfs_spin_lock(&obd->obd_nid_lock);
1924 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1925 cfs_spin_unlock(&obd->obd_nid_lock);
1930 if (new_stat->nid_proc != NULL)
1931 lprocfs_remove(&new_stat->nid_proc);
1932 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1935 nidstat_putref(new_stat);
1936 OBD_FREE_PTR(new_stat);
1940 int lprocfs_exp_cleanup(struct obd_export *exp)
1942 struct nid_stat *stat = exp->exp_nid_stats;
1944 if(!stat || !exp->exp_obd)
1947 nidstat_putref(exp->exp_nid_stats);
1948 exp->exp_nid_stats = NULL;
1953 int lprocfs_write_helper(const char *buffer, unsigned long count,
1956 return lprocfs_write_frac_helper(buffer, count, val, 1);
1959 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1962 char kernbuf[20], *end, *pbuf;
1964 if (count > (sizeof(kernbuf) - 1))
1967 if (cfs_copy_from_user(kernbuf, buffer, count))
1970 kernbuf[count] = '\0';
1977 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1981 if (end != NULL && *end == '.') {
1982 int temp_val, pow = 1;
1986 if (strlen(pbuf) > 5)
1987 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1989 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1992 for (i = 0; i < (end - pbuf); i++)
1995 *val += temp_val / pow;
2001 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
2004 long decimal_val, frac_val;
2010 decimal_val = val / mult;
2011 prtn = snprintf(buffer, count, "%ld", decimal_val);
2012 frac_val = val % mult;
2014 if (prtn < (count - 4) && frac_val > 0) {
2016 int i, temp_mult = 1, frac_bits = 0;
2018 temp_frac = frac_val * 10;
2019 buffer[prtn++] = '.';
2020 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2021 /* only reserved 2 bits fraction */
2022 buffer[prtn++] ='0';
2027 * Need to think these cases :
2028 * 1. #echo x.00 > /proc/xxx output result : x
2029 * 2. #echo x.0x > /proc/xxx output result : x.0x
2030 * 3. #echo x.x0 > /proc/xxx output result : x.x
2031 * 4. #echo x.xx > /proc/xxx output result : x.xx
2032 * Only reserved 2 bits fraction.
2034 for (i = 0; i < (5 - prtn); i++)
2037 frac_bits = min((int)count - prtn, 3 - frac_bits);
2038 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2039 frac_val * temp_mult / mult);
2042 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2044 if (buffer[prtn] == '.') {
2051 buffer[prtn++] ='\n';
2055 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2057 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2060 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2061 __u64 *val, int mult)
2063 char kernbuf[22], *end, *pbuf;
2064 __u64 whole, frac = 0, units;
2065 unsigned frac_d = 1;
2067 if (count > (sizeof(kernbuf) - 1))
2070 if (cfs_copy_from_user(kernbuf, buffer, count))
2073 kernbuf[count] = '\0';
2080 whole = simple_strtoull(pbuf, &end, 10);
2084 if (end != NULL && *end == '.') {
2088 /* need to limit frac_d to a __u32 */
2089 if (strlen(pbuf) > 10)
2092 frac = simple_strtoull(pbuf, &end, 10);
2093 /* count decimal places */
2094 for (i = 0; i < (end - pbuf); i++)
2111 /* Specified units override the multiplier */
2113 mult = mult < 0 ? -units : units;
2116 do_div(frac, frac_d);
2117 *val = whole * mult + frac;
2121 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2122 struct file_operations *seq_fops, void *data)
2124 struct proc_dir_entry *entry;
2127 LPROCFS_WRITE_ENTRY();
2128 entry = create_proc_entry(name, mode, parent);
2130 entry->proc_fops = seq_fops;
2133 LPROCFS_WRITE_EXIT();
2140 EXPORT_SYMBOL(lprocfs_seq_create);
2142 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2144 struct file_operations *seq_fops,
2147 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2148 mode, seq_fops, data));
2150 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2152 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2154 if (value >= OBD_HIST_MAX)
2155 value = OBD_HIST_MAX - 1;
2157 cfs_spin_lock(&oh->oh_lock);
2158 oh->oh_buckets[value]++;
2159 cfs_spin_unlock(&oh->oh_lock);
2161 EXPORT_SYMBOL(lprocfs_oh_tally);
2163 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2167 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2170 lprocfs_oh_tally(oh, val);
2172 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2174 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2176 unsigned long ret = 0;
2179 for (i = 0; i < OBD_HIST_MAX; i++)
2180 ret += oh->oh_buckets[i];
2183 EXPORT_SYMBOL(lprocfs_oh_sum);
2185 void lprocfs_oh_clear(struct obd_histogram *oh)
2187 cfs_spin_lock(&oh->oh_lock);
2188 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2189 cfs_spin_unlock(&oh->oh_lock);
2191 EXPORT_SYMBOL(lprocfs_oh_clear);
2193 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2194 int count, int *eof, void *data)
2196 struct obd_device *obd = data;
2202 c += cfs_hash_debug_header(page, count);
2203 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2204 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2205 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2206 #ifdef HAVE_QUOTA_SUPPORT
2207 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2208 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2209 page + c, count - c);
2214 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2216 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2217 int count, int *eof, void *data)
2219 struct obd_device *obd = data;
2222 LASSERT(obd != NULL);
2223 LASSERT(count >= 0);
2225 /* Set start of user data returned to
2226 page + off since the user may have
2227 requested to read much smaller than
2228 what we need to read */
2229 *start = page + off;
2231 /* We know we are allocated a page here.
2232 Also we know that this function will
2233 not need to write more than a page
2234 so we can truncate at CFS_PAGE_SIZE. */
2235 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2237 /* Initialize the page */
2238 memset(page, 0, size);
2240 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2242 if (obd->obd_max_recoverable_clients == 0) {
2243 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2249 /* sampled unlocked, but really... */
2250 if (obd->obd_recovering == 0) {
2251 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2253 if (lprocfs_obd_snprintf(&page, size, &len,
2254 "recovery_start: %lu\n",
2255 obd->obd_recovery_start) <= 0)
2257 if (lprocfs_obd_snprintf(&page, size, &len,
2258 "recovery_duration: %lu\n",
2259 obd->obd_recovery_end -
2260 obd->obd_recovery_start) <= 0)
2262 /* Number of clients that have completed recovery */
2263 if (lprocfs_obd_snprintf(&page, size, &len,
2264 "completed_clients: %d/%d\n",
2265 obd->obd_max_recoverable_clients -
2266 obd->obd_stale_clients,
2267 obd->obd_max_recoverable_clients) <= 0)
2269 if (lprocfs_obd_snprintf(&page, size, &len,
2270 "replayed_requests: %d\n",
2271 obd->obd_replayed_requests) <= 0)
2273 if (lprocfs_obd_snprintf(&page, size, &len,
2274 "last_transno: "LPD64"\n",
2275 obd->obd_next_recovery_transno - 1)<=0)
2277 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2278 obd->obd_version_recov ? "ON" : "OFF")<=0)
2280 if (lprocfs_obd_snprintf(&page, size, &len, "IR: %s\n",
2281 obd->obd_no_ir ? "OFF" : "ON") <= 0)
2286 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2288 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2289 obd->obd_recovery_start) <= 0)
2291 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2292 cfs_time_current_sec() >=
2293 obd->obd_recovery_start +
2294 obd->obd_recovery_timeout ? 0 :
2295 obd->obd_recovery_start +
2296 obd->obd_recovery_timeout -
2297 cfs_time_current_sec()) <= 0)
2299 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2300 cfs_atomic_read(&obd->obd_connected_clients),
2301 obd->obd_max_recoverable_clients) <= 0)
2303 /* Number of clients that have completed recovery */
2304 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2305 cfs_atomic_read(&obd->obd_req_replay_clients))
2308 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2309 cfs_atomic_read(&obd->obd_lock_replay_clients))
2312 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2313 cfs_atomic_read(&obd->obd_connected_clients) -
2314 cfs_atomic_read(&obd->obd_lock_replay_clients))
2317 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2318 obd->obd_stale_clients) <= 0)
2320 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2321 obd->obd_replayed_requests) <= 0)
2323 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2324 obd->obd_requests_queued_for_recovery) <= 0)
2327 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2328 obd->obd_next_recovery_transno) <= 0)
2334 return min(count, len - (int)off);
2336 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2338 int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off,
2339 int count, int *eof, void *data)
2341 struct obd_device *obd = (struct obd_device *)data;
2342 LASSERT(obd != NULL);
2344 return snprintf(page, count, "%d\n",
2345 obd->obd_recovery_ir_factor);
2347 EXPORT_SYMBOL(lprocfs_obd_rd_ir_factor);
2349 int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer,
2350 unsigned long count, void *data)
2352 struct obd_device *obd = (struct obd_device *)data;
2354 LASSERT(obd != NULL);
2356 rc = lprocfs_write_helper(buffer, count, &val);
2360 if (val < OBD_IR_FACTOR_MIN || val > OBD_IR_FACTOR_MAX)
2363 obd->obd_recovery_ir_factor = val;
2366 EXPORT_SYMBOL(lprocfs_obd_wr_ir_factor);
2368 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2369 int count, int *eof, void *data)
2371 struct obd_device *obd = (struct obd_device *)data;
2372 LASSERT(obd != NULL);
2374 return snprintf(page, count, "%d\n",
2375 obd->obd_recovery_timeout);
2377 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2379 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2380 unsigned long count, void *data)
2382 struct obd_device *obd = (struct obd_device *)data;
2384 LASSERT(obd != NULL);
2386 rc = lprocfs_write_helper(buffer, count, &val);
2390 obd->obd_recovery_timeout = val;
2393 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2395 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2396 int count, int *eof, void *data)
2398 struct obd_device *obd = data;
2399 LASSERT(obd != NULL);
2401 return snprintf(page, count, "%u\n", obd->obd_recovery_time_hard);
2403 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2405 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2406 unsigned long count, void *data)
2408 struct obd_device *obd = data;
2410 LASSERT(obd != NULL);
2412 rc = lprocfs_write_helper(buffer, count, &val);
2416 obd->obd_recovery_time_hard = val;
2419 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2421 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2422 int count, int *eof, void *data)
2424 struct obd_device *obd = (struct obd_device *)data;
2426 LASSERT(obd != NULL);
2427 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2429 return snprintf(page, count, "%s\n",
2430 obd->u.obt.obt_vfsmnt->mnt_devname);
2432 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2434 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2435 int count, int *eof, void *data)
2437 struct obd_device *dev = data;
2438 struct client_obd *cli = &dev->u.cli;
2441 client_obd_list_lock(&cli->cl_loi_list_lock);
2442 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2443 client_obd_list_unlock(&cli->cl_loi_list_lock);
2446 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2448 int lprocfs_obd_wr_max_pages_per_rpc(struct file *file, const char *buffer,
2449 unsigned long count, void *data)
2451 struct obd_device *dev = data;
2452 struct client_obd *cli = &dev->u.cli;
2453 struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
2456 rc = lprocfs_write_helper(buffer, count, &val);
2460 LPROCFS_CLIMP_CHECK(dev);
2461 if (val < 1 || val > ocd->ocd_brw_size >> CFS_PAGE_SHIFT) {
2462 LPROCFS_CLIMP_EXIT(dev);
2465 client_obd_list_lock(&cli->cl_loi_list_lock);
2466 cli->cl_max_pages_per_rpc = val;
2467 client_obd_list_unlock(&cli->cl_loi_list_lock);
2469 LPROCFS_CLIMP_EXIT(dev);
2472 EXPORT_SYMBOL(lprocfs_obd_wr_max_pages_per_rpc);
2474 int lprocfs_target_rd_instance(char *page, char **start, off_t off,
2475 int count, int *eof, void *data)
2477 struct obd_device *obd = (struct obd_device *)data;
2478 struct obd_device_target *target = &obd->u.obt;
2480 LASSERT(obd != NULL);
2481 LASSERT(target->obt_magic == OBT_MAGIC);
2483 return snprintf(page, count, "%u\n", obd->u.obt.obt_instance);
2485 EXPORT_SYMBOL(lprocfs_target_rd_instance);
2487 EXPORT_SYMBOL(lprocfs_register);
2488 EXPORT_SYMBOL(lprocfs_srch);
2489 EXPORT_SYMBOL(lprocfs_remove);
2490 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2491 EXPORT_SYMBOL(lprocfs_add_vars);
2492 EXPORT_SYMBOL(lprocfs_obd_setup);
2493 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2494 EXPORT_SYMBOL(lprocfs_add_simple);
2495 EXPORT_SYMBOL(lprocfs_add_symlink);
2496 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2497 EXPORT_SYMBOL(lprocfs_alloc_stats);
2498 EXPORT_SYMBOL(lprocfs_free_stats);
2499 EXPORT_SYMBOL(lprocfs_clear_stats);
2500 EXPORT_SYMBOL(lprocfs_register_stats);
2501 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2502 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2503 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2504 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2505 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2506 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2507 EXPORT_SYMBOL(lprocfs_free_md_stats);
2508 EXPORT_SYMBOL(lprocfs_exp_setup);
2509 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2511 EXPORT_SYMBOL(lprocfs_rd_u64);
2512 EXPORT_SYMBOL(lprocfs_rd_atomic);
2513 EXPORT_SYMBOL(lprocfs_wr_atomic);
2514 EXPORT_SYMBOL(lprocfs_rd_uint);
2515 EXPORT_SYMBOL(lprocfs_wr_uint);
2516 EXPORT_SYMBOL(lprocfs_rd_uuid);
2517 EXPORT_SYMBOL(lprocfs_rd_name);
2518 EXPORT_SYMBOL(lprocfs_rd_fstype);
2519 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2520 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2521 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2522 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2523 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2524 EXPORT_SYMBOL(lprocfs_rd_import);
2525 EXPORT_SYMBOL(lprocfs_rd_state);
2526 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2527 EXPORT_SYMBOL(lprocfs_rd_blksize);
2528 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2529 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2530 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2531 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2532 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2534 EXPORT_SYMBOL(lprocfs_write_helper);
2535 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2536 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2537 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2538 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2539 EXPORT_SYMBOL(lprocfs_stats_collect);