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",
820 int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
825 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
827 ret += snprintf(page + ret, count - ret, "%s%s",
828 ret ? sep : "", obd_connect_names[i]);
830 if (flags & ~(mask - 1))
831 ret += snprintf(page + ret, count - ret,
832 "%sunknown flags "LPX64,
833 ret ? sep : "", flags & ~(mask - 1));
836 EXPORT_SYMBOL(obd_connect_flags2str);
838 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
839 int *eof, void *data)
841 struct lprocfs_counter ret;
842 struct obd_device *obd = (struct obd_device *)data;
843 struct obd_import *imp;
844 struct obd_import_conn *conn;
847 LASSERT(obd != NULL);
848 LPROCFS_CLIMP_CHECK(obd);
849 imp = obd->u.cli.cl_import;
852 i = snprintf(page, count,
861 ptlrpc_import_state_name(imp->imp_state),
862 imp->imp_connect_data.ocd_instance);
863 i += obd_connect_flags2str(page + i, count - i,
864 imp->imp_connect_data.ocd_connect_flags,
866 i += snprintf(page + i, count - i,
869 i += obd_import_flags2str(imp, page + i, count - i);
871 i += snprintf(page + i, count - i,
874 " failover_nids: [");
875 cfs_spin_lock(&imp->imp_lock);
877 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
878 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
879 libcfs_nid2str(conn->oic_conn->c_peer.nid));
882 cfs_spin_unlock(&imp->imp_lock);
883 i += snprintf(page + i, count - i,
885 " current_connection: %s\n"
886 " connection_attempts: %u\n"
888 " in-progress_invalidations: %u\n",
889 libcfs_nid2str(imp->imp_connection->c_peer.nid),
892 cfs_atomic_read(&imp->imp_inval_count));
894 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
895 if (ret.lc_count != 0) {
896 /* first argument to do_div MUST be __u64 */
897 __u64 sum = ret.lc_sum;
898 do_div(sum, ret.lc_count);
902 i += snprintf(page + i, count - i,
905 " unregistering: %u\n"
907 " avg_waittime: "LPU64" %s\n",
908 cfs_atomic_read(&imp->imp_inflight),
909 cfs_atomic_read(&imp->imp_unregistering),
910 cfs_atomic_read(&imp->imp_timeouts),
911 ret.lc_sum, ret.lc_units);
914 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
915 if (imp->imp_at.iat_portal[j] == 0)
917 k = max_t(unsigned int, k,
918 at_get(&imp->imp_at.iat_service_estimate[j]));
920 i += snprintf(page + i, count - i,
921 " service_estimates:\n"
922 " services: %u sec\n"
923 " network: %u sec\n",
925 at_get(&imp->imp_at.iat_net_latency));
927 i += snprintf(page + i, count - i,
929 " last_replay: "LPU64"\n"
930 " peer_committed: "LPU64"\n"
931 " last_checked: "LPU64"\n",
932 imp->imp_last_replay_transno,
933 imp->imp_peer_committed_transno,
934 imp->imp_last_transno_checked);
937 for (rw = 0; rw <= 1; rw++) {
938 lprocfs_stats_collect(obd->obd_svc_stats,
939 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
941 if (ret.lc_sum > 0 && ret.lc_count > 0) {
942 /* first argument to do_div MUST be __u64 */
943 __u64 sum = ret.lc_sum;
944 do_div(sum, ret.lc_count);
946 i += snprintf(page + i, count - i,
947 " %s_data_averages:\n"
948 " bytes_per_rpc: "LPU64"\n",
949 rw ? "write" : "read",
953 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
954 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
955 if (ret.lc_sum > 0 && ret.lc_count != 0) {
956 /* first argument to do_div MUST be __u64 */
957 __u64 sum = ret.lc_sum;
958 do_div(sum, ret.lc_count);
960 i += snprintf(page + i, count - i,
961 " %s_per_rpc: "LPU64"\n",
962 ret.lc_units, ret.lc_sum);
965 i += snprintf(page + i, count - i,
966 " MB_per_sec: %u.%.02u\n",
967 k / j, (100 * k / j) % 100);
971 LPROCFS_CLIMP_EXIT(obd);
975 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
976 int *eof, void *data)
978 struct obd_device *obd = (struct obd_device *)data;
979 struct obd_import *imp;
982 LASSERT(obd != NULL);
983 LPROCFS_CLIMP_CHECK(obd);
984 imp = obd->u.cli.cl_import;
987 i = snprintf(page, count, "current_state: %s\n",
988 ptlrpc_import_state_name(imp->imp_state));
989 i += snprintf(page + i, count - i,
991 k = imp->imp_state_hist_idx;
992 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
993 struct import_state_hist *ish =
994 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
995 if (ish->ish_state == 0)
997 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
999 ptlrpc_import_state_name(ish->ish_state));
1002 LPROCFS_CLIMP_EXIT(obd);
1006 int lprocfs_at_hist_helper(char *page, int count, int rc,
1007 struct adaptive_timeout *at)
1010 for (i = 0; i < AT_BINS; i++)
1011 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1012 rc += snprintf(page + rc, count - rc, "\n");
1016 /* See also ptlrpc_lprocfs_rd_timeouts */
1017 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1018 int *eof, void *data)
1020 struct obd_device *obd = (struct obd_device *)data;
1021 struct obd_import *imp;
1022 unsigned int cur, worst;
1027 LASSERT(obd != NULL);
1028 LPROCFS_CLIMP_CHECK(obd);
1029 imp = obd->u.cli.cl_import;
1032 now = cfs_time_current_sec();
1034 /* Some network health info for kicks */
1035 s2dhms(&ts, now - imp->imp_last_reply_time);
1036 rc += snprintf(page + rc, count - rc,
1037 "%-10s : %ld, "DHMS_FMT" ago\n",
1038 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1040 cur = at_get(&imp->imp_at.iat_net_latency);
1041 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1042 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1043 s2dhms(&ts, now - worstt);
1044 rc += snprintf(page + rc, count - rc,
1045 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1046 "network", cur, worst, worstt, DHMS_VARS(&ts));
1047 rc = lprocfs_at_hist_helper(page, count, rc,
1048 &imp->imp_at.iat_net_latency);
1050 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1051 if (imp->imp_at.iat_portal[i] == 0)
1053 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1054 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1055 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1056 s2dhms(&ts, now - worstt);
1057 rc += snprintf(page + rc, count - rc,
1058 "portal %-2d : cur %3u worst %3u (at %ld, "
1059 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1060 cur, worst, worstt, DHMS_VARS(&ts));
1061 rc = lprocfs_at_hist_helper(page, count, rc,
1062 &imp->imp_at.iat_service_estimate[i]);
1065 LPROCFS_CLIMP_EXIT(obd);
1069 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1070 int count, int *eof, void *data)
1072 struct obd_device *obd = data;
1076 LPROCFS_CLIMP_CHECK(obd);
1077 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1078 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1079 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1080 ret += snprintf(page + ret, count - ret, "\n");
1081 LPROCFS_CLIMP_EXIT(obd);
1084 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1086 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1087 int *eof, void *data)
1089 struct obd_device *obd = data;
1091 LASSERT(obd != NULL);
1093 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1096 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1097 int *eof, void *data)
1099 struct obd_type *class = (struct obd_type*) data;
1101 LASSERT(class != NULL);
1103 return snprintf(page, count, "%d\n", class->typ_refcnt);
1106 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1110 LASSERT(obd != NULL);
1111 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1112 LASSERT(obd->obd_type->typ_procroot != NULL);
1114 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1115 obd->obd_type->typ_procroot,
1117 if (IS_ERR(obd->obd_proc_entry)) {
1118 rc = PTR_ERR(obd->obd_proc_entry);
1119 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1120 obd->obd_proc_entry = NULL;
1125 int lprocfs_obd_cleanup(struct obd_device *obd)
1129 if (obd->obd_proc_exports_entry) {
1130 /* Should be no exports left */
1131 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1132 lprocfs_remove(&obd->obd_proc_exports_entry);
1133 obd->obd_proc_exports_entry = NULL;
1135 if (obd->obd_proc_entry) {
1136 lprocfs_remove(&obd->obd_proc_entry);
1137 obd->obd_proc_entry = NULL;
1142 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1144 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1145 client_stat->nid_proc, client_stat->nid_stats,
1146 client_stat->nid_brw_stats);
1148 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1149 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1150 atomic_read(&client_stat->nid_exp_ref_count));
1152 if (client_stat->nid_proc)
1153 lprocfs_remove(&client_stat->nid_proc);
1155 if (client_stat->nid_stats)
1156 lprocfs_free_stats(&client_stat->nid_stats);
1158 if (client_stat->nid_brw_stats)
1159 OBD_FREE_PTR(client_stat->nid_brw_stats);
1161 if (client_stat->nid_ldlm_stats)
1162 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1164 OBD_FREE_PTR(client_stat);
1169 void lprocfs_free_per_client_stats(struct obd_device *obd)
1171 cfs_hash_t *hash = obd->obd_nid_stats_hash;
1172 struct nid_stat *stat;
1175 /* we need extra list - because hash_exit called to early */
1176 /* not need locking because all clients is died */
1177 while (!cfs_list_empty(&obd->obd_nid_stats)) {
1178 stat = cfs_list_entry(obd->obd_nid_stats.next,
1179 struct nid_stat, nid_list);
1180 cfs_list_del_init(&stat->nid_list);
1181 cfs_hash_del(hash, &stat->nid, &stat->nid_hash);
1182 lprocfs_free_client_stats(stat);
1187 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1188 enum lprocfs_stats_flags flags)
1190 struct lprocfs_stats *stats;
1191 unsigned int percpusize;
1193 unsigned int num_cpu;
1198 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1201 num_cpu = cfs_num_possible_cpus();
1203 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1207 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1208 stats->ls_flags = flags;
1209 cfs_spin_lock_init(&stats->ls_lock);
1210 /* Use this lock only if there are no percpu areas */
1212 stats->ls_flags = 0;
1215 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1217 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1219 for (i = 0; i < num_cpu; i++) {
1220 OBD_ALLOC(stats->ls_percpu[i], percpusize);
1221 if (stats->ls_percpu[i] == NULL) {
1222 for (j = 0; j < i; j++) {
1223 OBD_FREE(stats->ls_percpu[j], percpusize);
1224 stats->ls_percpu[j] = NULL;
1229 if (stats->ls_percpu[0] == NULL) {
1230 OBD_FREE(stats, offsetof(typeof(*stats),
1231 ls_percpu[num_cpu]));
1235 stats->ls_num = num;
1239 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1241 struct lprocfs_stats *stats = *statsh;
1242 unsigned int num_cpu;
1243 unsigned int percpusize;
1246 if (stats == NULL || stats->ls_num == 0)
1250 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1253 num_cpu = cfs_num_possible_cpus();
1255 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1257 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1258 for (i = 0; i < num_cpu; i++)
1259 OBD_FREE(stats->ls_percpu[i], percpusize);
1260 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1263 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1265 struct lprocfs_counter *percpu_cntr;
1267 unsigned int num_cpu;
1269 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1271 for (i = 0; i < num_cpu; i++) {
1272 for (j = 0; j < stats->ls_num; j++) {
1273 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1274 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1275 percpu_cntr->lc_count = 0;
1276 percpu_cntr->lc_sum = 0;
1277 percpu_cntr->lc_min = LC_MIN_INIT;
1278 percpu_cntr->lc_max = 0;
1279 percpu_cntr->lc_sumsquare = 0;
1280 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1284 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1287 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1288 size_t len, loff_t *off)
1290 struct seq_file *seq = file->private_data;
1291 struct lprocfs_stats *stats = seq->private;
1293 lprocfs_clear_stats(stats);
1298 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1300 struct lprocfs_stats *stats = p->private;
1301 /* return 1st cpu location */
1302 return (*pos >= stats->ls_num) ? NULL :
1303 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1306 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1310 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1312 struct lprocfs_stats *stats = p->private;
1314 return (*pos >= stats->ls_num) ? NULL :
1315 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1318 /* seq file export of one lprocfs counter */
1319 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1321 struct lprocfs_stats *stats = p->private;
1322 struct lprocfs_counter *cntr = v;
1323 struct lprocfs_counter ret;
1326 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1328 cfs_gettimeofday(&now);
1329 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1330 "snapshot_time", now.tv_sec, now.tv_usec);
1334 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1336 lprocfs_stats_collect(stats, idx, &ret);
1338 if (ret.lc_count == 0)
1341 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1342 ret.lc_count, cntr->lc_units);
1347 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1348 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1349 ret.lc_min, ret.lc_max, ret.lc_sum);
1352 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1353 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1357 rc = seq_printf(p, "\n");
1359 return (rc < 0) ? rc : 0;
1362 struct seq_operations lprocfs_stats_seq_sops = {
1363 start: lprocfs_stats_seq_start,
1364 stop: lprocfs_stats_seq_stop,
1365 next: lprocfs_stats_seq_next,
1366 show: lprocfs_stats_seq_show,
1369 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1371 struct proc_dir_entry *dp = PDE(inode);
1372 struct seq_file *seq;
1375 if (LPROCFS_ENTRY_AND_CHECK(dp))
1378 rc = seq_open(file, &lprocfs_stats_seq_sops);
1383 seq = file->private_data;
1384 seq->private = dp->data;
1388 struct file_operations lprocfs_stats_seq_fops = {
1389 .owner = THIS_MODULE,
1390 .open = lprocfs_stats_seq_open,
1392 .write = lprocfs_stats_seq_write,
1393 .llseek = seq_lseek,
1394 .release = lprocfs_seq_release,
1397 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1398 struct lprocfs_stats *stats)
1400 struct proc_dir_entry *entry;
1401 LASSERT(root != NULL);
1403 LPROCFS_WRITE_ENTRY();
1404 entry = create_proc_entry(name, 0644, root);
1406 entry->proc_fops = &lprocfs_stats_seq_fops;
1407 entry->data = stats;
1410 LPROCFS_WRITE_EXIT();
1418 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1419 unsigned conf, const char *name, const char *units)
1421 struct lprocfs_counter *c;
1423 unsigned int num_cpu;
1425 LASSERT(stats != NULL);
1427 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1429 for (i = 0; i < num_cpu; i++) {
1430 c = &(stats->ls_percpu[i]->lp_cntr[index]);
1431 c->lc_config = conf;
1434 c->lc_min = LC_MIN_INIT;
1437 c->lc_units = units;
1440 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1442 EXPORT_SYMBOL(lprocfs_counter_init);
1444 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1446 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1447 LASSERT(coffset < stats->ls_num); \
1448 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1451 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1453 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1454 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1455 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1456 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1457 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1458 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1459 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1460 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1461 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1462 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1463 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1467 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1468 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1469 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1470 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1471 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1472 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1473 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1474 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1475 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1476 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1477 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1478 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1479 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1480 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1481 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1482 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1483 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1484 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1485 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1486 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1487 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1488 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1489 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1490 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1491 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1492 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1493 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1494 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1495 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1496 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1497 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1498 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1499 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1500 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1501 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1502 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1503 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1504 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1505 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1506 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1507 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1508 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1509 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1510 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1511 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1512 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1513 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1514 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1515 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1516 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1517 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1518 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1519 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1520 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1521 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1524 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1526 struct lprocfs_stats *stats;
1527 unsigned int num_stats;
1530 LASSERT(obd->obd_stats == NULL);
1531 LASSERT(obd->obd_proc_entry != NULL);
1532 LASSERT(obd->obd_cntr_base == 0);
1534 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1535 num_private_stats - 1 /* o_owner */;
1536 stats = lprocfs_alloc_stats(num_stats, 0);
1540 lprocfs_init_ops_stats(num_private_stats, stats);
1542 for (i = num_private_stats; i < num_stats; i++) {
1543 /* If this LBUGs, it is likely that an obd
1544 * operation was added to struct obd_ops in
1545 * <obd.h>, and that the corresponding line item
1546 * LPROCFS_OBD_OP_INIT(.., .., opname)
1547 * is missing from the list above. */
1548 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1549 "Missing obd_stat initializer obd_op "
1550 "operation at offset %d.\n", i - num_private_stats);
1552 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1554 lprocfs_free_stats(&stats);
1556 obd->obd_stats = stats;
1557 obd->obd_cntr_base = num_private_stats;
1562 void lprocfs_free_obd_stats(struct obd_device *obd)
1565 lprocfs_free_stats(&obd->obd_stats);
1568 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1570 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1571 LASSERT(coffset < stats->ls_num); \
1572 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1575 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1577 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1578 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1579 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1580 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1581 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1582 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1583 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1584 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1585 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1586 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1587 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1588 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1589 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1590 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1591 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1592 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1593 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1594 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1595 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1596 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1597 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1598 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1599 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1600 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1601 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1602 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1603 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1604 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1605 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1606 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1607 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1608 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1611 int lprocfs_alloc_md_stats(struct obd_device *obd,
1612 unsigned num_private_stats)
1614 struct lprocfs_stats *stats;
1615 unsigned int num_stats;
1618 LASSERT(obd->md_stats == NULL);
1619 LASSERT(obd->obd_proc_entry != NULL);
1620 LASSERT(obd->md_cntr_base == 0);
1622 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1624 stats = lprocfs_alloc_stats(num_stats, 0);
1628 lprocfs_init_mps_stats(num_private_stats, stats);
1630 for (i = num_private_stats; i < num_stats; i++) {
1631 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1632 CERROR("Missing md_stat initializer md_op "
1633 "operation at offset %d. Aborting.\n",
1634 i - num_private_stats);
1638 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1640 lprocfs_free_stats(&stats);
1642 obd->md_stats = stats;
1643 obd->md_cntr_base = num_private_stats;
1648 void lprocfs_free_md_stats(struct obd_device *obd)
1650 struct lprocfs_stats *stats = obd->md_stats;
1652 if (stats != NULL) {
1653 obd->md_stats = NULL;
1654 obd->md_cntr_base = 0;
1655 lprocfs_free_stats(&stats);
1659 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1661 lprocfs_counter_init(ldlm_stats,
1662 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1663 0, "ldlm_enqueue", "reqs");
1664 lprocfs_counter_init(ldlm_stats,
1665 LDLM_CONVERT - LDLM_FIRST_OPC,
1666 0, "ldlm_convert", "reqs");
1667 lprocfs_counter_init(ldlm_stats,
1668 LDLM_CANCEL - LDLM_FIRST_OPC,
1669 0, "ldlm_cancel", "reqs");
1670 lprocfs_counter_init(ldlm_stats,
1671 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1672 0, "ldlm_bl_callback", "reqs");
1673 lprocfs_counter_init(ldlm_stats,
1674 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1675 0, "ldlm_cp_callback", "reqs");
1676 lprocfs_counter_init(ldlm_stats,
1677 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1678 0, "ldlm_gl_callback", "reqs");
1681 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1682 int *eof, void *data)
1684 struct obd_export *exp = data;
1685 LASSERT(exp != NULL);
1687 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1690 struct exp_uuid_cb_data {
1698 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1699 int count, int *eof, int *len)
1701 cb_data->page = page;
1702 cb_data->count = count;
1707 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1708 cfs_hlist_node_t *hnode, void *cb_data)
1711 struct obd_export *exp = cfs_hash_object(hs, hnode);
1712 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1714 if (exp->exp_nid_stats)
1715 *data->len += snprintf((data->page + *data->len),
1716 data->count, "%s\n",
1717 obd_uuid2str(&exp->exp_client_uuid));
1721 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1722 int *eof, void *data)
1724 struct nid_stat *stats = (struct nid_stat *)data;
1725 struct exp_uuid_cb_data cb_data;
1726 struct obd_device *obd = stats->nid_obd;
1731 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1732 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1733 lprocfs_exp_print_uuid, &cb_data);
1734 return (*cb_data.len);
1737 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1738 cfs_hlist_node_t *hnode, void *cb_data)
1741 struct exp_uuid_cb_data *data = cb_data;
1742 struct obd_export *exp = cfs_hash_object(hs, hnode);
1744 if (exp->exp_lock_hash != NULL) {
1746 *data->len += cfs_hash_debug_header(data->page,
1749 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1756 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1757 int *eof, void *data)
1759 struct nid_stat *stats = (struct nid_stat *)data;
1760 struct exp_uuid_cb_data cb_data;
1761 struct obd_device *obd = stats->nid_obd;
1766 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1768 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1769 lprocfs_exp_print_hash, &cb_data);
1770 return (*cb_data.len);
1773 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1774 int count, int *eof, void *data)
1777 return snprintf(page, count, "%s\n",
1778 "Write into this file to clear all nid stats and "
1779 "stale nid entries");
1781 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1783 static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1785 struct nid_stat *stat = obj;
1789 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1790 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1791 /* object has only hash references. */
1792 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1793 cfs_list_move(&stat->nid_list, data);
1794 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1797 /* we has reference to object - only clear data*/
1798 if (stat->nid_stats)
1799 lprocfs_clear_stats(stat->nid_stats);
1801 if (stat->nid_brw_stats) {
1802 for (i = 0; i < BRW_LAST; i++)
1803 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1808 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1809 unsigned long count, void *data)
1811 struct obd_device *obd = (struct obd_device *)data;
1812 struct nid_stat *client_stat;
1813 CFS_LIST_HEAD(free_list);
1815 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1816 lprocfs_nid_stats_clear_write_cb, &free_list);
1818 while (!cfs_list_empty(&free_list)) {
1819 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1821 cfs_list_del_init(&client_stat->nid_list);
1822 lprocfs_free_client_stats(client_stat);
1827 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1829 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1831 struct nid_stat *new_stat, *old_stat;
1832 struct obd_device *obd = NULL;
1833 cfs_proc_dir_entry_t *entry;
1834 char *buffer = NULL;
1840 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1841 !exp->exp_obd->obd_nid_stats_hash)
1844 /* not test against zero because eric say:
1845 * You may only test nid against another nid, or LNET_NID_ANY.
1846 * Anything else is nonsense.*/
1847 if (!nid || *nid == LNET_NID_ANY)
1852 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1854 OBD_ALLOC_PTR(new_stat);
1855 if (new_stat == NULL)
1858 new_stat->nid = *nid;
1859 new_stat->nid_obd = exp->exp_obd;
1860 /* we need set default refcount to 1 to balance obd_disconnect */
1861 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1863 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1864 nid, &new_stat->nid_hash);
1865 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1866 old_stat, libcfs_nid2str(*nid),
1867 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1869 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1870 * been and will never be called. */
1871 if (exp->exp_nid_stats) {
1872 nidstat_putref(exp->exp_nid_stats);
1873 exp->exp_nid_stats = NULL;
1876 /* Return -EALREADY here so that we know that the /proc
1877 * entry already has been created */
1878 if (old_stat != new_stat) {
1879 exp->exp_nid_stats = old_stat;
1880 GOTO(destroy_new, rc = -EALREADY);
1882 /* not found - create */
1883 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1885 GOTO(destroy_new, rc = -ENOMEM);
1887 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1888 new_stat->nid_proc = lprocfs_register(buffer,
1889 obd->obd_proc_exports_entry,
1891 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1893 if (new_stat->nid_proc == NULL) {
1894 CERROR("Error making export directory for nid %s\n",
1895 libcfs_nid2str(*nid));
1896 GOTO(destroy_new_ns, rc = -ENOMEM);
1899 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1900 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1901 if (IS_ERR(entry)) {
1902 CWARN("Error adding the NID stats file\n");
1903 rc = PTR_ERR(entry);
1904 GOTO(destroy_new_ns, rc);
1907 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1908 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1909 if (IS_ERR(entry)) {
1910 CWARN("Error adding the hash file\n");
1911 rc = PTR_ERR(entry);
1912 GOTO(destroy_new_ns, rc);
1915 exp->exp_nid_stats = new_stat;
1917 /* protect competitive add to list, not need locking on destroy */
1918 cfs_spin_lock(&obd->obd_nid_lock);
1919 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1920 cfs_spin_unlock(&obd->obd_nid_lock);
1925 if (new_stat->nid_proc != NULL)
1926 lprocfs_remove(&new_stat->nid_proc);
1927 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1930 nidstat_putref(new_stat);
1931 OBD_FREE_PTR(new_stat);
1935 int lprocfs_exp_cleanup(struct obd_export *exp)
1937 struct nid_stat *stat = exp->exp_nid_stats;
1939 if(!stat || !exp->exp_obd)
1942 nidstat_putref(exp->exp_nid_stats);
1943 exp->exp_nid_stats = NULL;
1948 int lprocfs_write_helper(const char *buffer, unsigned long count,
1951 return lprocfs_write_frac_helper(buffer, count, val, 1);
1954 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1957 char kernbuf[20], *end, *pbuf;
1959 if (count > (sizeof(kernbuf) - 1))
1962 if (cfs_copy_from_user(kernbuf, buffer, count))
1965 kernbuf[count] = '\0';
1972 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1976 if (end != NULL && *end == '.') {
1977 int temp_val, pow = 1;
1981 if (strlen(pbuf) > 5)
1982 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1984 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1987 for (i = 0; i < (end - pbuf); i++)
1990 *val += temp_val / pow;
1996 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
1999 long decimal_val, frac_val;
2005 decimal_val = val / mult;
2006 prtn = snprintf(buffer, count, "%ld", decimal_val);
2007 frac_val = val % mult;
2009 if (prtn < (count - 4) && frac_val > 0) {
2011 int i, temp_mult = 1, frac_bits = 0;
2013 temp_frac = frac_val * 10;
2014 buffer[prtn++] = '.';
2015 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2016 /* only reserved 2 bits fraction */
2017 buffer[prtn++] ='0';
2022 * Need to think these cases :
2023 * 1. #echo x.00 > /proc/xxx output result : x
2024 * 2. #echo x.0x > /proc/xxx output result : x.0x
2025 * 3. #echo x.x0 > /proc/xxx output result : x.x
2026 * 4. #echo x.xx > /proc/xxx output result : x.xx
2027 * Only reserved 2 bits fraction.
2029 for (i = 0; i < (5 - prtn); i++)
2032 frac_bits = min((int)count - prtn, 3 - frac_bits);
2033 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2034 frac_val * temp_mult / mult);
2037 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2039 if (buffer[prtn] == '.') {
2046 buffer[prtn++] ='\n';
2050 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2052 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2055 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2056 __u64 *val, int mult)
2058 char kernbuf[22], *end, *pbuf;
2059 __u64 whole, frac = 0, units;
2060 unsigned frac_d = 1;
2062 if (count > (sizeof(kernbuf) - 1))
2065 if (cfs_copy_from_user(kernbuf, buffer, count))
2068 kernbuf[count] = '\0';
2075 whole = simple_strtoull(pbuf, &end, 10);
2079 if (end != NULL && *end == '.') {
2083 /* need to limit frac_d to a __u32 */
2084 if (strlen(pbuf) > 10)
2087 frac = simple_strtoull(pbuf, &end, 10);
2088 /* count decimal places */
2089 for (i = 0; i < (end - pbuf); i++)
2106 /* Specified units override the multiplier */
2108 mult = mult < 0 ? -units : units;
2111 do_div(frac, frac_d);
2112 *val = whole * mult + frac;
2116 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2117 struct file_operations *seq_fops, void *data)
2119 struct proc_dir_entry *entry;
2122 LPROCFS_WRITE_ENTRY();
2123 entry = create_proc_entry(name, mode, parent);
2125 entry->proc_fops = seq_fops;
2128 LPROCFS_WRITE_EXIT();
2135 EXPORT_SYMBOL(lprocfs_seq_create);
2137 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2139 struct file_operations *seq_fops,
2142 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2143 mode, seq_fops, data));
2145 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2147 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2149 if (value >= OBD_HIST_MAX)
2150 value = OBD_HIST_MAX - 1;
2152 cfs_spin_lock(&oh->oh_lock);
2153 oh->oh_buckets[value]++;
2154 cfs_spin_unlock(&oh->oh_lock);
2156 EXPORT_SYMBOL(lprocfs_oh_tally);
2158 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2162 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2165 lprocfs_oh_tally(oh, val);
2167 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2169 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2171 unsigned long ret = 0;
2174 for (i = 0; i < OBD_HIST_MAX; i++)
2175 ret += oh->oh_buckets[i];
2178 EXPORT_SYMBOL(lprocfs_oh_sum);
2180 void lprocfs_oh_clear(struct obd_histogram *oh)
2182 cfs_spin_lock(&oh->oh_lock);
2183 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2184 cfs_spin_unlock(&oh->oh_lock);
2186 EXPORT_SYMBOL(lprocfs_oh_clear);
2188 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2189 int count, int *eof, void *data)
2191 struct obd_device *obd = data;
2197 c += cfs_hash_debug_header(page, count);
2198 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2199 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2200 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2201 #ifdef HAVE_QUOTA_SUPPORT
2202 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2203 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2204 page + c, count - c);
2209 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2211 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2212 int count, int *eof, void *data)
2214 struct obd_device *obd = data;
2217 LASSERT(obd != NULL);
2218 LASSERT(count >= 0);
2220 /* Set start of user data returned to
2221 page + off since the user may have
2222 requested to read much smaller than
2223 what we need to read */
2224 *start = page + off;
2226 /* We know we are allocated a page here.
2227 Also we know that this function will
2228 not need to write more than a page
2229 so we can truncate at CFS_PAGE_SIZE. */
2230 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2232 /* Initialize the page */
2233 memset(page, 0, size);
2235 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2237 if (obd->obd_max_recoverable_clients == 0) {
2238 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2244 /* sampled unlocked, but really... */
2245 if (obd->obd_recovering == 0) {
2246 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2248 if (lprocfs_obd_snprintf(&page, size, &len,
2249 "recovery_start: %lu\n",
2250 obd->obd_recovery_start) <= 0)
2252 if (lprocfs_obd_snprintf(&page, size, &len,
2253 "recovery_duration: %lu\n",
2254 obd->obd_recovery_end -
2255 obd->obd_recovery_start) <= 0)
2257 /* Number of clients that have completed recovery */
2258 if (lprocfs_obd_snprintf(&page, size, &len,
2259 "completed_clients: %d/%d\n",
2260 obd->obd_max_recoverable_clients -
2261 obd->obd_stale_clients,
2262 obd->obd_max_recoverable_clients) <= 0)
2264 if (lprocfs_obd_snprintf(&page, size, &len,
2265 "replayed_requests: %d\n",
2266 obd->obd_replayed_requests) <= 0)
2268 if (lprocfs_obd_snprintf(&page, size, &len,
2269 "last_transno: "LPD64"\n",
2270 obd->obd_next_recovery_transno - 1)<=0)
2272 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2273 obd->obd_version_recov ? "ON" : "OFF")<=0)
2275 if (lprocfs_obd_snprintf(&page, size, &len, "IR: %s\n",
2276 obd->obd_no_ir ? "OFF" : "ON") <= 0)
2281 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2283 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2284 obd->obd_recovery_start) <= 0)
2286 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2287 cfs_time_current_sec() >=
2288 obd->obd_recovery_start +
2289 obd->obd_recovery_timeout ? 0 :
2290 obd->obd_recovery_start +
2291 obd->obd_recovery_timeout -
2292 cfs_time_current_sec()) <= 0)
2294 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2295 cfs_atomic_read(&obd->obd_connected_clients),
2296 obd->obd_max_recoverable_clients) <= 0)
2298 /* Number of clients that have completed recovery */
2299 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2300 cfs_atomic_read(&obd->obd_req_replay_clients))
2303 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2304 cfs_atomic_read(&obd->obd_lock_replay_clients))
2307 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2308 cfs_atomic_read(&obd->obd_connected_clients) -
2309 cfs_atomic_read(&obd->obd_lock_replay_clients))
2312 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2313 obd->obd_stale_clients) <= 0)
2315 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2316 obd->obd_replayed_requests) <= 0)
2318 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2319 obd->obd_requests_queued_for_recovery) <= 0)
2322 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2323 obd->obd_next_recovery_transno) <= 0)
2329 return min(count, len - (int)off);
2331 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2333 int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off,
2334 int count, int *eof, void *data)
2336 struct obd_device *obd = (struct obd_device *)data;
2337 LASSERT(obd != NULL);
2339 return snprintf(page, count, "%d\n",
2340 obd->obd_recovery_ir_factor);
2342 EXPORT_SYMBOL(lprocfs_obd_rd_ir_factor);
2344 int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer,
2345 unsigned long count, void *data)
2347 struct obd_device *obd = (struct obd_device *)data;
2349 LASSERT(obd != NULL);
2351 rc = lprocfs_write_helper(buffer, count, &val);
2355 if (val < OBD_IR_FACTOR_MIN || val > OBD_IR_FACTOR_MAX)
2358 obd->obd_recovery_ir_factor = val;
2361 EXPORT_SYMBOL(lprocfs_obd_wr_ir_factor);
2363 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2364 int count, int *eof, void *data)
2366 struct obd_device *obd = (struct obd_device *)data;
2367 LASSERT(obd != NULL);
2369 return snprintf(page, count, "%d\n",
2370 obd->obd_recovery_timeout);
2372 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2374 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2375 unsigned long count, void *data)
2377 struct obd_device *obd = (struct obd_device *)data;
2379 LASSERT(obd != NULL);
2381 rc = lprocfs_write_helper(buffer, count, &val);
2385 obd->obd_recovery_timeout = val;
2388 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2390 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2391 int count, int *eof, void *data)
2393 struct obd_device *obd = data;
2394 LASSERT(obd != NULL);
2396 return snprintf(page, count, "%u\n", obd->obd_recovery_time_hard);
2398 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2400 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2401 unsigned long count, void *data)
2403 struct obd_device *obd = data;
2405 LASSERT(obd != NULL);
2407 rc = lprocfs_write_helper(buffer, count, &val);
2411 obd->obd_recovery_time_hard = val;
2414 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2416 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2417 int count, int *eof, void *data)
2419 struct obd_device *obd = (struct obd_device *)data;
2421 LASSERT(obd != NULL);
2422 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2424 return snprintf(page, count, "%s\n",
2425 obd->u.obt.obt_vfsmnt->mnt_devname);
2427 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2429 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2430 int count, int *eof, void *data)
2432 struct obd_device *dev = data;
2433 struct client_obd *cli = &dev->u.cli;
2436 client_obd_list_lock(&cli->cl_loi_list_lock);
2437 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2438 client_obd_list_unlock(&cli->cl_loi_list_lock);
2441 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2443 int lprocfs_obd_wr_max_pages_per_rpc(struct file *file, const char *buffer,
2444 unsigned long count, void *data)
2446 struct obd_device *dev = data;
2447 struct client_obd *cli = &dev->u.cli;
2448 struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
2451 rc = lprocfs_write_helper(buffer, count, &val);
2455 LPROCFS_CLIMP_CHECK(dev);
2456 if (val < 1 || val > ocd->ocd_brw_size >> CFS_PAGE_SHIFT) {
2457 LPROCFS_CLIMP_EXIT(dev);
2460 client_obd_list_lock(&cli->cl_loi_list_lock);
2461 cli->cl_max_pages_per_rpc = val;
2462 client_obd_list_unlock(&cli->cl_loi_list_lock);
2464 LPROCFS_CLIMP_EXIT(dev);
2467 EXPORT_SYMBOL(lprocfs_obd_wr_max_pages_per_rpc);
2469 int lprocfs_target_rd_instance(char *page, char **start, off_t off,
2470 int count, int *eof, void *data)
2472 struct obd_device *obd = (struct obd_device *)data;
2473 struct obd_device_target *target = &obd->u.obt;
2475 LASSERT(obd != NULL);
2476 LASSERT(target->obt_magic == OBT_MAGIC);
2478 return snprintf(page, count, "%u\n", obd->u.obt.obt_instance);
2480 EXPORT_SYMBOL(lprocfs_target_rd_instance);
2482 EXPORT_SYMBOL(lprocfs_register);
2483 EXPORT_SYMBOL(lprocfs_srch);
2484 EXPORT_SYMBOL(lprocfs_remove);
2485 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2486 EXPORT_SYMBOL(lprocfs_add_vars);
2487 EXPORT_SYMBOL(lprocfs_obd_setup);
2488 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2489 EXPORT_SYMBOL(lprocfs_add_simple);
2490 EXPORT_SYMBOL(lprocfs_add_symlink);
2491 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2492 EXPORT_SYMBOL(lprocfs_alloc_stats);
2493 EXPORT_SYMBOL(lprocfs_free_stats);
2494 EXPORT_SYMBOL(lprocfs_clear_stats);
2495 EXPORT_SYMBOL(lprocfs_register_stats);
2496 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2497 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2498 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2499 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2500 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2501 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2502 EXPORT_SYMBOL(lprocfs_free_md_stats);
2503 EXPORT_SYMBOL(lprocfs_exp_setup);
2504 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2506 EXPORT_SYMBOL(lprocfs_rd_u64);
2507 EXPORT_SYMBOL(lprocfs_rd_atomic);
2508 EXPORT_SYMBOL(lprocfs_wr_atomic);
2509 EXPORT_SYMBOL(lprocfs_rd_uint);
2510 EXPORT_SYMBOL(lprocfs_wr_uint);
2511 EXPORT_SYMBOL(lprocfs_rd_uuid);
2512 EXPORT_SYMBOL(lprocfs_rd_name);
2513 EXPORT_SYMBOL(lprocfs_rd_fstype);
2514 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2515 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2516 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2517 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2518 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2519 EXPORT_SYMBOL(lprocfs_rd_import);
2520 EXPORT_SYMBOL(lprocfs_rd_state);
2521 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2522 EXPORT_SYMBOL(lprocfs_rd_blksize);
2523 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2524 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2525 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2526 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2527 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2529 EXPORT_SYMBOL(lprocfs_write_helper);
2530 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2531 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2532 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2533 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2534 EXPORT_SYMBOL(lprocfs_stats_collect);