1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
30 * Use is subject to license terms.
33 * Copyright (c) 2011 Whamcloud, Inc.
36 * This file is part of Lustre, http://www.lustre.org/
37 * Lustre is a trademark of Sun Microsystems, Inc.
39 * lustre/obdclass/lprocfs_status.c
41 * Author: Hariharan Thantry <thantry@users.sourceforge.net>
45 # define EXPORT_SYMTAB
47 #define DEBUG_SUBSYSTEM S_CLASS
50 # include <liblustre.h>
53 #include <obd_class.h>
54 #include <lprocfs_status.h>
55 #include <lustre_fsfilt.h>
56 #include <lustre_log.h>
57 #include <lustre/lustre_idl.h>
61 #define MAX_STRING_SIZE 128
63 /* for bug 10866, global variable */
64 CFS_DECLARE_RWSEM(_lprocfs_lock);
65 EXPORT_SYMBOL(_lprocfs_lock);
67 int lprocfs_seq_release(struct inode *inode, struct file *file)
70 return seq_release(inode, file);
72 EXPORT_SYMBOL(lprocfs_seq_release);
74 static struct proc_dir_entry *__lprocfs_srch(struct proc_dir_entry *head,
77 struct proc_dir_entry *temp;
83 while (temp != NULL) {
84 if (strcmp(temp->name, name) == 0) {
93 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
96 struct proc_dir_entry *temp;
99 temp = __lprocfs_srch(head, name);
104 /* lprocfs API calls */
106 /* Function that emulates snprintf but also has the side effect of advancing
107 the page pointer for the next write into the buffer, incrementing the total
108 length written to the buffer, and decrementing the size left in the
110 static int lprocfs_obd_snprintf(char **page, int end, int *len,
111 const char *format, ...)
119 va_start(list, format);
120 n = vsnprintf(*page, end - *len, format, list);
123 *page += n; *len += n;
127 cfs_proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
129 read_proc_t *read_proc,
130 write_proc_t *write_proc,
132 struct file_operations *fops)
134 cfs_proc_dir_entry_t *proc;
137 if (root == NULL || name == NULL)
138 return ERR_PTR(-EINVAL);
145 LPROCFS_WRITE_ENTRY();
146 proc = create_proc_entry(name, mode, root);
148 CERROR("LprocFS: No memory to create /proc entry %s", name);
149 LPROCFS_WRITE_EXIT();
150 return ERR_PTR(-ENOMEM);
152 proc->read_proc = read_proc;
153 proc->write_proc = write_proc;
156 proc->proc_fops = fops;
157 LPROCFS_WRITE_EXIT();
161 struct proc_dir_entry *lprocfs_add_symlink(const char *name,
162 struct proc_dir_entry *parent, const char *format, ...)
164 struct proc_dir_entry *entry;
168 if (parent == NULL || format == NULL)
171 OBD_ALLOC_WAIT(dest, MAX_STRING_SIZE + 1);
175 va_start(ap, format);
176 vsnprintf(dest, MAX_STRING_SIZE, format, ap);
179 entry = proc_symlink(name, parent, dest);
181 CERROR("LprocFS: Could not create symbolic link from %s to %s",
184 OBD_FREE(dest, MAX_STRING_SIZE + 1);
188 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
189 size_t size, loff_t *ppos)
191 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
192 char *page, *start = NULL;
193 int rc = 0, eof = 1, count;
195 if (*ppos >= CFS_PAGE_SIZE)
198 page = (char *)__get_free_page(GFP_KERNEL);
202 if (LPROCFS_ENTRY_AND_CHECK(dp)) {
207 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
209 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
215 /* for lustre proc read, the read count must be less than PAGE_SIZE */
224 start = page + *ppos;
225 } else if (start < page) {
229 count = (rc < size) ? rc : size;
230 if (cfs_copy_to_user(buf, start, count)) {
237 free_page((unsigned long)page);
241 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
242 size_t size, loff_t *ppos)
244 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
247 if (LPROCFS_ENTRY_AND_CHECK(dp))
250 rc = dp->write_proc(f, buf, size, dp->data);
255 static struct file_operations lprocfs_generic_fops = {
256 .owner = THIS_MODULE,
257 .read = lprocfs_fops_read,
258 .write = lprocfs_fops_write,
261 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
263 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
264 struct obd_device *obd = dp->data;
266 cfs_atomic_inc(&obd->obd_evict_inprogress);
271 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
273 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
274 struct obd_device *obd = dp->data;
276 cfs_atomic_dec(&obd->obd_evict_inprogress);
277 cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
282 struct file_operations lprocfs_evict_client_fops = {
283 .owner = THIS_MODULE,
284 .read = lprocfs_fops_read,
285 .write = lprocfs_fops_write,
286 .open = lprocfs_evict_client_open,
287 .release = lprocfs_evict_client_release,
289 EXPORT_SYMBOL(lprocfs_evict_client_fops);
294 * \param root [in] The parent proc entry on which new entry will be added.
295 * \param list [in] Array of proc entries to be added.
296 * \param data [in] The argument to be passed when entries read/write routines
297 * are called through /proc file.
299 * \retval 0 on success
302 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
307 if (root == NULL || list == NULL)
310 LPROCFS_WRITE_ENTRY();
311 while (list->name != NULL) {
312 struct proc_dir_entry *cur_root, *proc;
313 char *pathcopy, *cur, *next, pathbuf[64];
314 int pathsize = strlen(list->name) + 1;
319 /* need copy of path for strsep */
320 if (strlen(list->name) > sizeof(pathbuf) - 1) {
321 OBD_ALLOC(pathcopy, pathsize);
322 if (pathcopy == NULL)
323 GOTO(out, rc = -ENOMEM);
329 strcpy(pathcopy, list->name);
331 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
332 if (*cur =='\0') /* skip double/trailing "/" */
335 proc = __lprocfs_srch(cur_root, cur);
336 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
337 cur_root->name, cur, next,
338 (proc ? "exists" : "new"));
340 cur_root = (proc ? proc :
341 proc_mkdir(cur, cur_root));
342 } else if (proc == NULL) {
344 if (list->proc_mode != 0000) {
345 mode = list->proc_mode;
349 if (list->write_fptr)
352 proc = create_proc_entry(cur, mode, cur_root);
356 if (pathcopy != pathbuf)
357 OBD_FREE(pathcopy, pathsize);
359 if (cur_root == NULL || proc == NULL) {
360 CERROR("LprocFS: No memory to create /proc entry %s",
362 GOTO(out, rc = -ENOMEM);
366 proc->proc_fops = list->fops;
368 proc->proc_fops = &lprocfs_generic_fops;
369 proc->read_proc = list->read_fptr;
370 proc->write_proc = list->write_fptr;
371 proc->data = (list->data ? list->data : data);
375 LPROCFS_WRITE_EXIT();
379 void lprocfs_remove(struct proc_dir_entry **rooth)
381 struct proc_dir_entry *root = *rooth;
382 struct proc_dir_entry *temp = root;
383 struct proc_dir_entry *rm_entry;
384 struct proc_dir_entry *parent;
390 parent = root->parent;
391 LASSERT(parent != NULL);
392 LPROCFS_WRITE_ENTRY(); /* search vs remove race */
395 while (temp->subdir != NULL)
401 /* Memory corruption once caused this to fail, and
402 without this LASSERT we would loop here forever. */
403 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
404 "0x%p %s/%s len %d\n", rm_entry, temp->name,
405 rm_entry->name, (int)strlen(rm_entry->name));
407 #ifdef HAVE_PROCFS_USERS
408 /* if procfs uses user count to synchronize deletion of
409 * proc entry, there is no protection for rm_entry->data,
410 * then lprocfs_fops_read and lprocfs_fops_write maybe
411 * call proc_dir_entry->read_proc (or write_proc) with
412 * proc_dir_entry->data == NULL, then cause kernel Oops.
413 * see bug19706 for detailed information */
415 /* procfs won't free rm_entry->data if it isn't a LINK,
416 * and Lustre won't use rm_entry->data if it is a LINK */
417 if (S_ISLNK(rm_entry->mode))
418 rm_entry->data = NULL;
420 /* Now, the rm_entry->deleted flags is protected
421 * by _lprocfs_lock. */
422 rm_entry->data = NULL;
424 remove_proc_entry(rm_entry->name, temp);
428 LPROCFS_WRITE_EXIT();
431 void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
433 LASSERT(parent != NULL);
434 remove_proc_entry(name, parent);
437 struct proc_dir_entry *lprocfs_register(const char *name,
438 struct proc_dir_entry *parent,
439 struct lprocfs_vars *list, void *data)
441 struct proc_dir_entry *newchild;
443 newchild = lprocfs_srch(parent, name);
444 if (newchild != NULL) {
445 CERROR(" Lproc: Attempting to register %s more than once \n",
447 return ERR_PTR(-EALREADY);
450 newchild = proc_mkdir(name, parent);
451 if (newchild != NULL && list != NULL) {
452 int rc = lprocfs_add_vars(newchild, list, data);
454 lprocfs_remove(&newchild);
461 /* Generic callbacks */
462 int lprocfs_rd_uint(char *page, char **start, off_t off,
463 int count, int *eof, void *data)
465 unsigned int *temp = data;
466 return snprintf(page, count, "%u\n", *temp);
469 int lprocfs_wr_uint(struct file *file, const char *buffer,
470 unsigned long count, void *data)
473 char dummy[MAX_STRING_SIZE + 1], *end;
476 dummy[MAX_STRING_SIZE] = '\0';
477 if (cfs_copy_from_user(dummy, buffer, MAX_STRING_SIZE))
480 tmp = simple_strtoul(dummy, &end, 0);
484 *p = (unsigned int)tmp;
488 int lprocfs_rd_u64(char *page, char **start, off_t off,
489 int count, int *eof, void *data)
491 LASSERT(data != NULL);
493 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
496 int lprocfs_rd_atomic(char *page, char **start, off_t off,
497 int count, int *eof, void *data)
499 cfs_atomic_t *atom = data;
500 LASSERT(atom != NULL);
502 return snprintf(page, count, "%d\n", cfs_atomic_read(atom));
505 int lprocfs_wr_atomic(struct file *file, const char *buffer,
506 unsigned long count, void *data)
508 cfs_atomic_t *atm = data;
512 rc = lprocfs_write_helper(buffer, count, &val);
519 cfs_atomic_set(atm, val);
523 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
524 int *eof, void *data)
526 struct obd_device *obd = data;
528 LASSERT(obd != NULL);
530 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
533 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
534 int *eof, void *data)
536 struct obd_device *dev = data;
538 LASSERT(dev != NULL);
539 LASSERT(dev->obd_name != NULL);
541 return snprintf(page, count, "%s\n", dev->obd_name);
544 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
547 struct obd_device *obd = data;
549 LASSERT(obd != NULL);
550 LASSERT(obd->obd_fsops != NULL);
551 LASSERT(obd->obd_fsops->fs_type != NULL);
552 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
555 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
556 int *eof, void *data)
558 struct obd_statfs osfs;
559 int rc = obd_statfs(data, &osfs,
560 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
564 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
569 int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
570 int *eof, void *data)
572 struct obd_statfs osfs;
573 int rc = obd_statfs(data, &osfs,
574 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
577 __u32 blk_size = osfs.os_bsize >> 10;
578 __u64 result = osfs.os_blocks;
580 while (blk_size >>= 1)
584 rc = snprintf(page, count, LPU64"\n", result);
589 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
590 int *eof, void *data)
592 struct obd_statfs osfs;
593 int rc = obd_statfs(data, &osfs,
594 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
597 __u32 blk_size = osfs.os_bsize >> 10;
598 __u64 result = osfs.os_bfree;
600 while (blk_size >>= 1)
604 rc = snprintf(page, count, LPU64"\n", result);
609 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
610 int *eof, void *data)
612 struct obd_statfs osfs;
613 int rc = obd_statfs(data, &osfs,
614 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
617 __u32 blk_size = osfs.os_bsize >> 10;
618 __u64 result = osfs.os_bavail;
620 while (blk_size >>= 1)
624 rc = snprintf(page, count, LPU64"\n", result);
629 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
630 int *eof, void *data)
632 struct obd_statfs osfs;
633 int rc = obd_statfs(data, &osfs,
634 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
638 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
644 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
645 int *eof, void *data)
647 struct obd_statfs osfs;
648 int rc = obd_statfs(data, &osfs,
649 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
653 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
658 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
659 int *eof, void *data)
661 struct obd_device *obd = data;
662 struct obd_import *imp;
663 char *imp_state_name = NULL;
666 LASSERT(obd != NULL);
667 LPROCFS_CLIMP_CHECK(obd);
668 imp = obd->u.cli.cl_import;
669 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
671 rc = snprintf(page, count, "%s\t%s%s\n",
672 obd2cli_tgt(obd), imp_state_name,
673 imp->imp_deactive ? "\tDEACTIVATED" : "");
675 LPROCFS_CLIMP_EXIT(obd);
679 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
680 int *eof, void *data)
682 struct obd_device *obd = data;
683 struct ptlrpc_connection *conn;
686 LASSERT(obd != NULL);
688 LPROCFS_CLIMP_CHECK(obd);
689 conn = obd->u.cli.cl_import->imp_connection;
691 if (conn && obd->u.cli.cl_import) {
692 rc = snprintf(page, count, "%s\n",
693 conn->c_remote_uuid.uuid);
695 rc = snprintf(page, count, "%s\n", "<none>");
698 LPROCFS_CLIMP_EXIT(obd);
702 /** add up per-cpu counters */
703 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
704 struct lprocfs_counter *cnt)
706 unsigned int num_cpu;
707 struct lprocfs_counter t;
708 struct lprocfs_counter *percpu_cntr;
711 memset(cnt, 0, sizeof(*cnt));
714 /* set count to 1 to avoid divide-by-zero errs in callers */
719 cnt->lc_min = LC_MIN_INIT;
721 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
723 for (i = 0; i < num_cpu; i++) {
724 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
727 centry = cfs_atomic_read(&percpu_cntr-> \
729 t.lc_count = percpu_cntr->lc_count;
730 t.lc_sum = percpu_cntr->lc_sum;
731 t.lc_min = percpu_cntr->lc_min;
732 t.lc_max = percpu_cntr->lc_max;
733 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
734 } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
736 centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
738 cnt->lc_count += t.lc_count;
739 cnt->lc_sum += t.lc_sum;
740 if (t.lc_min < cnt->lc_min)
741 cnt->lc_min = t.lc_min;
742 if (t.lc_max > cnt->lc_max)
743 cnt->lc_max = t.lc_max;
744 cnt->lc_sumsquare += t.lc_sumsquare;
747 cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
748 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
752 * Append a space separated list of current set flags to str.
754 #define flag2str(flag) \
755 if (imp->imp_##flag && max - len > 0) \
756 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
757 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
761 if (imp->imp_obd->obd_no_recov)
762 len += snprintf(str, max - len, "no_recov");
766 flag2str(replayable);
772 static const char *obd_connect_names[] = {
786 "join_file(obsolete)",
790 "remote_client_by_force",
799 "mds_mds_connection",
802 "alt_checksum_algorithm",
819 int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
824 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
826 ret += snprintf(page + ret, count - ret, "%s%s",
827 ret ? sep : "", obd_connect_names[i]);
829 if (flags & ~(mask - 1))
830 ret += snprintf(page + ret, count - ret,
831 "%sunknown flags "LPX64,
832 ret ? sep : "", flags & ~(mask - 1));
835 EXPORT_SYMBOL(obd_connect_flags2str);
837 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
838 int *eof, void *data)
840 struct lprocfs_counter ret;
841 struct obd_device *obd = (struct obd_device *)data;
842 struct obd_import *imp;
843 struct obd_import_conn *conn;
846 LASSERT(obd != NULL);
847 LPROCFS_CLIMP_CHECK(obd);
848 imp = obd->u.cli.cl_import;
851 i = snprintf(page, count,
860 ptlrpc_import_state_name(imp->imp_state),
861 imp->imp_connect_data.ocd_instance);
862 i += obd_connect_flags2str(page + i, count - i,
863 imp->imp_connect_data.ocd_connect_flags,
865 i += snprintf(page + i, count - i,
868 i += obd_import_flags2str(imp, page + i, count - i);
870 i += snprintf(page + i, count - i,
873 " failover_nids: [");
874 cfs_spin_lock(&imp->imp_lock);
876 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
877 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
878 libcfs_nid2str(conn->oic_conn->c_peer.nid));
881 cfs_spin_unlock(&imp->imp_lock);
882 i += snprintf(page + i, count - i,
884 " current_connection: %s\n"
885 " connection_attempts: %u\n"
887 " in-progress_invalidations: %u\n",
888 libcfs_nid2str(imp->imp_connection->c_peer.nid),
891 cfs_atomic_read(&imp->imp_inval_count));
893 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
894 if (ret.lc_count != 0) {
895 /* first argument to do_div MUST be __u64 */
896 __u64 sum = ret.lc_sum;
897 do_div(sum, ret.lc_count);
901 i += snprintf(page + i, count - i,
904 " unregistering: %u\n"
906 " avg_waittime: "LPU64" %s\n",
907 cfs_atomic_read(&imp->imp_inflight),
908 cfs_atomic_read(&imp->imp_unregistering),
909 cfs_atomic_read(&imp->imp_timeouts),
910 ret.lc_sum, ret.lc_units);
913 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
914 if (imp->imp_at.iat_portal[j] == 0)
916 k = max_t(unsigned int, k,
917 at_get(&imp->imp_at.iat_service_estimate[j]));
919 i += snprintf(page + i, count - i,
920 " service_estimates:\n"
921 " services: %u sec\n"
922 " network: %u sec\n",
924 at_get(&imp->imp_at.iat_net_latency));
926 i += snprintf(page + i, count - i,
928 " last_replay: "LPU64"\n"
929 " peer_committed: "LPU64"\n"
930 " last_checked: "LPU64"\n",
931 imp->imp_last_replay_transno,
932 imp->imp_peer_committed_transno,
933 imp->imp_last_transno_checked);
936 for (rw = 0; rw <= 1; rw++) {
937 lprocfs_stats_collect(obd->obd_svc_stats,
938 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
940 if (ret.lc_sum > 0 && ret.lc_count > 0) {
941 /* first argument to do_div MUST be __u64 */
942 __u64 sum = ret.lc_sum;
943 do_div(sum, ret.lc_count);
945 i += snprintf(page + i, count - i,
946 " %s_data_averages:\n"
947 " bytes_per_rpc: "LPU64"\n",
948 rw ? "write" : "read",
952 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
953 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
954 if (ret.lc_sum > 0 && ret.lc_count != 0) {
955 /* first argument to do_div MUST be __u64 */
956 __u64 sum = ret.lc_sum;
957 do_div(sum, ret.lc_count);
959 i += snprintf(page + i, count - i,
960 " %s_per_rpc: "LPU64"\n",
961 ret.lc_units, ret.lc_sum);
964 i += snprintf(page + i, count - i,
965 " MB_per_sec: %u.%.02u\n",
966 k / j, (100 * k / j) % 100);
970 LPROCFS_CLIMP_EXIT(obd);
974 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
975 int *eof, void *data)
977 struct obd_device *obd = (struct obd_device *)data;
978 struct obd_import *imp;
981 LASSERT(obd != NULL);
982 LPROCFS_CLIMP_CHECK(obd);
983 imp = obd->u.cli.cl_import;
986 i = snprintf(page, count, "current_state: %s\n",
987 ptlrpc_import_state_name(imp->imp_state));
988 i += snprintf(page + i, count - i,
990 k = imp->imp_state_hist_idx;
991 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
992 struct import_state_hist *ish =
993 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
994 if (ish->ish_state == 0)
996 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
998 ptlrpc_import_state_name(ish->ish_state));
1001 LPROCFS_CLIMP_EXIT(obd);
1005 int lprocfs_at_hist_helper(char *page, int count, int rc,
1006 struct adaptive_timeout *at)
1009 for (i = 0; i < AT_BINS; i++)
1010 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1011 rc += snprintf(page + rc, count - rc, "\n");
1015 /* See also ptlrpc_lprocfs_rd_timeouts */
1016 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1017 int *eof, void *data)
1019 struct obd_device *obd = (struct obd_device *)data;
1020 struct obd_import *imp;
1021 unsigned int cur, worst;
1026 LASSERT(obd != NULL);
1027 LPROCFS_CLIMP_CHECK(obd);
1028 imp = obd->u.cli.cl_import;
1031 now = cfs_time_current_sec();
1033 /* Some network health info for kicks */
1034 s2dhms(&ts, now - imp->imp_last_reply_time);
1035 rc += snprintf(page + rc, count - rc,
1036 "%-10s : %ld, "DHMS_FMT" ago\n",
1037 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1039 cur = at_get(&imp->imp_at.iat_net_latency);
1040 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1041 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1042 s2dhms(&ts, now - worstt);
1043 rc += snprintf(page + rc, count - rc,
1044 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1045 "network", cur, worst, worstt, DHMS_VARS(&ts));
1046 rc = lprocfs_at_hist_helper(page, count, rc,
1047 &imp->imp_at.iat_net_latency);
1049 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1050 if (imp->imp_at.iat_portal[i] == 0)
1052 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1053 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1054 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1055 s2dhms(&ts, now - worstt);
1056 rc += snprintf(page + rc, count - rc,
1057 "portal %-2d : cur %3u worst %3u (at %ld, "
1058 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1059 cur, worst, worstt, DHMS_VARS(&ts));
1060 rc = lprocfs_at_hist_helper(page, count, rc,
1061 &imp->imp_at.iat_service_estimate[i]);
1064 LPROCFS_CLIMP_EXIT(obd);
1068 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1069 int count, int *eof, void *data)
1071 struct obd_device *obd = data;
1075 LPROCFS_CLIMP_CHECK(obd);
1076 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1077 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1078 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1079 ret += snprintf(page + ret, count - ret, "\n");
1080 LPROCFS_CLIMP_EXIT(obd);
1083 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1085 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1086 int *eof, void *data)
1088 struct obd_device *obd = data;
1090 LASSERT(obd != NULL);
1092 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1095 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1096 int *eof, void *data)
1098 struct obd_type *class = (struct obd_type*) data;
1100 LASSERT(class != NULL);
1102 return snprintf(page, count, "%d\n", class->typ_refcnt);
1105 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1109 LASSERT(obd != NULL);
1110 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1111 LASSERT(obd->obd_type->typ_procroot != NULL);
1113 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1114 obd->obd_type->typ_procroot,
1116 if (IS_ERR(obd->obd_proc_entry)) {
1117 rc = PTR_ERR(obd->obd_proc_entry);
1118 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1119 obd->obd_proc_entry = NULL;
1124 int lprocfs_obd_cleanup(struct obd_device *obd)
1128 if (obd->obd_proc_exports_entry) {
1129 /* Should be no exports left */
1130 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1131 lprocfs_remove(&obd->obd_proc_exports_entry);
1132 obd->obd_proc_exports_entry = NULL;
1134 if (obd->obd_proc_entry) {
1135 lprocfs_remove(&obd->obd_proc_entry);
1136 obd->obd_proc_entry = NULL;
1141 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1143 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1144 client_stat->nid_proc, client_stat->nid_stats,
1145 client_stat->nid_brw_stats);
1147 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1148 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1149 atomic_read(&client_stat->nid_exp_ref_count));
1151 if (client_stat->nid_proc)
1152 lprocfs_remove(&client_stat->nid_proc);
1154 if (client_stat->nid_stats)
1155 lprocfs_free_stats(&client_stat->nid_stats);
1157 if (client_stat->nid_brw_stats)
1158 OBD_FREE_PTR(client_stat->nid_brw_stats);
1160 if (client_stat->nid_ldlm_stats)
1161 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1163 OBD_FREE_PTR(client_stat);
1168 void lprocfs_free_per_client_stats(struct obd_device *obd)
1170 cfs_hash_t *hash = obd->obd_nid_stats_hash;
1171 struct nid_stat *stat;
1174 /* we need extra list - because hash_exit called to early */
1175 /* not need locking because all clients is died */
1176 while (!cfs_list_empty(&obd->obd_nid_stats)) {
1177 stat = cfs_list_entry(obd->obd_nid_stats.next,
1178 struct nid_stat, nid_list);
1179 cfs_list_del_init(&stat->nid_list);
1180 cfs_hash_del(hash, &stat->nid, &stat->nid_hash);
1181 lprocfs_free_client_stats(stat);
1186 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1187 enum lprocfs_stats_flags flags)
1189 struct lprocfs_stats *stats;
1190 unsigned int percpusize;
1192 unsigned int num_cpu;
1197 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1200 num_cpu = cfs_num_possible_cpus();
1202 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1206 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1207 stats->ls_flags = flags;
1208 cfs_spin_lock_init(&stats->ls_lock);
1209 /* Use this lock only if there are no percpu areas */
1211 stats->ls_flags = 0;
1214 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1216 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1218 for (i = 0; i < num_cpu; i++) {
1219 OBD_ALLOC(stats->ls_percpu[i], percpusize);
1220 if (stats->ls_percpu[i] == NULL) {
1221 for (j = 0; j < i; j++) {
1222 OBD_FREE(stats->ls_percpu[j], percpusize);
1223 stats->ls_percpu[j] = NULL;
1228 if (stats->ls_percpu[0] == NULL) {
1229 OBD_FREE(stats, offsetof(typeof(*stats),
1230 ls_percpu[num_cpu]));
1234 stats->ls_num = num;
1238 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1240 struct lprocfs_stats *stats = *statsh;
1241 unsigned int num_cpu;
1242 unsigned int percpusize;
1245 if (stats == NULL || stats->ls_num == 0)
1249 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1252 num_cpu = cfs_num_possible_cpus();
1254 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1256 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1257 for (i = 0; i < num_cpu; i++)
1258 OBD_FREE(stats->ls_percpu[i], percpusize);
1259 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1262 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1264 struct lprocfs_counter *percpu_cntr;
1266 unsigned int num_cpu;
1268 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1270 for (i = 0; i < num_cpu; i++) {
1271 for (j = 0; j < stats->ls_num; j++) {
1272 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1273 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1274 percpu_cntr->lc_count = 0;
1275 percpu_cntr->lc_sum = 0;
1276 percpu_cntr->lc_min = LC_MIN_INIT;
1277 percpu_cntr->lc_max = 0;
1278 percpu_cntr->lc_sumsquare = 0;
1279 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1283 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1286 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1287 size_t len, loff_t *off)
1289 struct seq_file *seq = file->private_data;
1290 struct lprocfs_stats *stats = seq->private;
1292 lprocfs_clear_stats(stats);
1297 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1299 struct lprocfs_stats *stats = p->private;
1300 /* return 1st cpu location */
1301 return (*pos >= stats->ls_num) ? NULL :
1302 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1305 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1309 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1311 struct lprocfs_stats *stats = p->private;
1313 return (*pos >= stats->ls_num) ? NULL :
1314 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1317 /* seq file export of one lprocfs counter */
1318 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1320 struct lprocfs_stats *stats = p->private;
1321 struct lprocfs_counter *cntr = v;
1322 struct lprocfs_counter ret;
1325 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1327 cfs_gettimeofday(&now);
1328 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1329 "snapshot_time", now.tv_sec, now.tv_usec);
1333 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1335 lprocfs_stats_collect(stats, idx, &ret);
1337 if (ret.lc_count == 0)
1340 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1341 ret.lc_count, cntr->lc_units);
1346 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1347 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1348 ret.lc_min, ret.lc_max, ret.lc_sum);
1351 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1352 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1356 rc = seq_printf(p, "\n");
1358 return (rc < 0) ? rc : 0;
1361 struct seq_operations lprocfs_stats_seq_sops = {
1362 start: lprocfs_stats_seq_start,
1363 stop: lprocfs_stats_seq_stop,
1364 next: lprocfs_stats_seq_next,
1365 show: lprocfs_stats_seq_show,
1368 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1370 struct proc_dir_entry *dp = PDE(inode);
1371 struct seq_file *seq;
1374 if (LPROCFS_ENTRY_AND_CHECK(dp))
1377 rc = seq_open(file, &lprocfs_stats_seq_sops);
1382 seq = file->private_data;
1383 seq->private = dp->data;
1387 struct file_operations lprocfs_stats_seq_fops = {
1388 .owner = THIS_MODULE,
1389 .open = lprocfs_stats_seq_open,
1391 .write = lprocfs_stats_seq_write,
1392 .llseek = seq_lseek,
1393 .release = lprocfs_seq_release,
1396 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1397 struct lprocfs_stats *stats)
1399 struct proc_dir_entry *entry;
1400 LASSERT(root != NULL);
1402 LPROCFS_WRITE_ENTRY();
1403 entry = create_proc_entry(name, 0644, root);
1405 entry->proc_fops = &lprocfs_stats_seq_fops;
1406 entry->data = stats;
1409 LPROCFS_WRITE_EXIT();
1417 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1418 unsigned conf, const char *name, const char *units)
1420 struct lprocfs_counter *c;
1422 unsigned int num_cpu;
1424 LASSERT(stats != NULL);
1426 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1428 for (i = 0; i < num_cpu; i++) {
1429 c = &(stats->ls_percpu[i]->lp_cntr[index]);
1430 c->lc_config = conf;
1433 c->lc_min = LC_MIN_INIT;
1436 c->lc_units = units;
1439 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1441 EXPORT_SYMBOL(lprocfs_counter_init);
1443 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1445 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1446 LASSERT(coffset < stats->ls_num); \
1447 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1450 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1452 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1453 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1454 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1455 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1456 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1457 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1458 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1459 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1460 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1461 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1462 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1463 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1467 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1468 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1469 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1470 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1471 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1472 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1473 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1474 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1475 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1476 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1477 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1478 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1479 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1480 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1481 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1482 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1483 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1484 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1485 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1486 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1487 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1488 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1489 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1490 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1491 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1492 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1493 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1494 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1495 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1496 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1497 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1498 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1499 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1500 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1501 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1502 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1503 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1504 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1505 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1506 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1507 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1508 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1509 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1510 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1511 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1512 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1513 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1514 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1515 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1516 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1517 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1518 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1519 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1520 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1523 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1525 struct lprocfs_stats *stats;
1526 unsigned int num_stats;
1529 LASSERT(obd->obd_stats == NULL);
1530 LASSERT(obd->obd_proc_entry != NULL);
1531 LASSERT(obd->obd_cntr_base == 0);
1533 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1534 num_private_stats - 1 /* o_owner */;
1535 stats = lprocfs_alloc_stats(num_stats, 0);
1539 lprocfs_init_ops_stats(num_private_stats, stats);
1541 for (i = num_private_stats; i < num_stats; i++) {
1542 /* If this LBUGs, it is likely that an obd
1543 * operation was added to struct obd_ops in
1544 * <obd.h>, and that the corresponding line item
1545 * LPROCFS_OBD_OP_INIT(.., .., opname)
1546 * is missing from the list above. */
1547 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1548 "Missing obd_stat initializer obd_op "
1549 "operation at offset %d.\n", i - num_private_stats);
1551 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1553 lprocfs_free_stats(&stats);
1555 obd->obd_stats = stats;
1556 obd->obd_cntr_base = num_private_stats;
1561 void lprocfs_free_obd_stats(struct obd_device *obd)
1564 lprocfs_free_stats(&obd->obd_stats);
1567 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1569 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1570 LASSERT(coffset < stats->ls_num); \
1571 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1574 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1576 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1577 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1578 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1579 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1580 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1581 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1582 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1583 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1584 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1585 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1586 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1587 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1588 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1589 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1590 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1591 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1592 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1593 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1594 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1595 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1596 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1597 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1598 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1599 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1600 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1601 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1602 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1603 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1604 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1605 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1606 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1607 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1610 int lprocfs_alloc_md_stats(struct obd_device *obd,
1611 unsigned num_private_stats)
1613 struct lprocfs_stats *stats;
1614 unsigned int num_stats;
1617 LASSERT(obd->md_stats == NULL);
1618 LASSERT(obd->obd_proc_entry != NULL);
1619 LASSERT(obd->md_cntr_base == 0);
1621 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1623 stats = lprocfs_alloc_stats(num_stats, 0);
1627 lprocfs_init_mps_stats(num_private_stats, stats);
1629 for (i = num_private_stats; i < num_stats; i++) {
1630 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1631 CERROR("Missing md_stat initializer md_op "
1632 "operation at offset %d. Aborting.\n",
1633 i - num_private_stats);
1637 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1639 lprocfs_free_stats(&stats);
1641 obd->md_stats = stats;
1642 obd->md_cntr_base = num_private_stats;
1647 void lprocfs_free_md_stats(struct obd_device *obd)
1649 struct lprocfs_stats *stats = obd->md_stats;
1651 if (stats != NULL) {
1652 obd->md_stats = NULL;
1653 obd->md_cntr_base = 0;
1654 lprocfs_free_stats(&stats);
1658 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1660 lprocfs_counter_init(ldlm_stats,
1661 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1662 0, "ldlm_enqueue", "reqs");
1663 lprocfs_counter_init(ldlm_stats,
1664 LDLM_CONVERT - LDLM_FIRST_OPC,
1665 0, "ldlm_convert", "reqs");
1666 lprocfs_counter_init(ldlm_stats,
1667 LDLM_CANCEL - LDLM_FIRST_OPC,
1668 0, "ldlm_cancel", "reqs");
1669 lprocfs_counter_init(ldlm_stats,
1670 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1671 0, "ldlm_bl_callback", "reqs");
1672 lprocfs_counter_init(ldlm_stats,
1673 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1674 0, "ldlm_cp_callback", "reqs");
1675 lprocfs_counter_init(ldlm_stats,
1676 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1677 0, "ldlm_gl_callback", "reqs");
1680 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1681 int *eof, void *data)
1683 struct obd_export *exp = data;
1684 LASSERT(exp != NULL);
1686 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1689 struct exp_uuid_cb_data {
1697 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1698 int count, int *eof, int *len)
1700 cb_data->page = page;
1701 cb_data->count = count;
1706 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1707 cfs_hlist_node_t *hnode, void *cb_data)
1710 struct obd_export *exp = cfs_hash_object(hs, hnode);
1711 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1713 if (exp->exp_nid_stats)
1714 *data->len += snprintf((data->page + *data->len),
1715 data->count, "%s\n",
1716 obd_uuid2str(&exp->exp_client_uuid));
1720 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1721 int *eof, void *data)
1723 struct nid_stat *stats = (struct nid_stat *)data;
1724 struct exp_uuid_cb_data cb_data;
1725 struct obd_device *obd = stats->nid_obd;
1730 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1731 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1732 lprocfs_exp_print_uuid, &cb_data);
1733 return (*cb_data.len);
1736 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1737 cfs_hlist_node_t *hnode, void *cb_data)
1740 struct exp_uuid_cb_data *data = cb_data;
1741 struct obd_export *exp = cfs_hash_object(hs, hnode);
1743 if (exp->exp_lock_hash != NULL) {
1745 *data->len += cfs_hash_debug_header(data->page,
1748 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1755 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1756 int *eof, void *data)
1758 struct nid_stat *stats = (struct nid_stat *)data;
1759 struct exp_uuid_cb_data cb_data;
1760 struct obd_device *obd = stats->nid_obd;
1765 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1767 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1768 lprocfs_exp_print_hash, &cb_data);
1769 return (*cb_data.len);
1772 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1773 int count, int *eof, void *data)
1776 return snprintf(page, count, "%s\n",
1777 "Write into this file to clear all nid stats and "
1778 "stale nid entries");
1780 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1782 static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1784 struct nid_stat *stat = obj;
1788 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1789 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1790 /* object has only hash references. */
1791 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1792 cfs_list_move(&stat->nid_list, data);
1793 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1796 /* we has reference to object - only clear data*/
1797 if (stat->nid_stats)
1798 lprocfs_clear_stats(stat->nid_stats);
1800 if (stat->nid_brw_stats) {
1801 for (i = 0; i < BRW_LAST; i++)
1802 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1807 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1808 unsigned long count, void *data)
1810 struct obd_device *obd = (struct obd_device *)data;
1811 struct nid_stat *client_stat;
1812 CFS_LIST_HEAD(free_list);
1814 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1815 lprocfs_nid_stats_clear_write_cb, &free_list);
1817 while (!cfs_list_empty(&free_list)) {
1818 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1820 cfs_list_del_init(&client_stat->nid_list);
1821 lprocfs_free_client_stats(client_stat);
1826 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1828 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1830 struct nid_stat *new_stat, *old_stat;
1831 struct obd_device *obd = NULL;
1832 cfs_proc_dir_entry_t *entry;
1833 char *buffer = NULL;
1839 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1840 !exp->exp_obd->obd_nid_stats_hash)
1843 /* not test against zero because eric say:
1844 * You may only test nid against another nid, or LNET_NID_ANY.
1845 * Anything else is nonsense.*/
1846 if (!nid || *nid == LNET_NID_ANY)
1851 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1853 OBD_ALLOC_PTR(new_stat);
1854 if (new_stat == NULL)
1857 new_stat->nid = *nid;
1858 new_stat->nid_obd = exp->exp_obd;
1859 /* we need set default refcount to 1 to balance obd_disconnect */
1860 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1862 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1863 nid, &new_stat->nid_hash);
1864 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1865 old_stat, libcfs_nid2str(*nid),
1866 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1868 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1869 * been and will never be called. */
1870 if (exp->exp_nid_stats) {
1871 nidstat_putref(exp->exp_nid_stats);
1872 exp->exp_nid_stats = NULL;
1875 /* Return -EALREADY here so that we know that the /proc
1876 * entry already has been created */
1877 if (old_stat != new_stat) {
1878 exp->exp_nid_stats = old_stat;
1879 GOTO(destroy_new, rc = -EALREADY);
1881 /* not found - create */
1882 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1884 GOTO(destroy_new, rc = -ENOMEM);
1886 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1887 new_stat->nid_proc = lprocfs_register(buffer,
1888 obd->obd_proc_exports_entry,
1890 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1892 if (new_stat->nid_proc == NULL) {
1893 CERROR("Error making export directory for nid %s\n",
1894 libcfs_nid2str(*nid));
1895 GOTO(destroy_new_ns, rc = -ENOMEM);
1898 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1899 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1900 if (IS_ERR(entry)) {
1901 CWARN("Error adding the NID stats file\n");
1902 rc = PTR_ERR(entry);
1903 GOTO(destroy_new_ns, rc);
1906 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1907 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1908 if (IS_ERR(entry)) {
1909 CWARN("Error adding the hash file\n");
1910 rc = PTR_ERR(entry);
1911 GOTO(destroy_new_ns, rc);
1914 exp->exp_nid_stats = new_stat;
1916 /* protect competitive add to list, not need locking on destroy */
1917 cfs_spin_lock(&obd->obd_nid_lock);
1918 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1919 cfs_spin_unlock(&obd->obd_nid_lock);
1924 if (new_stat->nid_proc != NULL)
1925 lprocfs_remove(&new_stat->nid_proc);
1926 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1929 nidstat_putref(new_stat);
1930 OBD_FREE_PTR(new_stat);
1934 int lprocfs_exp_cleanup(struct obd_export *exp)
1936 struct nid_stat *stat = exp->exp_nid_stats;
1938 if(!stat || !exp->exp_obd)
1941 nidstat_putref(exp->exp_nid_stats);
1942 exp->exp_nid_stats = NULL;
1947 int lprocfs_write_helper(const char *buffer, unsigned long count,
1950 return lprocfs_write_frac_helper(buffer, count, val, 1);
1953 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1956 char kernbuf[20], *end, *pbuf;
1958 if (count > (sizeof(kernbuf) - 1))
1961 if (cfs_copy_from_user(kernbuf, buffer, count))
1964 kernbuf[count] = '\0';
1971 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1975 if (end != NULL && *end == '.') {
1976 int temp_val, pow = 1;
1980 if (strlen(pbuf) > 5)
1981 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1983 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1986 for (i = 0; i < (end - pbuf); i++)
1989 *val += temp_val / pow;
1995 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
1998 long decimal_val, frac_val;
2004 decimal_val = val / mult;
2005 prtn = snprintf(buffer, count, "%ld", decimal_val);
2006 frac_val = val % mult;
2008 if (prtn < (count - 4) && frac_val > 0) {
2010 int i, temp_mult = 1, frac_bits = 0;
2012 temp_frac = frac_val * 10;
2013 buffer[prtn++] = '.';
2014 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2015 /* only reserved 2 bits fraction */
2016 buffer[prtn++] ='0';
2021 * Need to think these cases :
2022 * 1. #echo x.00 > /proc/xxx output result : x
2023 * 2. #echo x.0x > /proc/xxx output result : x.0x
2024 * 3. #echo x.x0 > /proc/xxx output result : x.x
2025 * 4. #echo x.xx > /proc/xxx output result : x.xx
2026 * Only reserved 2 bits fraction.
2028 for (i = 0; i < (5 - prtn); i++)
2031 frac_bits = min((int)count - prtn, 3 - frac_bits);
2032 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2033 frac_val * temp_mult / mult);
2036 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2038 if (buffer[prtn] == '.') {
2045 buffer[prtn++] ='\n';
2049 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2051 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2054 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2055 __u64 *val, int mult)
2057 char kernbuf[22], *end, *pbuf;
2058 __u64 whole, frac = 0, units;
2059 unsigned frac_d = 1;
2061 if (count > (sizeof(kernbuf) - 1))
2064 if (cfs_copy_from_user(kernbuf, buffer, count))
2067 kernbuf[count] = '\0';
2074 whole = simple_strtoull(pbuf, &end, 10);
2078 if (end != NULL && *end == '.') {
2082 /* need to limit frac_d to a __u32 */
2083 if (strlen(pbuf) > 10)
2086 frac = simple_strtoull(pbuf, &end, 10);
2087 /* count decimal places */
2088 for (i = 0; i < (end - pbuf); i++)
2105 /* Specified units override the multiplier */
2107 mult = mult < 0 ? -units : units;
2110 do_div(frac, frac_d);
2111 *val = whole * mult + frac;
2115 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2116 struct file_operations *seq_fops, void *data)
2118 struct proc_dir_entry *entry;
2121 LPROCFS_WRITE_ENTRY();
2122 entry = create_proc_entry(name, mode, parent);
2124 entry->proc_fops = seq_fops;
2127 LPROCFS_WRITE_EXIT();
2134 EXPORT_SYMBOL(lprocfs_seq_create);
2136 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2138 struct file_operations *seq_fops,
2141 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2142 mode, seq_fops, data));
2144 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2146 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2148 if (value >= OBD_HIST_MAX)
2149 value = OBD_HIST_MAX - 1;
2151 cfs_spin_lock(&oh->oh_lock);
2152 oh->oh_buckets[value]++;
2153 cfs_spin_unlock(&oh->oh_lock);
2155 EXPORT_SYMBOL(lprocfs_oh_tally);
2157 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2161 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2164 lprocfs_oh_tally(oh, val);
2166 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2168 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2170 unsigned long ret = 0;
2173 for (i = 0; i < OBD_HIST_MAX; i++)
2174 ret += oh->oh_buckets[i];
2177 EXPORT_SYMBOL(lprocfs_oh_sum);
2179 void lprocfs_oh_clear(struct obd_histogram *oh)
2181 cfs_spin_lock(&oh->oh_lock);
2182 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2183 cfs_spin_unlock(&oh->oh_lock);
2185 EXPORT_SYMBOL(lprocfs_oh_clear);
2187 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2188 int count, int *eof, void *data)
2190 struct obd_device *obd = data;
2196 c += cfs_hash_debug_header(page, count);
2197 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2198 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2199 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2200 #ifdef HAVE_QUOTA_SUPPORT
2201 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2202 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2203 page + c, count - c);
2208 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2210 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2211 int count, int *eof, void *data)
2213 struct obd_device *obd = data;
2216 LASSERT(obd != NULL);
2217 LASSERT(count >= 0);
2219 /* Set start of user data returned to
2220 page + off since the user may have
2221 requested to read much smaller than
2222 what we need to read */
2223 *start = page + off;
2225 /* We know we are allocated a page here.
2226 Also we know that this function will
2227 not need to write more than a page
2228 so we can truncate at CFS_PAGE_SIZE. */
2229 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2231 /* Initialize the page */
2232 memset(page, 0, size);
2234 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2236 if (obd->obd_max_recoverable_clients == 0) {
2237 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2243 /* sampled unlocked, but really... */
2244 if (obd->obd_recovering == 0) {
2245 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2247 if (lprocfs_obd_snprintf(&page, size, &len,
2248 "recovery_start: %lu\n",
2249 obd->obd_recovery_start) <= 0)
2251 if (lprocfs_obd_snprintf(&page, size, &len,
2252 "recovery_duration: %lu\n",
2253 obd->obd_recovery_end -
2254 obd->obd_recovery_start) <= 0)
2256 /* Number of clients that have completed recovery */
2257 if (lprocfs_obd_snprintf(&page, size, &len,
2258 "completed_clients: %d/%d\n",
2259 obd->obd_max_recoverable_clients -
2260 obd->obd_stale_clients,
2261 obd->obd_max_recoverable_clients) <= 0)
2263 if (lprocfs_obd_snprintf(&page, size, &len,
2264 "replayed_requests: %d\n",
2265 obd->obd_replayed_requests) <= 0)
2267 if (lprocfs_obd_snprintf(&page, size, &len,
2268 "last_transno: "LPD64"\n",
2269 obd->obd_next_recovery_transno - 1)<=0)
2271 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2272 obd->obd_version_recov ? "ON" : "OFF")<=0)
2274 if (lprocfs_obd_snprintf(&page, size, &len, "IR: %s\n",
2275 obd->obd_no_ir ? "OFF" : "ON") <= 0)
2280 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2282 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2283 obd->obd_recovery_start) <= 0)
2285 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2286 cfs_time_current_sec() >= obd->obd_recovery_end ? 0 :
2287 obd->obd_recovery_end - cfs_time_current_sec()) <= 0)
2289 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2290 cfs_atomic_read(&obd->obd_connected_clients),
2291 obd->obd_max_recoverable_clients) <= 0)
2293 /* Number of clients that have completed recovery */
2294 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2295 cfs_atomic_read(&obd->obd_req_replay_clients))
2298 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2299 cfs_atomic_read(&obd->obd_lock_replay_clients))
2302 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2303 cfs_atomic_read(&obd->obd_connected_clients) -
2304 cfs_atomic_read(&obd->obd_lock_replay_clients))
2307 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2308 obd->obd_stale_clients) <= 0)
2310 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2311 obd->obd_replayed_requests) <= 0)
2313 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2314 obd->obd_requests_queued_for_recovery) <= 0)
2317 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2318 obd->obd_next_recovery_transno) <= 0)
2324 return min(count, len - (int)off);
2326 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2328 int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off,
2329 int count, int *eof, void *data)
2331 struct obd_device *obd = (struct obd_device *)data;
2332 LASSERT(obd != NULL);
2334 return snprintf(page, count, "%d\n",
2335 obd->obd_recovery_ir_factor);
2337 EXPORT_SYMBOL(lprocfs_obd_rd_ir_factor);
2339 int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer,
2340 unsigned long count, void *data)
2342 struct obd_device *obd = (struct obd_device *)data;
2344 LASSERT(obd != NULL);
2346 rc = lprocfs_write_helper(buffer, count, &val);
2350 if (val < OBD_IR_FACTOR_MIN || val > OBD_IR_FACTOR_MAX)
2353 obd->obd_recovery_ir_factor = val;
2356 EXPORT_SYMBOL(lprocfs_obd_wr_ir_factor);
2358 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2359 int count, int *eof, void *data)
2361 struct obd_device *obd = (struct obd_device *)data;
2362 LASSERT(obd != NULL);
2364 return snprintf(page, count, "%d\n",
2365 obd->obd_recovery_timeout);
2367 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2369 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2370 unsigned long count, void *data)
2372 struct obd_device *obd = (struct obd_device *)data;
2374 LASSERT(obd != NULL);
2376 rc = lprocfs_write_helper(buffer, count, &val);
2380 obd->obd_recovery_timeout = val;
2383 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2385 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2386 int count, int *eof, void *data)
2388 struct obd_device *obd = data;
2389 LASSERT(obd != NULL);
2391 return snprintf(page, count, "%u\n", obd->obd_recovery_time_hard);
2393 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2395 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2396 unsigned long count, void *data)
2398 struct obd_device *obd = data;
2400 LASSERT(obd != NULL);
2402 rc = lprocfs_write_helper(buffer, count, &val);
2406 obd->obd_recovery_time_hard = val;
2409 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2411 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2412 int count, int *eof, void *data)
2414 struct obd_device *obd = (struct obd_device *)data;
2416 LASSERT(obd != NULL);
2417 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2419 return snprintf(page, count, "%s\n",
2420 obd->u.obt.obt_vfsmnt->mnt_devname);
2422 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2424 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2425 int count, int *eof, void *data)
2427 struct obd_device *dev = data;
2428 struct client_obd *cli = &dev->u.cli;
2431 client_obd_list_lock(&cli->cl_loi_list_lock);
2432 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2433 client_obd_list_unlock(&cli->cl_loi_list_lock);
2436 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2438 int lprocfs_obd_wr_max_pages_per_rpc(struct file *file, const char *buffer,
2439 unsigned long count, void *data)
2441 struct obd_device *dev = data;
2442 struct client_obd *cli = &dev->u.cli;
2443 struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
2446 rc = lprocfs_write_helper(buffer, count, &val);
2450 LPROCFS_CLIMP_CHECK(dev);
2451 if (val < 1 || val > ocd->ocd_brw_size >> CFS_PAGE_SHIFT) {
2452 LPROCFS_CLIMP_EXIT(dev);
2455 client_obd_list_lock(&cli->cl_loi_list_lock);
2456 cli->cl_max_pages_per_rpc = val;
2457 client_obd_list_unlock(&cli->cl_loi_list_lock);
2459 LPROCFS_CLIMP_EXIT(dev);
2462 EXPORT_SYMBOL(lprocfs_obd_wr_max_pages_per_rpc);
2464 int lprocfs_target_rd_instance(char *page, char **start, off_t off,
2465 int count, int *eof, void *data)
2467 struct obd_device *obd = (struct obd_device *)data;
2468 struct obd_device_target *target = &obd->u.obt;
2470 LASSERT(obd != NULL);
2471 LASSERT(target->obt_magic == OBT_MAGIC);
2473 return snprintf(page, count, "%u\n", obd->u.obt.obt_instance);
2475 EXPORT_SYMBOL(lprocfs_target_rd_instance);
2477 EXPORT_SYMBOL(lprocfs_register);
2478 EXPORT_SYMBOL(lprocfs_srch);
2479 EXPORT_SYMBOL(lprocfs_remove);
2480 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2481 EXPORT_SYMBOL(lprocfs_add_vars);
2482 EXPORT_SYMBOL(lprocfs_obd_setup);
2483 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2484 EXPORT_SYMBOL(lprocfs_add_simple);
2485 EXPORT_SYMBOL(lprocfs_add_symlink);
2486 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2487 EXPORT_SYMBOL(lprocfs_alloc_stats);
2488 EXPORT_SYMBOL(lprocfs_free_stats);
2489 EXPORT_SYMBOL(lprocfs_clear_stats);
2490 EXPORT_SYMBOL(lprocfs_register_stats);
2491 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2492 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2493 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2494 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2495 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2496 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2497 EXPORT_SYMBOL(lprocfs_free_md_stats);
2498 EXPORT_SYMBOL(lprocfs_exp_setup);
2499 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2501 EXPORT_SYMBOL(lprocfs_rd_u64);
2502 EXPORT_SYMBOL(lprocfs_rd_atomic);
2503 EXPORT_SYMBOL(lprocfs_wr_atomic);
2504 EXPORT_SYMBOL(lprocfs_rd_uint);
2505 EXPORT_SYMBOL(lprocfs_wr_uint);
2506 EXPORT_SYMBOL(lprocfs_rd_uuid);
2507 EXPORT_SYMBOL(lprocfs_rd_name);
2508 EXPORT_SYMBOL(lprocfs_rd_fstype);
2509 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2510 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2511 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2512 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2513 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2514 EXPORT_SYMBOL(lprocfs_rd_import);
2515 EXPORT_SYMBOL(lprocfs_rd_state);
2516 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2517 EXPORT_SYMBOL(lprocfs_rd_blksize);
2518 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2519 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2520 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2521 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2522 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2524 EXPORT_SYMBOL(lprocfs_write_helper);
2525 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2526 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2527 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2528 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2529 EXPORT_SYMBOL(lprocfs_stats_collect);