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 #define MAX_STRING_SIZE 128
62 /* for bug 10866, global variable */
63 CFS_DECLARE_RWSEM(_lprocfs_lock);
64 EXPORT_SYMBOL(_lprocfs_lock);
66 int lprocfs_seq_release(struct inode *inode, struct file *file)
69 return seq_release(inode, file);
71 EXPORT_SYMBOL(lprocfs_seq_release);
73 static struct proc_dir_entry *__lprocfs_srch(struct proc_dir_entry *head,
76 struct proc_dir_entry *temp;
82 while (temp != NULL) {
83 if (strcmp(temp->name, name) == 0) {
92 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
95 struct proc_dir_entry *temp;
98 temp = __lprocfs_srch(head, name);
103 /* lprocfs API calls */
105 /* Function that emulates snprintf but also has the side effect of advancing
106 the page pointer for the next write into the buffer, incrementing the total
107 length written to the buffer, and decrementing the size left in the
109 static int lprocfs_obd_snprintf(char **page, int end, int *len,
110 const char *format, ...)
118 va_start(list, format);
119 n = vsnprintf(*page, end - *len, format, list);
122 *page += n; *len += n;
126 cfs_proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
128 read_proc_t *read_proc,
129 write_proc_t *write_proc,
131 struct file_operations *fops)
133 cfs_proc_dir_entry_t *proc;
136 if (root == NULL || name == NULL)
137 return ERR_PTR(-EINVAL);
144 LPROCFS_WRITE_ENTRY();
145 proc = create_proc_entry(name, mode, root);
147 CERROR("LprocFS: No memory to create /proc entry %s", name);
148 LPROCFS_WRITE_EXIT();
149 return ERR_PTR(-ENOMEM);
151 proc->read_proc = read_proc;
152 proc->write_proc = write_proc;
155 proc->proc_fops = fops;
156 LPROCFS_WRITE_EXIT();
160 struct proc_dir_entry *lprocfs_add_symlink(const char *name,
161 struct proc_dir_entry *parent, const char *format, ...)
163 struct proc_dir_entry *entry;
167 if (parent == NULL || format == NULL)
170 OBD_ALLOC_WAIT(dest, MAX_STRING_SIZE + 1);
174 va_start(ap, format);
175 vsnprintf(dest, MAX_STRING_SIZE, format, ap);
178 entry = proc_symlink(name, parent, dest);
180 CERROR("LprocFS: Could not create symbolic link from %s to %s",
183 OBD_FREE(dest, MAX_STRING_SIZE + 1);
187 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
188 size_t size, loff_t *ppos)
190 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
191 char *page, *start = NULL;
192 int rc = 0, eof = 1, count;
194 if (*ppos >= CFS_PAGE_SIZE)
197 page = (char *)__get_free_page(GFP_KERNEL);
201 if (LPROCFS_ENTRY_AND_CHECK(dp)) {
206 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
208 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
214 /* for lustre proc read, the read count must be less than PAGE_SIZE */
223 start = page + *ppos;
224 } else if (start < page) {
228 count = (rc < size) ? rc : size;
229 if (cfs_copy_to_user(buf, start, count)) {
236 free_page((unsigned long)page);
240 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
241 size_t size, loff_t *ppos)
243 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
246 if (LPROCFS_ENTRY_AND_CHECK(dp))
249 rc = dp->write_proc(f, buf, size, dp->data);
254 static struct file_operations lprocfs_generic_fops = {
255 .owner = THIS_MODULE,
256 .read = lprocfs_fops_read,
257 .write = lprocfs_fops_write,
260 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
262 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
263 struct obd_device *obd = dp->data;
265 cfs_atomic_inc(&obd->obd_evict_inprogress);
270 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
272 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
273 struct obd_device *obd = dp->data;
275 cfs_atomic_dec(&obd->obd_evict_inprogress);
276 cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
281 struct file_operations lprocfs_evict_client_fops = {
282 .owner = THIS_MODULE,
283 .read = lprocfs_fops_read,
284 .write = lprocfs_fops_write,
285 .open = lprocfs_evict_client_open,
286 .release = lprocfs_evict_client_release,
288 EXPORT_SYMBOL(lprocfs_evict_client_fops);
293 * \param root [in] The parent proc entry on which new entry will be added.
294 * \param list [in] Array of proc entries to be added.
295 * \param data [in] The argument to be passed when entries read/write routines
296 * are called through /proc file.
298 * \retval 0 on success
301 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
306 if (root == NULL || list == NULL)
309 LPROCFS_WRITE_ENTRY();
310 while (list->name != NULL) {
311 struct proc_dir_entry *cur_root, *proc;
312 char *pathcopy, *cur, *next, pathbuf[64];
313 int pathsize = strlen(list->name) + 1;
318 /* need copy of path for strsep */
319 if (strlen(list->name) > sizeof(pathbuf) - 1) {
320 OBD_ALLOC(pathcopy, pathsize);
321 if (pathcopy == NULL)
322 GOTO(out, rc = -ENOMEM);
328 strcpy(pathcopy, list->name);
330 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
331 if (*cur =='\0') /* skip double/trailing "/" */
334 proc = __lprocfs_srch(cur_root, cur);
335 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
336 cur_root->name, cur, next,
337 (proc ? "exists" : "new"));
339 cur_root = (proc ? proc :
340 proc_mkdir(cur, cur_root));
341 } else if (proc == NULL) {
343 if (list->proc_mode != 0000) {
344 mode = list->proc_mode;
348 if (list->write_fptr)
351 proc = create_proc_entry(cur, mode, cur_root);
355 if (pathcopy != pathbuf)
356 OBD_FREE(pathcopy, pathsize);
358 if (cur_root == NULL || proc == NULL) {
359 CERROR("LprocFS: No memory to create /proc entry %s",
361 GOTO(out, rc = -ENOMEM);
365 proc->proc_fops = list->fops;
367 proc->proc_fops = &lprocfs_generic_fops;
368 proc->read_proc = list->read_fptr;
369 proc->write_proc = list->write_fptr;
370 proc->data = (list->data ? list->data : data);
374 LPROCFS_WRITE_EXIT();
378 void lprocfs_remove(struct proc_dir_entry **rooth)
380 struct proc_dir_entry *root = *rooth;
381 struct proc_dir_entry *temp = root;
382 struct proc_dir_entry *rm_entry;
383 struct proc_dir_entry *parent;
389 parent = root->parent;
390 LASSERT(parent != NULL);
391 LPROCFS_WRITE_ENTRY(); /* search vs remove race */
394 while (temp->subdir != NULL)
400 /* Memory corruption once caused this to fail, and
401 without this LASSERT we would loop here forever. */
402 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
403 "0x%p %s/%s len %d\n", rm_entry, temp->name,
404 rm_entry->name, (int)strlen(rm_entry->name));
406 #ifdef HAVE_PROCFS_USERS
407 /* if procfs uses user count to synchronize deletion of
408 * proc entry, there is no protection for rm_entry->data,
409 * then lprocfs_fops_read and lprocfs_fops_write maybe
410 * call proc_dir_entry->read_proc (or write_proc) with
411 * proc_dir_entry->data == NULL, then cause kernel Oops.
412 * see bug19706 for detailed information */
414 /* procfs won't free rm_entry->data if it isn't a LINK,
415 * and Lustre won't use rm_entry->data if it is a LINK */
416 if (S_ISLNK(rm_entry->mode))
417 rm_entry->data = NULL;
419 /* Now, the rm_entry->deleted flags is protected
420 * by _lprocfs_lock. */
421 rm_entry->data = NULL;
423 remove_proc_entry(rm_entry->name, temp);
427 LPROCFS_WRITE_EXIT();
430 void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
432 LASSERT(parent != NULL);
433 remove_proc_entry(name, parent);
436 struct proc_dir_entry *lprocfs_register(const char *name,
437 struct proc_dir_entry *parent,
438 struct lprocfs_vars *list, void *data)
440 struct proc_dir_entry *newchild;
442 newchild = lprocfs_srch(parent, name);
443 if (newchild != NULL) {
444 CERROR(" Lproc: Attempting to register %s more than once \n",
446 return ERR_PTR(-EALREADY);
449 newchild = proc_mkdir(name, parent);
450 if (newchild != NULL && list != NULL) {
451 int rc = lprocfs_add_vars(newchild, list, data);
453 lprocfs_remove(&newchild);
460 /* Generic callbacks */
461 int lprocfs_rd_uint(char *page, char **start, off_t off,
462 int count, int *eof, void *data)
464 unsigned int *temp = data;
465 return snprintf(page, count, "%u\n", *temp);
468 int lprocfs_wr_uint(struct file *file, const char *buffer,
469 unsigned long count, void *data)
472 char dummy[MAX_STRING_SIZE + 1], *end;
475 dummy[MAX_STRING_SIZE] = '\0';
476 if (cfs_copy_from_user(dummy, buffer, MAX_STRING_SIZE))
479 tmp = simple_strtoul(dummy, &end, 0);
483 *p = (unsigned int)tmp;
487 int lprocfs_rd_u64(char *page, char **start, off_t off,
488 int count, int *eof, void *data)
490 LASSERT(data != NULL);
492 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
495 int lprocfs_rd_atomic(char *page, char **start, off_t off,
496 int count, int *eof, void *data)
498 cfs_atomic_t *atom = data;
499 LASSERT(atom != NULL);
501 return snprintf(page, count, "%d\n", cfs_atomic_read(atom));
504 int lprocfs_wr_atomic(struct file *file, const char *buffer,
505 unsigned long count, void *data)
507 cfs_atomic_t *atm = data;
511 rc = lprocfs_write_helper(buffer, count, &val);
518 cfs_atomic_set(atm, val);
522 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
523 int *eof, void *data)
525 struct obd_device *obd = data;
527 LASSERT(obd != NULL);
529 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
532 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
533 int *eof, void *data)
535 struct obd_device *dev = data;
537 LASSERT(dev != NULL);
538 LASSERT(dev->obd_name != NULL);
540 return snprintf(page, count, "%s\n", dev->obd_name);
543 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
546 struct obd_device *obd = data;
548 LASSERT(obd != NULL);
549 LASSERT(obd->obd_fsops != NULL);
550 LASSERT(obd->obd_fsops->fs_type != NULL);
551 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
554 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
555 int *eof, void *data)
557 struct obd_statfs osfs;
558 int rc = obd_statfs(data, &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_statfs osfs;
572 int rc = obd_statfs(data, &osfs,
573 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
576 __u32 blk_size = osfs.os_bsize >> 10;
577 __u64 result = osfs.os_blocks;
579 while (blk_size >>= 1)
583 rc = snprintf(page, count, LPU64"\n", result);
588 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
589 int *eof, void *data)
591 struct obd_statfs osfs;
592 int rc = obd_statfs(data, &osfs,
593 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
596 __u32 blk_size = osfs.os_bsize >> 10;
597 __u64 result = osfs.os_bfree;
599 while (blk_size >>= 1)
603 rc = snprintf(page, count, LPU64"\n", result);
608 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
609 int *eof, void *data)
611 struct obd_statfs osfs;
612 int rc = obd_statfs(data, &osfs,
613 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
616 __u32 blk_size = osfs.os_bsize >> 10;
617 __u64 result = osfs.os_bavail;
619 while (blk_size >>= 1)
623 rc = snprintf(page, count, LPU64"\n", result);
628 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
629 int *eof, void *data)
631 struct obd_statfs osfs;
632 int rc = obd_statfs(data, &osfs,
633 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
637 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
643 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
644 int *eof, void *data)
646 struct obd_statfs osfs;
647 int rc = obd_statfs(data, &osfs,
648 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
652 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
657 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
658 int *eof, void *data)
660 struct obd_device *obd = data;
661 struct obd_import *imp;
662 char *imp_state_name = NULL;
665 LASSERT(obd != NULL);
666 LPROCFS_CLIMP_CHECK(obd);
667 imp = obd->u.cli.cl_import;
668 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
670 rc = snprintf(page, count, "%s\t%s%s\n",
671 obd2cli_tgt(obd), imp_state_name,
672 imp->imp_deactive ? "\tDEACTIVATED" : "");
674 LPROCFS_CLIMP_EXIT(obd);
678 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
679 int *eof, void *data)
681 struct obd_device *obd = data;
682 struct ptlrpc_connection *conn;
685 LASSERT(obd != NULL);
687 LPROCFS_CLIMP_CHECK(obd);
688 conn = obd->u.cli.cl_import->imp_connection;
690 if (conn && obd->u.cli.cl_import) {
691 rc = snprintf(page, count, "%s\n",
692 conn->c_remote_uuid.uuid);
694 rc = snprintf(page, count, "%s\n", "<none>");
697 LPROCFS_CLIMP_EXIT(obd);
701 /** add up per-cpu counters */
702 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
703 struct lprocfs_counter *cnt)
705 unsigned int num_cpu;
706 struct lprocfs_counter t;
707 struct lprocfs_counter *percpu_cntr;
710 memset(cnt, 0, sizeof(*cnt));
713 /* set count to 1 to avoid divide-by-zero errs in callers */
718 cnt->lc_min = LC_MIN_INIT;
720 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
722 for (i = 0; i < num_cpu; i++) {
723 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
726 centry = cfs_atomic_read(&percpu_cntr-> \
728 t.lc_count = percpu_cntr->lc_count;
729 t.lc_sum = percpu_cntr->lc_sum;
730 t.lc_min = percpu_cntr->lc_min;
731 t.lc_max = percpu_cntr->lc_max;
732 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
733 } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
735 centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
737 cnt->lc_count += t.lc_count;
738 cnt->lc_sum += t.lc_sum;
739 if (t.lc_min < cnt->lc_min)
740 cnt->lc_min = t.lc_min;
741 if (t.lc_max > cnt->lc_max)
742 cnt->lc_max = t.lc_max;
743 cnt->lc_sumsquare += t.lc_sumsquare;
746 cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
747 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
751 * Append a space separated list of current set flags to str.
753 #define flag2str(flag) \
754 if (imp->imp_##flag && max - len > 0) \
755 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
756 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
760 if (imp->imp_obd->obd_no_recov)
761 len += snprintf(str, max - len, "no_recov");
765 flag2str(replayable);
771 static const char *obd_connect_names[] = {
785 "join_file(obsolete)",
789 "remote_client_by_force",
798 "mds_mds_connection",
801 "alt_checksum_algorithm",
818 int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
823 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
825 ret += snprintf(page + ret, count - ret, "%s%s",
826 ret ? sep : "", obd_connect_names[i]);
828 if (flags & ~(mask - 1))
829 ret += snprintf(page + ret, count - ret,
830 "%sunknown flags "LPX64,
831 ret ? sep : "", flags & ~(mask - 1));
834 EXPORT_SYMBOL(obd_connect_flags2str);
836 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
837 int *eof, void *data)
839 struct lprocfs_counter ret;
840 struct obd_device *obd = (struct obd_device *)data;
841 struct obd_import *imp;
842 struct obd_import_conn *conn;
845 LASSERT(obd != NULL);
846 LPROCFS_CLIMP_CHECK(obd);
847 imp = obd->u.cli.cl_import;
850 i = snprintf(page, count,
859 ptlrpc_import_state_name(imp->imp_state),
860 imp->imp_connect_data.ocd_instance);
861 i += obd_connect_flags2str(page + i, count - i,
862 imp->imp_connect_data.ocd_connect_flags,
864 i += snprintf(page + i, count - i,
867 i += obd_import_flags2str(imp, page + i, count - i);
869 i += snprintf(page + i, count - i,
872 " failover_nids: [");
873 cfs_spin_lock(&imp->imp_lock);
875 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
876 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
877 libcfs_nid2str(conn->oic_conn->c_peer.nid));
880 cfs_spin_unlock(&imp->imp_lock);
881 i += snprintf(page + i, count - i,
883 " current_connection: %s\n"
884 " connection_attempts: %u\n"
886 " in-progress_invalidations: %u\n",
887 libcfs_nid2str(imp->imp_connection->c_peer.nid),
890 cfs_atomic_read(&imp->imp_inval_count));
892 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
893 if (ret.lc_count != 0) {
894 /* first argument to do_div MUST be __u64 */
895 __u64 sum = ret.lc_sum;
896 do_div(sum, ret.lc_count);
900 i += snprintf(page + i, count - i,
903 " unregistering: %u\n"
905 " avg_waittime: "LPU64" %s\n",
906 cfs_atomic_read(&imp->imp_inflight),
907 cfs_atomic_read(&imp->imp_unregistering),
908 cfs_atomic_read(&imp->imp_timeouts),
909 ret.lc_sum, ret.lc_units);
912 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
913 if (imp->imp_at.iat_portal[j] == 0)
915 k = max_t(unsigned int, k,
916 at_get(&imp->imp_at.iat_service_estimate[j]));
918 i += snprintf(page + i, count - i,
919 " service_estimates:\n"
920 " services: %u sec\n"
921 " network: %u sec\n",
923 at_get(&imp->imp_at.iat_net_latency));
925 i += snprintf(page + i, count - i,
927 " last_replay: "LPU64"\n"
928 " peer_committed: "LPU64"\n"
929 " last_checked: "LPU64"\n",
930 imp->imp_last_replay_transno,
931 imp->imp_peer_committed_transno,
932 imp->imp_last_transno_checked);
935 for (rw = 0; rw <= 1; rw++) {
936 lprocfs_stats_collect(obd->obd_svc_stats,
937 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
939 if (ret.lc_sum > 0 && ret.lc_count > 0) {
940 /* first argument to do_div MUST be __u64 */
941 __u64 sum = ret.lc_sum;
942 do_div(sum, ret.lc_count);
944 i += snprintf(page + i, count - i,
945 " %s_data_averages:\n"
946 " bytes_per_rpc: "LPU64"\n",
947 rw ? "write" : "read",
951 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
952 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
953 if (ret.lc_sum > 0 && ret.lc_count != 0) {
954 /* first argument to do_div MUST be __u64 */
955 __u64 sum = ret.lc_sum;
956 do_div(sum, ret.lc_count);
958 i += snprintf(page + i, count - i,
959 " %s_per_rpc: "LPU64"\n",
960 ret.lc_units, ret.lc_sum);
963 i += snprintf(page + i, count - i,
964 " MB_per_sec: %u.%.02u\n",
965 k / j, (100 * k / j) % 100);
969 LPROCFS_CLIMP_EXIT(obd);
973 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
974 int *eof, void *data)
976 struct obd_device *obd = (struct obd_device *)data;
977 struct obd_import *imp;
980 LASSERT(obd != NULL);
981 LPROCFS_CLIMP_CHECK(obd);
982 imp = obd->u.cli.cl_import;
985 i = snprintf(page, count, "current_state: %s\n",
986 ptlrpc_import_state_name(imp->imp_state));
987 i += snprintf(page + i, count - i,
989 k = imp->imp_state_hist_idx;
990 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
991 struct import_state_hist *ish =
992 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
993 if (ish->ish_state == 0)
995 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
997 ptlrpc_import_state_name(ish->ish_state));
1000 LPROCFS_CLIMP_EXIT(obd);
1004 int lprocfs_at_hist_helper(char *page, int count, int rc,
1005 struct adaptive_timeout *at)
1008 for (i = 0; i < AT_BINS; i++)
1009 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1010 rc += snprintf(page + rc, count - rc, "\n");
1014 /* See also ptlrpc_lprocfs_rd_timeouts */
1015 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1016 int *eof, void *data)
1018 struct obd_device *obd = (struct obd_device *)data;
1019 struct obd_import *imp;
1020 unsigned int cur, worst;
1025 LASSERT(obd != NULL);
1026 LPROCFS_CLIMP_CHECK(obd);
1027 imp = obd->u.cli.cl_import;
1030 now = cfs_time_current_sec();
1032 /* Some network health info for kicks */
1033 s2dhms(&ts, now - imp->imp_last_reply_time);
1034 rc += snprintf(page + rc, count - rc,
1035 "%-10s : %ld, "DHMS_FMT" ago\n",
1036 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1038 cur = at_get(&imp->imp_at.iat_net_latency);
1039 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1040 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1041 s2dhms(&ts, now - worstt);
1042 rc += snprintf(page + rc, count - rc,
1043 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1044 "network", cur, worst, worstt, DHMS_VARS(&ts));
1045 rc = lprocfs_at_hist_helper(page, count, rc,
1046 &imp->imp_at.iat_net_latency);
1048 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1049 if (imp->imp_at.iat_portal[i] == 0)
1051 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1052 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1053 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1054 s2dhms(&ts, now - worstt);
1055 rc += snprintf(page + rc, count - rc,
1056 "portal %-2d : cur %3u worst %3u (at %ld, "
1057 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1058 cur, worst, worstt, DHMS_VARS(&ts));
1059 rc = lprocfs_at_hist_helper(page, count, rc,
1060 &imp->imp_at.iat_service_estimate[i]);
1063 LPROCFS_CLIMP_EXIT(obd);
1067 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1068 int count, int *eof, void *data)
1070 struct obd_device *obd = data;
1074 LPROCFS_CLIMP_CHECK(obd);
1075 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1076 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1077 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1078 ret += snprintf(page + ret, count - ret, "\n");
1079 LPROCFS_CLIMP_EXIT(obd);
1082 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1084 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1085 int *eof, void *data)
1087 struct obd_device *obd = data;
1089 LASSERT(obd != NULL);
1091 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1094 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1095 int *eof, void *data)
1097 struct obd_type *class = (struct obd_type*) data;
1099 LASSERT(class != NULL);
1101 return snprintf(page, count, "%d\n", class->typ_refcnt);
1104 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1108 LASSERT(obd != NULL);
1109 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1110 LASSERT(obd->obd_type->typ_procroot != NULL);
1112 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1113 obd->obd_type->typ_procroot,
1115 if (IS_ERR(obd->obd_proc_entry)) {
1116 rc = PTR_ERR(obd->obd_proc_entry);
1117 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1118 obd->obd_proc_entry = NULL;
1123 int lprocfs_obd_cleanup(struct obd_device *obd)
1127 if (obd->obd_proc_exports_entry) {
1128 /* Should be no exports left */
1129 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1130 lprocfs_remove(&obd->obd_proc_exports_entry);
1131 obd->obd_proc_exports_entry = NULL;
1133 if (obd->obd_proc_entry) {
1134 lprocfs_remove(&obd->obd_proc_entry);
1135 obd->obd_proc_entry = NULL;
1140 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1142 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1143 client_stat->nid_proc, client_stat->nid_stats,
1144 client_stat->nid_brw_stats);
1146 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1147 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1148 atomic_read(&client_stat->nid_exp_ref_count));
1150 if (client_stat->nid_proc)
1151 lprocfs_remove(&client_stat->nid_proc);
1153 if (client_stat->nid_stats)
1154 lprocfs_free_stats(&client_stat->nid_stats);
1156 if (client_stat->nid_brw_stats)
1157 OBD_FREE_PTR(client_stat->nid_brw_stats);
1159 if (client_stat->nid_ldlm_stats)
1160 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1162 OBD_FREE_PTR(client_stat);
1167 void lprocfs_free_per_client_stats(struct obd_device *obd)
1169 cfs_hash_t *hash = obd->obd_nid_stats_hash;
1170 struct nid_stat *stat;
1173 /* we need extra list - because hash_exit called to early */
1174 /* not need locking because all clients is died */
1175 while (!cfs_list_empty(&obd->obd_nid_stats)) {
1176 stat = cfs_list_entry(obd->obd_nid_stats.next,
1177 struct nid_stat, nid_list);
1178 cfs_list_del_init(&stat->nid_list);
1179 cfs_hash_del(hash, &stat->nid, &stat->nid_hash);
1180 lprocfs_free_client_stats(stat);
1185 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1186 enum lprocfs_stats_flags flags)
1188 struct lprocfs_stats *stats;
1189 unsigned int percpusize;
1191 unsigned int num_cpu;
1196 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1199 num_cpu = cfs_num_possible_cpus();
1201 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1205 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1206 stats->ls_flags = flags;
1207 cfs_spin_lock_init(&stats->ls_lock);
1208 /* Use this lock only if there are no percpu areas */
1210 stats->ls_flags = 0;
1213 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1215 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1217 for (i = 0; i < num_cpu; i++) {
1218 OBD_ALLOC(stats->ls_percpu[i], percpusize);
1219 if (stats->ls_percpu[i] == NULL) {
1220 for (j = 0; j < i; j++) {
1221 OBD_FREE(stats->ls_percpu[j], percpusize);
1222 stats->ls_percpu[j] = NULL;
1227 if (stats->ls_percpu[0] == NULL) {
1228 OBD_FREE(stats, offsetof(typeof(*stats),
1229 ls_percpu[num_cpu]));
1233 stats->ls_num = num;
1237 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1239 struct lprocfs_stats *stats = *statsh;
1240 unsigned int num_cpu;
1241 unsigned int percpusize;
1244 if (stats == NULL || stats->ls_num == 0)
1248 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1251 num_cpu = cfs_num_possible_cpus();
1253 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1255 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1256 for (i = 0; i < num_cpu; i++)
1257 OBD_FREE(stats->ls_percpu[i], percpusize);
1258 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1261 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1263 struct lprocfs_counter *percpu_cntr;
1265 unsigned int num_cpu;
1267 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1269 for (i = 0; i < num_cpu; i++) {
1270 for (j = 0; j < stats->ls_num; j++) {
1271 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1272 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1273 percpu_cntr->lc_count = 0;
1274 percpu_cntr->lc_sum = 0;
1275 percpu_cntr->lc_min = LC_MIN_INIT;
1276 percpu_cntr->lc_max = 0;
1277 percpu_cntr->lc_sumsquare = 0;
1278 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1282 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1285 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1286 size_t len, loff_t *off)
1288 struct seq_file *seq = file->private_data;
1289 struct lprocfs_stats *stats = seq->private;
1291 lprocfs_clear_stats(stats);
1296 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1298 struct lprocfs_stats *stats = p->private;
1299 /* return 1st cpu location */
1300 return (*pos >= stats->ls_num) ? NULL :
1301 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1304 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1308 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1310 struct lprocfs_stats *stats = p->private;
1312 return (*pos >= stats->ls_num) ? NULL :
1313 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1316 /* seq file export of one lprocfs counter */
1317 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1319 struct lprocfs_stats *stats = p->private;
1320 struct lprocfs_counter *cntr = v;
1321 struct lprocfs_counter ret;
1324 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1326 cfs_gettimeofday(&now);
1327 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1328 "snapshot_time", now.tv_sec, now.tv_usec);
1332 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1334 lprocfs_stats_collect(stats, idx, &ret);
1336 if (ret.lc_count == 0)
1339 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1340 ret.lc_count, cntr->lc_units);
1345 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1346 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1347 ret.lc_min, ret.lc_max, ret.lc_sum);
1350 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1351 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1355 rc = seq_printf(p, "\n");
1357 return (rc < 0) ? rc : 0;
1360 struct seq_operations lprocfs_stats_seq_sops = {
1361 start: lprocfs_stats_seq_start,
1362 stop: lprocfs_stats_seq_stop,
1363 next: lprocfs_stats_seq_next,
1364 show: lprocfs_stats_seq_show,
1367 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1369 struct proc_dir_entry *dp = PDE(inode);
1370 struct seq_file *seq;
1373 if (LPROCFS_ENTRY_AND_CHECK(dp))
1376 rc = seq_open(file, &lprocfs_stats_seq_sops);
1381 seq = file->private_data;
1382 seq->private = dp->data;
1386 struct file_operations lprocfs_stats_seq_fops = {
1387 .owner = THIS_MODULE,
1388 .open = lprocfs_stats_seq_open,
1390 .write = lprocfs_stats_seq_write,
1391 .llseek = seq_lseek,
1392 .release = lprocfs_seq_release,
1395 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1396 struct lprocfs_stats *stats)
1398 struct proc_dir_entry *entry;
1399 LASSERT(root != NULL);
1401 LPROCFS_WRITE_ENTRY();
1402 entry = create_proc_entry(name, 0644, root);
1404 entry->proc_fops = &lprocfs_stats_seq_fops;
1405 entry->data = stats;
1408 LPROCFS_WRITE_EXIT();
1416 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1417 unsigned conf, const char *name, const char *units)
1419 struct lprocfs_counter *c;
1421 unsigned int num_cpu;
1423 LASSERT(stats != NULL);
1425 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1427 for (i = 0; i < num_cpu; i++) {
1428 c = &(stats->ls_percpu[i]->lp_cntr[index]);
1429 c->lc_config = conf;
1432 c->lc_min = LC_MIN_INIT;
1435 c->lc_units = units;
1438 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1440 EXPORT_SYMBOL(lprocfs_counter_init);
1442 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1444 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1445 LASSERT(coffset < stats->ls_num); \
1446 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1449 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1451 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1452 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1453 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1454 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1455 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1456 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1457 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1458 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1459 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1460 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1461 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1462 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1463 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1467 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1468 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1469 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1470 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1471 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1472 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1473 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1474 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1475 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1476 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1477 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1478 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1479 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1480 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1481 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1482 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1483 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1484 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1485 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1486 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1487 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1488 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1489 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1490 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1491 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1492 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1493 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1494 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1495 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1496 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1497 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1498 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1499 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1500 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1501 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1502 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1503 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1504 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1505 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1506 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1507 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1508 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1509 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1510 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1511 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1512 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1513 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1514 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1515 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1516 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1517 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1518 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1519 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1522 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1524 struct lprocfs_stats *stats;
1525 unsigned int num_stats;
1528 LASSERT(obd->obd_stats == NULL);
1529 LASSERT(obd->obd_proc_entry != NULL);
1530 LASSERT(obd->obd_cntr_base == 0);
1532 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1533 num_private_stats - 1 /* o_owner */;
1534 stats = lprocfs_alloc_stats(num_stats, 0);
1538 lprocfs_init_ops_stats(num_private_stats, stats);
1540 for (i = num_private_stats; i < num_stats; i++) {
1541 /* If this LBUGs, it is likely that an obd
1542 * operation was added to struct obd_ops in
1543 * <obd.h>, and that the corresponding line item
1544 * LPROCFS_OBD_OP_INIT(.., .., opname)
1545 * is missing from the list above. */
1546 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1547 "Missing obd_stat initializer obd_op "
1548 "operation at offset %d.\n", i - num_private_stats);
1550 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1552 lprocfs_free_stats(&stats);
1554 obd->obd_stats = stats;
1555 obd->obd_cntr_base = num_private_stats;
1560 void lprocfs_free_obd_stats(struct obd_device *obd)
1563 lprocfs_free_stats(&obd->obd_stats);
1566 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1568 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1569 LASSERT(coffset < stats->ls_num); \
1570 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1573 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1575 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1576 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1577 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1578 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1579 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1580 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1581 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1582 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1583 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1584 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1585 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1586 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1587 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1588 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1589 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1590 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1591 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1592 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1593 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1594 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1595 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1596 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1597 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1598 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1599 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1600 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1601 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1602 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1603 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1604 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1605 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1606 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1609 int lprocfs_alloc_md_stats(struct obd_device *obd,
1610 unsigned num_private_stats)
1612 struct lprocfs_stats *stats;
1613 unsigned int num_stats;
1616 LASSERT(obd->md_stats == NULL);
1617 LASSERT(obd->obd_proc_entry != NULL);
1618 LASSERT(obd->md_cntr_base == 0);
1620 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1622 stats = lprocfs_alloc_stats(num_stats, 0);
1626 lprocfs_init_mps_stats(num_private_stats, stats);
1628 for (i = num_private_stats; i < num_stats; i++) {
1629 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1630 CERROR("Missing md_stat initializer md_op "
1631 "operation at offset %d. Aborting.\n",
1632 i - num_private_stats);
1636 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1638 lprocfs_free_stats(&stats);
1640 obd->md_stats = stats;
1641 obd->md_cntr_base = num_private_stats;
1646 void lprocfs_free_md_stats(struct obd_device *obd)
1648 struct lprocfs_stats *stats = obd->md_stats;
1650 if (stats != NULL) {
1651 obd->md_stats = NULL;
1652 obd->md_cntr_base = 0;
1653 lprocfs_free_stats(&stats);
1657 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1659 lprocfs_counter_init(ldlm_stats,
1660 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1661 0, "ldlm_enqueue", "reqs");
1662 lprocfs_counter_init(ldlm_stats,
1663 LDLM_CONVERT - LDLM_FIRST_OPC,
1664 0, "ldlm_convert", "reqs");
1665 lprocfs_counter_init(ldlm_stats,
1666 LDLM_CANCEL - LDLM_FIRST_OPC,
1667 0, "ldlm_cancel", "reqs");
1668 lprocfs_counter_init(ldlm_stats,
1669 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1670 0, "ldlm_bl_callback", "reqs");
1671 lprocfs_counter_init(ldlm_stats,
1672 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1673 0, "ldlm_cp_callback", "reqs");
1674 lprocfs_counter_init(ldlm_stats,
1675 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1676 0, "ldlm_gl_callback", "reqs");
1679 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1680 int *eof, void *data)
1682 struct obd_export *exp = data;
1683 LASSERT(exp != NULL);
1685 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1688 struct exp_uuid_cb_data {
1696 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1697 int count, int *eof, int *len)
1699 cb_data->page = page;
1700 cb_data->count = count;
1705 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1706 cfs_hlist_node_t *hnode, void *cb_data)
1709 struct obd_export *exp = cfs_hash_object(hs, hnode);
1710 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1712 if (exp->exp_nid_stats)
1713 *data->len += snprintf((data->page + *data->len),
1714 data->count, "%s\n",
1715 obd_uuid2str(&exp->exp_client_uuid));
1719 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1720 int *eof, void *data)
1722 struct nid_stat *stats = (struct nid_stat *)data;
1723 struct exp_uuid_cb_data cb_data;
1724 struct obd_device *obd = stats->nid_obd;
1729 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1730 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1731 lprocfs_exp_print_uuid, &cb_data);
1732 return (*cb_data.len);
1735 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1736 cfs_hlist_node_t *hnode, void *cb_data)
1739 struct exp_uuid_cb_data *data = cb_data;
1740 struct obd_export *exp = cfs_hash_object(hs, hnode);
1742 if (exp->exp_lock_hash != NULL) {
1744 *data->len += cfs_hash_debug_header(data->page,
1747 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1754 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1755 int *eof, void *data)
1757 struct nid_stat *stats = (struct nid_stat *)data;
1758 struct exp_uuid_cb_data cb_data;
1759 struct obd_device *obd = stats->nid_obd;
1764 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1766 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1767 lprocfs_exp_print_hash, &cb_data);
1768 return (*cb_data.len);
1771 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1772 int count, int *eof, void *data)
1775 return snprintf(page, count, "%s\n",
1776 "Write into this file to clear all nid stats and "
1777 "stale nid entries");
1779 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1781 static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1783 struct nid_stat *stat = obj;
1787 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1788 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1789 /* object has only hash references. */
1790 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1791 cfs_list_move(&stat->nid_list, data);
1792 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1795 /* we has reference to object - only clear data*/
1796 if (stat->nid_stats)
1797 lprocfs_clear_stats(stat->nid_stats);
1799 if (stat->nid_brw_stats) {
1800 for (i = 0; i < BRW_LAST; i++)
1801 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1806 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1807 unsigned long count, void *data)
1809 struct obd_device *obd = (struct obd_device *)data;
1810 struct nid_stat *client_stat;
1811 CFS_LIST_HEAD(free_list);
1813 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1814 lprocfs_nid_stats_clear_write_cb, &free_list);
1816 while (!cfs_list_empty(&free_list)) {
1817 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1819 cfs_list_del_init(&client_stat->nid_list);
1820 lprocfs_free_client_stats(client_stat);
1825 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1827 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1829 struct nid_stat *new_stat, *old_stat;
1830 struct obd_device *obd = NULL;
1831 cfs_proc_dir_entry_t *entry;
1832 char *buffer = NULL;
1838 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1839 !exp->exp_obd->obd_nid_stats_hash)
1842 /* not test against zero because eric say:
1843 * You may only test nid against another nid, or LNET_NID_ANY.
1844 * Anything else is nonsense.*/
1845 if (!nid || *nid == LNET_NID_ANY)
1850 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1852 OBD_ALLOC_PTR(new_stat);
1853 if (new_stat == NULL)
1856 new_stat->nid = *nid;
1857 new_stat->nid_obd = exp->exp_obd;
1858 /* we need set default refcount to 1 to balance obd_disconnect */
1859 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1861 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1862 nid, &new_stat->nid_hash);
1863 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1864 old_stat, libcfs_nid2str(*nid),
1865 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1867 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1868 * been and will never be called. */
1869 if (exp->exp_nid_stats) {
1870 nidstat_putref(exp->exp_nid_stats);
1871 exp->exp_nid_stats = NULL;
1874 /* Return -EALREADY here so that we know that the /proc
1875 * entry already has been created */
1876 if (old_stat != new_stat) {
1877 exp->exp_nid_stats = old_stat;
1878 GOTO(destroy_new, rc = -EALREADY);
1880 /* not found - create */
1881 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1883 GOTO(destroy_new, rc = -ENOMEM);
1885 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1886 new_stat->nid_proc = lprocfs_register(buffer,
1887 obd->obd_proc_exports_entry,
1889 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1891 if (new_stat->nid_proc == NULL) {
1892 CERROR("Error making export directory for nid %s\n",
1893 libcfs_nid2str(*nid));
1894 GOTO(destroy_new_ns, rc = -ENOMEM);
1897 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1898 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1899 if (IS_ERR(entry)) {
1900 CWARN("Error adding the NID stats file\n");
1901 rc = PTR_ERR(entry);
1902 GOTO(destroy_new_ns, rc);
1905 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1906 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1907 if (IS_ERR(entry)) {
1908 CWARN("Error adding the hash file\n");
1909 rc = PTR_ERR(entry);
1910 GOTO(destroy_new_ns, rc);
1913 exp->exp_nid_stats = new_stat;
1915 /* protect competitive add to list, not need locking on destroy */
1916 cfs_spin_lock(&obd->obd_nid_lock);
1917 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1918 cfs_spin_unlock(&obd->obd_nid_lock);
1923 if (new_stat->nid_proc != NULL)
1924 lprocfs_remove(&new_stat->nid_proc);
1925 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1928 nidstat_putref(new_stat);
1929 OBD_FREE_PTR(new_stat);
1933 int lprocfs_exp_cleanup(struct obd_export *exp)
1935 struct nid_stat *stat = exp->exp_nid_stats;
1937 if(!stat || !exp->exp_obd)
1940 nidstat_putref(exp->exp_nid_stats);
1941 exp->exp_nid_stats = NULL;
1946 int lprocfs_write_helper(const char *buffer, unsigned long count,
1949 return lprocfs_write_frac_helper(buffer, count, val, 1);
1952 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1955 char kernbuf[20], *end, *pbuf;
1957 if (count > (sizeof(kernbuf) - 1))
1960 if (cfs_copy_from_user(kernbuf, buffer, count))
1963 kernbuf[count] = '\0';
1970 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1974 if (end != NULL && *end == '.') {
1975 int temp_val, pow = 1;
1979 if (strlen(pbuf) > 5)
1980 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1982 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1985 for (i = 0; i < (end - pbuf); i++)
1988 *val += temp_val / pow;
1994 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
1997 long decimal_val, frac_val;
2003 decimal_val = val / mult;
2004 prtn = snprintf(buffer, count, "%ld", decimal_val);
2005 frac_val = val % mult;
2007 if (prtn < (count - 4) && frac_val > 0) {
2009 int i, temp_mult = 1, frac_bits = 0;
2011 temp_frac = frac_val * 10;
2012 buffer[prtn++] = '.';
2013 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2014 /* only reserved 2 bits fraction */
2015 buffer[prtn++] ='0';
2020 * Need to think these cases :
2021 * 1. #echo x.00 > /proc/xxx output result : x
2022 * 2. #echo x.0x > /proc/xxx output result : x.0x
2023 * 3. #echo x.x0 > /proc/xxx output result : x.x
2024 * 4. #echo x.xx > /proc/xxx output result : x.xx
2025 * Only reserved 2 bits fraction.
2027 for (i = 0; i < (5 - prtn); i++)
2030 frac_bits = min((int)count - prtn, 3 - frac_bits);
2031 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2032 frac_val * temp_mult / mult);
2035 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2037 if (buffer[prtn] == '.') {
2044 buffer[prtn++] ='\n';
2048 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2050 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2053 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2054 __u64 *val, int mult)
2056 char kernbuf[22], *end, *pbuf;
2057 __u64 whole, frac = 0, units;
2058 unsigned frac_d = 1;
2060 if (count > (sizeof(kernbuf) - 1))
2063 if (cfs_copy_from_user(kernbuf, buffer, count))
2066 kernbuf[count] = '\0';
2073 whole = simple_strtoull(pbuf, &end, 10);
2077 if (end != NULL && *end == '.') {
2081 /* need to limit frac_d to a __u32 */
2082 if (strlen(pbuf) > 10)
2085 frac = simple_strtoull(pbuf, &end, 10);
2086 /* count decimal places */
2087 for (i = 0; i < (end - pbuf); i++)
2104 /* Specified units override the multiplier */
2106 mult = mult < 0 ? -units : units;
2109 do_div(frac, frac_d);
2110 *val = whole * mult + frac;
2114 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2115 struct file_operations *seq_fops, void *data)
2117 struct proc_dir_entry *entry;
2120 LPROCFS_WRITE_ENTRY();
2121 entry = create_proc_entry(name, mode, parent);
2123 entry->proc_fops = seq_fops;
2126 LPROCFS_WRITE_EXIT();
2133 EXPORT_SYMBOL(lprocfs_seq_create);
2135 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2137 struct file_operations *seq_fops,
2140 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2141 mode, seq_fops, data));
2143 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2145 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2147 if (value >= OBD_HIST_MAX)
2148 value = OBD_HIST_MAX - 1;
2150 cfs_spin_lock(&oh->oh_lock);
2151 oh->oh_buckets[value]++;
2152 cfs_spin_unlock(&oh->oh_lock);
2154 EXPORT_SYMBOL(lprocfs_oh_tally);
2156 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2160 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2163 lprocfs_oh_tally(oh, val);
2165 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2167 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2169 unsigned long ret = 0;
2172 for (i = 0; i < OBD_HIST_MAX; i++)
2173 ret += oh->oh_buckets[i];
2176 EXPORT_SYMBOL(lprocfs_oh_sum);
2178 void lprocfs_oh_clear(struct obd_histogram *oh)
2180 cfs_spin_lock(&oh->oh_lock);
2181 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2182 cfs_spin_unlock(&oh->oh_lock);
2184 EXPORT_SYMBOL(lprocfs_oh_clear);
2186 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2187 int count, int *eof, void *data)
2189 struct obd_device *obd = data;
2195 c += cfs_hash_debug_header(page, count);
2196 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2197 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2198 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2199 #ifdef HAVE_QUOTA_SUPPORT
2200 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2201 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2202 page + c, count - c);
2207 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2209 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2210 int count, int *eof, void *data)
2212 struct obd_device *obd = data;
2215 LASSERT(obd != NULL);
2216 LASSERT(count >= 0);
2218 /* Set start of user data returned to
2219 page + off since the user may have
2220 requested to read much smaller than
2221 what we need to read */
2222 *start = page + off;
2224 /* We know we are allocated a page here.
2225 Also we know that this function will
2226 not need to write more than a page
2227 so we can truncate at CFS_PAGE_SIZE. */
2228 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2230 /* Initialize the page */
2231 memset(page, 0, size);
2233 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2235 if (obd->obd_max_recoverable_clients == 0) {
2236 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2242 /* sampled unlocked, but really... */
2243 if (obd->obd_recovering == 0) {
2244 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2246 if (lprocfs_obd_snprintf(&page, size, &len,
2247 "recovery_start: %lu\n",
2248 obd->obd_recovery_start) <= 0)
2250 if (lprocfs_obd_snprintf(&page, size, &len,
2251 "recovery_duration: %lu\n",
2252 obd->obd_recovery_end -
2253 obd->obd_recovery_start) <= 0)
2255 /* Number of clients that have completed recovery */
2256 if (lprocfs_obd_snprintf(&page, size, &len,
2257 "completed_clients: %d/%d\n",
2258 obd->obd_max_recoverable_clients -
2259 obd->obd_stale_clients,
2260 obd->obd_max_recoverable_clients) <= 0)
2262 if (lprocfs_obd_snprintf(&page, size, &len,
2263 "replayed_requests: %d\n",
2264 obd->obd_replayed_requests) <= 0)
2266 if (lprocfs_obd_snprintf(&page, size, &len,
2267 "last_transno: "LPD64"\n",
2268 obd->obd_next_recovery_transno - 1)<=0)
2270 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2271 obd->obd_version_recov ? "ON" : "OFF")<=0)
2273 if (lprocfs_obd_snprintf(&page, size, &len, "IR: %s\n",
2274 obd->obd_no_ir ? "OFF" : "ON") <= 0)
2279 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2281 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2282 obd->obd_recovery_start) <= 0)
2284 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2285 cfs_time_current_sec() >=
2286 obd->obd_recovery_start +
2287 obd->obd_recovery_timeout ? 0 :
2288 obd->obd_recovery_start +
2289 obd->obd_recovery_timeout -
2290 cfs_time_current_sec()) <= 0)
2292 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2293 cfs_atomic_read(&obd->obd_connected_clients),
2294 obd->obd_max_recoverable_clients) <= 0)
2296 /* Number of clients that have completed recovery */
2297 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2298 cfs_atomic_read(&obd->obd_req_replay_clients))
2301 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2302 cfs_atomic_read(&obd->obd_lock_replay_clients))
2305 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2306 cfs_atomic_read(&obd->obd_connected_clients) -
2307 cfs_atomic_read(&obd->obd_lock_replay_clients))
2310 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2311 obd->obd_stale_clients) <= 0)
2313 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2314 obd->obd_replayed_requests) <= 0)
2316 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2317 obd->obd_requests_queued_for_recovery) <= 0)
2320 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2321 obd->obd_next_recovery_transno) <= 0)
2327 return min(count, len - (int)off);
2329 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2331 int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off,
2332 int count, int *eof, void *data)
2334 struct obd_device *obd = (struct obd_device *)data;
2335 LASSERT(obd != NULL);
2337 return snprintf(page, count, "%d\n",
2338 obd->obd_recovery_ir_factor);
2340 EXPORT_SYMBOL(lprocfs_obd_rd_ir_factor);
2342 int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer,
2343 unsigned long count, void *data)
2345 struct obd_device *obd = (struct obd_device *)data;
2347 LASSERT(obd != NULL);
2349 rc = lprocfs_write_helper(buffer, count, &val);
2353 if (val < OBD_IR_FACTOR_MIN || val > OBD_IR_FACTOR_MAX)
2356 obd->obd_recovery_ir_factor = val;
2359 EXPORT_SYMBOL(lprocfs_obd_wr_ir_factor);
2361 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2362 int count, int *eof, void *data)
2364 struct obd_device *obd = (struct obd_device *)data;
2365 LASSERT(obd != NULL);
2367 return snprintf(page, count, "%d\n",
2368 obd->obd_recovery_timeout);
2370 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2372 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2373 unsigned long count, void *data)
2375 struct obd_device *obd = (struct obd_device *)data;
2377 LASSERT(obd != NULL);
2379 rc = lprocfs_write_helper(buffer, count, &val);
2383 obd->obd_recovery_timeout = val;
2386 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2388 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2389 int count, int *eof, void *data)
2391 struct obd_device *obd = data;
2392 LASSERT(obd != NULL);
2394 return snprintf(page, count, "%u\n", obd->obd_recovery_time_hard);
2396 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2398 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2399 unsigned long count, void *data)
2401 struct obd_device *obd = data;
2403 LASSERT(obd != NULL);
2405 rc = lprocfs_write_helper(buffer, count, &val);
2409 obd->obd_recovery_time_hard = val;
2412 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2414 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2415 int count, int *eof, void *data)
2417 struct obd_device *obd = (struct obd_device *)data;
2419 LASSERT(obd != NULL);
2420 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2422 return snprintf(page, count, "%s\n",
2423 obd->u.obt.obt_vfsmnt->mnt_devname);
2425 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2427 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2428 int count, int *eof, void *data)
2430 struct obd_device *dev = data;
2431 struct client_obd *cli = &dev->u.cli;
2434 client_obd_list_lock(&cli->cl_loi_list_lock);
2435 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2436 client_obd_list_unlock(&cli->cl_loi_list_lock);
2439 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2441 int lprocfs_obd_wr_max_pages_per_rpc(struct file *file, const char *buffer,
2442 unsigned long count, void *data)
2444 struct obd_device *dev = data;
2445 struct client_obd *cli = &dev->u.cli;
2446 struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
2449 rc = lprocfs_write_helper(buffer, count, &val);
2453 LPROCFS_CLIMP_CHECK(dev);
2454 if (val < 1 || val > ocd->ocd_brw_size >> CFS_PAGE_SHIFT) {
2455 LPROCFS_CLIMP_EXIT(dev);
2458 client_obd_list_lock(&cli->cl_loi_list_lock);
2459 cli->cl_max_pages_per_rpc = val;
2460 client_obd_list_unlock(&cli->cl_loi_list_lock);
2462 LPROCFS_CLIMP_EXIT(dev);
2465 EXPORT_SYMBOL(lprocfs_obd_wr_max_pages_per_rpc);
2467 int lprocfs_target_rd_instance(char *page, char **start, off_t off,
2468 int count, int *eof, void *data)
2470 struct obd_device *obd = (struct obd_device *)data;
2471 struct obd_device_target *target = &obd->u.obt;
2473 LASSERT(obd != NULL);
2474 LASSERT(target->obt_magic == OBT_MAGIC);
2476 return snprintf(page, count, "%u\n", obd->u.obt.obt_instance);
2478 EXPORT_SYMBOL(lprocfs_target_rd_instance);
2480 EXPORT_SYMBOL(lprocfs_register);
2481 EXPORT_SYMBOL(lprocfs_srch);
2482 EXPORT_SYMBOL(lprocfs_remove);
2483 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2484 EXPORT_SYMBOL(lprocfs_add_vars);
2485 EXPORT_SYMBOL(lprocfs_obd_setup);
2486 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2487 EXPORT_SYMBOL(lprocfs_add_simple);
2488 EXPORT_SYMBOL(lprocfs_add_symlink);
2489 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2490 EXPORT_SYMBOL(lprocfs_alloc_stats);
2491 EXPORT_SYMBOL(lprocfs_free_stats);
2492 EXPORT_SYMBOL(lprocfs_clear_stats);
2493 EXPORT_SYMBOL(lprocfs_register_stats);
2494 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2495 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2496 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2497 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2498 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2499 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2500 EXPORT_SYMBOL(lprocfs_free_md_stats);
2501 EXPORT_SYMBOL(lprocfs_exp_setup);
2502 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2504 EXPORT_SYMBOL(lprocfs_rd_u64);
2505 EXPORT_SYMBOL(lprocfs_rd_atomic);
2506 EXPORT_SYMBOL(lprocfs_wr_atomic);
2507 EXPORT_SYMBOL(lprocfs_rd_uint);
2508 EXPORT_SYMBOL(lprocfs_wr_uint);
2509 EXPORT_SYMBOL(lprocfs_rd_uuid);
2510 EXPORT_SYMBOL(lprocfs_rd_name);
2511 EXPORT_SYMBOL(lprocfs_rd_fstype);
2512 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2513 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2514 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2515 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2516 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2517 EXPORT_SYMBOL(lprocfs_rd_import);
2518 EXPORT_SYMBOL(lprocfs_rd_state);
2519 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2520 EXPORT_SYMBOL(lprocfs_rd_blksize);
2521 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2522 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2523 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2524 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2525 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2527 EXPORT_SYMBOL(lprocfs_write_helper);
2528 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2529 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2530 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2531 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2532 EXPORT_SYMBOL(lprocfs_stats_collect);