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",
817 int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
822 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
824 ret += snprintf(page + ret, count - ret, "%s%s",
825 ret ? sep : "", obd_connect_names[i]);
827 if (flags & ~(mask - 1))
828 ret += snprintf(page + ret, count - ret,
829 "%sunknown flags "LPX64,
830 ret ? sep : "", flags & ~(mask - 1));
833 EXPORT_SYMBOL(obd_connect_flags2str);
835 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
836 int *eof, void *data)
838 struct lprocfs_counter ret;
839 struct obd_device *obd = (struct obd_device *)data;
840 struct obd_import *imp;
841 struct obd_import_conn *conn;
844 LASSERT(obd != NULL);
845 LPROCFS_CLIMP_CHECK(obd);
846 imp = obd->u.cli.cl_import;
849 i = snprintf(page, count,
858 ptlrpc_import_state_name(imp->imp_state),
859 imp->imp_connect_data.ocd_instance);
860 i += obd_connect_flags2str(page + i, count - i,
861 imp->imp_connect_data.ocd_connect_flags,
863 i += snprintf(page + i, count - i,
866 i += obd_import_flags2str(imp, page + i, count - i);
868 i += snprintf(page + i, count - i,
871 " failover_nids: [");
872 cfs_spin_lock(&imp->imp_lock);
874 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
875 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
876 libcfs_nid2str(conn->oic_conn->c_peer.nid));
879 cfs_spin_unlock(&imp->imp_lock);
880 i += snprintf(page + i, count - i,
882 " current_connection: %s\n"
883 " connection_attempts: %u\n"
885 " in-progress_invalidations: %u\n",
886 libcfs_nid2str(imp->imp_connection->c_peer.nid),
889 cfs_atomic_read(&imp->imp_inval_count));
891 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
892 if (ret.lc_count != 0) {
893 /* first argument to do_div MUST be __u64 */
894 __u64 sum = ret.lc_sum;
895 do_div(sum, ret.lc_count);
899 i += snprintf(page + i, count - i,
902 " unregistering: %u\n"
904 " avg_waittime: "LPU64" %s\n",
905 cfs_atomic_read(&imp->imp_inflight),
906 cfs_atomic_read(&imp->imp_unregistering),
907 cfs_atomic_read(&imp->imp_timeouts),
908 ret.lc_sum, ret.lc_units);
911 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
912 if (imp->imp_at.iat_portal[j] == 0)
914 k = max_t(unsigned int, k,
915 at_get(&imp->imp_at.iat_service_estimate[j]));
917 i += snprintf(page + i, count - i,
918 " service_estimates:\n"
919 " services: %u sec\n"
920 " network: %u sec\n",
922 at_get(&imp->imp_at.iat_net_latency));
924 i += snprintf(page + i, count - i,
926 " last_replay: "LPU64"\n"
927 " peer_committed: "LPU64"\n"
928 " last_checked: "LPU64"\n",
929 imp->imp_last_replay_transno,
930 imp->imp_peer_committed_transno,
931 imp->imp_last_transno_checked);
934 for (rw = 0; rw <= 1; rw++) {
935 lprocfs_stats_collect(obd->obd_svc_stats,
936 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
938 if (ret.lc_sum > 0 && ret.lc_count > 0) {
939 /* first argument to do_div MUST be __u64 */
940 __u64 sum = ret.lc_sum;
941 do_div(sum, ret.lc_count);
943 i += snprintf(page + i, count - i,
944 " %s_data_averages:\n"
945 " bytes_per_rpc: "LPU64"\n",
946 rw ? "write" : "read",
950 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
951 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
952 if (ret.lc_sum > 0 && ret.lc_count != 0) {
953 /* first argument to do_div MUST be __u64 */
954 __u64 sum = ret.lc_sum;
955 do_div(sum, ret.lc_count);
957 i += snprintf(page + i, count - i,
958 " %s_per_rpc: "LPU64"\n",
959 ret.lc_units, ret.lc_sum);
962 i += snprintf(page + i, count - i,
963 " MB_per_sec: %u.%.02u\n",
964 k / j, (100 * k / j) % 100);
968 LPROCFS_CLIMP_EXIT(obd);
972 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
973 int *eof, void *data)
975 struct obd_device *obd = (struct obd_device *)data;
976 struct obd_import *imp;
979 LASSERT(obd != NULL);
980 LPROCFS_CLIMP_CHECK(obd);
981 imp = obd->u.cli.cl_import;
984 i = snprintf(page, count, "current_state: %s\n",
985 ptlrpc_import_state_name(imp->imp_state));
986 i += snprintf(page + i, count - i,
988 k = imp->imp_state_hist_idx;
989 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
990 struct import_state_hist *ish =
991 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
992 if (ish->ish_state == 0)
994 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
996 ptlrpc_import_state_name(ish->ish_state));
999 LPROCFS_CLIMP_EXIT(obd);
1003 int lprocfs_at_hist_helper(char *page, int count, int rc,
1004 struct adaptive_timeout *at)
1007 for (i = 0; i < AT_BINS; i++)
1008 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1009 rc += snprintf(page + rc, count - rc, "\n");
1013 /* See also ptlrpc_lprocfs_rd_timeouts */
1014 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1015 int *eof, void *data)
1017 struct obd_device *obd = (struct obd_device *)data;
1018 struct obd_import *imp;
1019 unsigned int cur, worst;
1024 LASSERT(obd != NULL);
1025 LPROCFS_CLIMP_CHECK(obd);
1026 imp = obd->u.cli.cl_import;
1029 now = cfs_time_current_sec();
1031 /* Some network health info for kicks */
1032 s2dhms(&ts, now - imp->imp_last_reply_time);
1033 rc += snprintf(page + rc, count - rc,
1034 "%-10s : %ld, "DHMS_FMT" ago\n",
1035 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1037 cur = at_get(&imp->imp_at.iat_net_latency);
1038 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1039 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1040 s2dhms(&ts, now - worstt);
1041 rc += snprintf(page + rc, count - rc,
1042 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1043 "network", cur, worst, worstt, DHMS_VARS(&ts));
1044 rc = lprocfs_at_hist_helper(page, count, rc,
1045 &imp->imp_at.iat_net_latency);
1047 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1048 if (imp->imp_at.iat_portal[i] == 0)
1050 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1051 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1052 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1053 s2dhms(&ts, now - worstt);
1054 rc += snprintf(page + rc, count - rc,
1055 "portal %-2d : cur %3u worst %3u (at %ld, "
1056 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1057 cur, worst, worstt, DHMS_VARS(&ts));
1058 rc = lprocfs_at_hist_helper(page, count, rc,
1059 &imp->imp_at.iat_service_estimate[i]);
1062 LPROCFS_CLIMP_EXIT(obd);
1066 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1067 int count, int *eof, void *data)
1069 struct obd_device *obd = data;
1073 LPROCFS_CLIMP_CHECK(obd);
1074 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1075 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1076 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1077 ret += snprintf(page + ret, count - ret, "\n");
1078 LPROCFS_CLIMP_EXIT(obd);
1081 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1083 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1084 int *eof, void *data)
1086 struct obd_device *obd = data;
1088 LASSERT(obd != NULL);
1090 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1093 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1094 int *eof, void *data)
1096 struct obd_type *class = (struct obd_type*) data;
1098 LASSERT(class != NULL);
1100 return snprintf(page, count, "%d\n", class->typ_refcnt);
1103 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1107 LASSERT(obd != NULL);
1108 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1109 LASSERT(obd->obd_type->typ_procroot != NULL);
1111 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1112 obd->obd_type->typ_procroot,
1114 if (IS_ERR(obd->obd_proc_entry)) {
1115 rc = PTR_ERR(obd->obd_proc_entry);
1116 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1117 obd->obd_proc_entry = NULL;
1122 int lprocfs_obd_cleanup(struct obd_device *obd)
1126 if (obd->obd_proc_exports_entry) {
1127 /* Should be no exports left */
1128 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1129 lprocfs_remove(&obd->obd_proc_exports_entry);
1130 obd->obd_proc_exports_entry = NULL;
1132 if (obd->obd_proc_entry) {
1133 lprocfs_remove(&obd->obd_proc_entry);
1134 obd->obd_proc_entry = NULL;
1139 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1141 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1142 client_stat->nid_proc, client_stat->nid_stats,
1143 client_stat->nid_brw_stats);
1145 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1146 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1147 atomic_read(&client_stat->nid_exp_ref_count));
1149 if (client_stat->nid_proc)
1150 lprocfs_remove(&client_stat->nid_proc);
1152 if (client_stat->nid_stats)
1153 lprocfs_free_stats(&client_stat->nid_stats);
1155 if (client_stat->nid_brw_stats)
1156 OBD_FREE_PTR(client_stat->nid_brw_stats);
1158 if (client_stat->nid_ldlm_stats)
1159 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1161 OBD_FREE_PTR(client_stat);
1166 void lprocfs_free_per_client_stats(struct obd_device *obd)
1168 cfs_hash_t *hash = obd->obd_nid_stats_hash;
1169 struct nid_stat *stat;
1172 /* we need extra list - because hash_exit called to early */
1173 /* not need locking because all clients is died */
1174 while (!cfs_list_empty(&obd->obd_nid_stats)) {
1175 stat = cfs_list_entry(obd->obd_nid_stats.next,
1176 struct nid_stat, nid_list);
1177 cfs_list_del_init(&stat->nid_list);
1178 cfs_hash_del(hash, &stat->nid, &stat->nid_hash);
1179 lprocfs_free_client_stats(stat);
1184 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1185 enum lprocfs_stats_flags flags)
1187 struct lprocfs_stats *stats;
1188 unsigned int percpusize;
1190 unsigned int num_cpu;
1195 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1198 num_cpu = cfs_num_possible_cpus();
1200 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1204 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1205 stats->ls_flags = flags;
1206 cfs_spin_lock_init(&stats->ls_lock);
1207 /* Use this lock only if there are no percpu areas */
1209 stats->ls_flags = 0;
1212 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1214 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1216 for (i = 0; i < num_cpu; i++) {
1217 OBD_ALLOC(stats->ls_percpu[i], percpusize);
1218 if (stats->ls_percpu[i] == NULL) {
1219 for (j = 0; j < i; j++) {
1220 OBD_FREE(stats->ls_percpu[j], percpusize);
1221 stats->ls_percpu[j] = NULL;
1226 if (stats->ls_percpu[0] == NULL) {
1227 OBD_FREE(stats, offsetof(typeof(*stats),
1228 ls_percpu[num_cpu]));
1232 stats->ls_num = num;
1236 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1238 struct lprocfs_stats *stats = *statsh;
1239 unsigned int num_cpu;
1240 unsigned int percpusize;
1243 if (stats == NULL || stats->ls_num == 0)
1247 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1250 num_cpu = cfs_num_possible_cpus();
1252 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1254 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1255 for (i = 0; i < num_cpu; i++)
1256 OBD_FREE(stats->ls_percpu[i], percpusize);
1257 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1260 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1262 struct lprocfs_counter *percpu_cntr;
1264 unsigned int num_cpu;
1266 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1268 for (i = 0; i < num_cpu; i++) {
1269 for (j = 0; j < stats->ls_num; j++) {
1270 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1271 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1272 percpu_cntr->lc_count = 0;
1273 percpu_cntr->lc_sum = 0;
1274 percpu_cntr->lc_min = LC_MIN_INIT;
1275 percpu_cntr->lc_max = 0;
1276 percpu_cntr->lc_sumsquare = 0;
1277 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1281 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1284 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1285 size_t len, loff_t *off)
1287 struct seq_file *seq = file->private_data;
1288 struct lprocfs_stats *stats = seq->private;
1290 lprocfs_clear_stats(stats);
1295 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1297 struct lprocfs_stats *stats = p->private;
1298 /* return 1st cpu location */
1299 return (*pos >= stats->ls_num) ? NULL :
1300 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1303 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1307 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1309 struct lprocfs_stats *stats = p->private;
1311 return (*pos >= stats->ls_num) ? NULL :
1312 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1315 /* seq file export of one lprocfs counter */
1316 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1318 struct lprocfs_stats *stats = p->private;
1319 struct lprocfs_counter *cntr = v;
1320 struct lprocfs_counter ret;
1323 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1325 cfs_gettimeofday(&now);
1326 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1327 "snapshot_time", now.tv_sec, now.tv_usec);
1331 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1333 lprocfs_stats_collect(stats, idx, &ret);
1335 if (ret.lc_count == 0)
1338 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1339 ret.lc_count, cntr->lc_units);
1344 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1345 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1346 ret.lc_min, ret.lc_max, ret.lc_sum);
1349 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1350 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1354 rc = seq_printf(p, "\n");
1356 return (rc < 0) ? rc : 0;
1359 struct seq_operations lprocfs_stats_seq_sops = {
1360 start: lprocfs_stats_seq_start,
1361 stop: lprocfs_stats_seq_stop,
1362 next: lprocfs_stats_seq_next,
1363 show: lprocfs_stats_seq_show,
1366 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1368 struct proc_dir_entry *dp = PDE(inode);
1369 struct seq_file *seq;
1372 if (LPROCFS_ENTRY_AND_CHECK(dp))
1375 rc = seq_open(file, &lprocfs_stats_seq_sops);
1380 seq = file->private_data;
1381 seq->private = dp->data;
1385 struct file_operations lprocfs_stats_seq_fops = {
1386 .owner = THIS_MODULE,
1387 .open = lprocfs_stats_seq_open,
1389 .write = lprocfs_stats_seq_write,
1390 .llseek = seq_lseek,
1391 .release = lprocfs_seq_release,
1394 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1395 struct lprocfs_stats *stats)
1397 struct proc_dir_entry *entry;
1398 LASSERT(root != NULL);
1400 LPROCFS_WRITE_ENTRY();
1401 entry = create_proc_entry(name, 0644, root);
1403 entry->proc_fops = &lprocfs_stats_seq_fops;
1404 entry->data = stats;
1407 LPROCFS_WRITE_EXIT();
1415 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1416 unsigned conf, const char *name, const char *units)
1418 struct lprocfs_counter *c;
1420 unsigned int num_cpu;
1422 LASSERT(stats != NULL);
1424 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1426 for (i = 0; i < num_cpu; i++) {
1427 c = &(stats->ls_percpu[i]->lp_cntr[index]);
1428 c->lc_config = conf;
1431 c->lc_min = LC_MIN_INIT;
1434 c->lc_units = units;
1437 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1439 EXPORT_SYMBOL(lprocfs_counter_init);
1441 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1443 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1444 LASSERT(coffset < stats->ls_num); \
1445 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1448 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1450 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1451 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1452 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1453 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1454 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1455 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1456 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1457 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1458 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1459 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1460 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1461 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1462 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1463 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1467 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1468 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1469 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1470 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1471 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1472 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1473 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1474 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1475 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1476 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1477 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1478 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1479 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1480 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1481 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1482 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1483 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1484 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1485 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1486 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1487 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1488 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1489 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1490 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1491 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1492 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1493 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1494 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1495 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1496 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1497 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1498 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1499 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1500 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1501 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1502 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1503 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1504 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1505 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1506 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1507 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1508 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1509 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1510 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1511 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1512 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1513 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1514 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1515 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1516 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1517 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1518 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1521 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1523 struct lprocfs_stats *stats;
1524 unsigned int num_stats;
1527 LASSERT(obd->obd_stats == NULL);
1528 LASSERT(obd->obd_proc_entry != NULL);
1529 LASSERT(obd->obd_cntr_base == 0);
1531 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1532 num_private_stats - 1 /* o_owner */;
1533 stats = lprocfs_alloc_stats(num_stats, 0);
1537 lprocfs_init_ops_stats(num_private_stats, stats);
1539 for (i = num_private_stats; i < num_stats; i++) {
1540 /* If this LBUGs, it is likely that an obd
1541 * operation was added to struct obd_ops in
1542 * <obd.h>, and that the corresponding line item
1543 * LPROCFS_OBD_OP_INIT(.., .., opname)
1544 * is missing from the list above. */
1545 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1546 "Missing obd_stat initializer obd_op "
1547 "operation at offset %d.\n", i - num_private_stats);
1549 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1551 lprocfs_free_stats(&stats);
1553 obd->obd_stats = stats;
1554 obd->obd_cntr_base = num_private_stats;
1559 void lprocfs_free_obd_stats(struct obd_device *obd)
1562 lprocfs_free_stats(&obd->obd_stats);
1565 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1567 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1568 LASSERT(coffset < stats->ls_num); \
1569 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1572 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1574 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1575 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1576 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1577 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1578 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1579 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1580 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1581 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1582 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1583 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1584 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1585 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1586 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1587 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1588 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1589 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1590 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1591 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1592 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1593 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1594 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1595 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1596 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1597 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1598 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1599 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1600 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1601 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1602 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1603 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1604 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1605 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1608 int lprocfs_alloc_md_stats(struct obd_device *obd,
1609 unsigned num_private_stats)
1611 struct lprocfs_stats *stats;
1612 unsigned int num_stats;
1615 LASSERT(obd->md_stats == NULL);
1616 LASSERT(obd->obd_proc_entry != NULL);
1617 LASSERT(obd->md_cntr_base == 0);
1619 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1621 stats = lprocfs_alloc_stats(num_stats, 0);
1625 lprocfs_init_mps_stats(num_private_stats, stats);
1627 for (i = num_private_stats; i < num_stats; i++) {
1628 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1629 CERROR("Missing md_stat initializer md_op "
1630 "operation at offset %d. Aborting.\n",
1631 i - num_private_stats);
1635 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1637 lprocfs_free_stats(&stats);
1639 obd->md_stats = stats;
1640 obd->md_cntr_base = num_private_stats;
1645 void lprocfs_free_md_stats(struct obd_device *obd)
1647 struct lprocfs_stats *stats = obd->md_stats;
1649 if (stats != NULL) {
1650 obd->md_stats = NULL;
1651 obd->md_cntr_base = 0;
1652 lprocfs_free_stats(&stats);
1656 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1658 lprocfs_counter_init(ldlm_stats,
1659 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1660 0, "ldlm_enqueue", "reqs");
1661 lprocfs_counter_init(ldlm_stats,
1662 LDLM_CONVERT - LDLM_FIRST_OPC,
1663 0, "ldlm_convert", "reqs");
1664 lprocfs_counter_init(ldlm_stats,
1665 LDLM_CANCEL - LDLM_FIRST_OPC,
1666 0, "ldlm_cancel", "reqs");
1667 lprocfs_counter_init(ldlm_stats,
1668 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1669 0, "ldlm_bl_callback", "reqs");
1670 lprocfs_counter_init(ldlm_stats,
1671 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1672 0, "ldlm_cp_callback", "reqs");
1673 lprocfs_counter_init(ldlm_stats,
1674 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1675 0, "ldlm_gl_callback", "reqs");
1678 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1679 int *eof, void *data)
1681 struct obd_export *exp = data;
1682 LASSERT(exp != NULL);
1684 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1687 struct exp_uuid_cb_data {
1695 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1696 int count, int *eof, int *len)
1698 cb_data->page = page;
1699 cb_data->count = count;
1704 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1705 cfs_hlist_node_t *hnode, void *cb_data)
1708 struct obd_export *exp = cfs_hash_object(hs, hnode);
1709 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1711 if (exp->exp_nid_stats)
1712 *data->len += snprintf((data->page + *data->len),
1713 data->count, "%s\n",
1714 obd_uuid2str(&exp->exp_client_uuid));
1718 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1719 int *eof, void *data)
1721 struct nid_stat *stats = (struct nid_stat *)data;
1722 struct exp_uuid_cb_data cb_data;
1723 struct obd_device *obd = stats->nid_obd;
1728 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1729 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1730 lprocfs_exp_print_uuid, &cb_data);
1731 return (*cb_data.len);
1734 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1735 cfs_hlist_node_t *hnode, void *cb_data)
1738 struct exp_uuid_cb_data *data = cb_data;
1739 struct obd_export *exp = cfs_hash_object(hs, hnode);
1741 if (exp->exp_lock_hash != NULL) {
1743 *data->len += cfs_hash_debug_header(data->page,
1746 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1753 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1754 int *eof, void *data)
1756 struct nid_stat *stats = (struct nid_stat *)data;
1757 struct exp_uuid_cb_data cb_data;
1758 struct obd_device *obd = stats->nid_obd;
1763 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1765 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1766 lprocfs_exp_print_hash, &cb_data);
1767 return (*cb_data.len);
1770 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1771 int count, int *eof, void *data)
1774 return snprintf(page, count, "%s\n",
1775 "Write into this file to clear all nid stats and "
1776 "stale nid entries");
1778 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1780 static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1782 struct nid_stat *stat = obj;
1786 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1787 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1788 /* object has only hash references. */
1789 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1790 cfs_list_move(&stat->nid_list, data);
1791 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1794 /* we has reference to object - only clear data*/
1795 if (stat->nid_stats)
1796 lprocfs_clear_stats(stat->nid_stats);
1798 if (stat->nid_brw_stats) {
1799 for (i = 0; i < BRW_LAST; i++)
1800 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1805 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1806 unsigned long count, void *data)
1808 struct obd_device *obd = (struct obd_device *)data;
1809 struct nid_stat *client_stat;
1810 CFS_LIST_HEAD(free_list);
1812 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1813 lprocfs_nid_stats_clear_write_cb, &free_list);
1815 while (!cfs_list_empty(&free_list)) {
1816 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1818 cfs_list_del_init(&client_stat->nid_list);
1819 lprocfs_free_client_stats(client_stat);
1824 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1826 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1828 struct nid_stat *new_stat, *old_stat;
1829 struct obd_device *obd = NULL;
1830 cfs_proc_dir_entry_t *entry;
1831 char *buffer = NULL;
1837 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1838 !exp->exp_obd->obd_nid_stats_hash)
1841 /* not test against zero because eric say:
1842 * You may only test nid against another nid, or LNET_NID_ANY.
1843 * Anything else is nonsense.*/
1844 if (!nid || *nid == LNET_NID_ANY)
1849 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1851 OBD_ALLOC_PTR(new_stat);
1852 if (new_stat == NULL)
1855 new_stat->nid = *nid;
1856 new_stat->nid_obd = exp->exp_obd;
1857 /* we need set default refcount to 1 to balance obd_disconnect */
1858 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1860 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1861 nid, &new_stat->nid_hash);
1862 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1863 old_stat, libcfs_nid2str(*nid),
1864 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1866 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1867 * been and will never be called. */
1868 if (exp->exp_nid_stats) {
1869 nidstat_putref(exp->exp_nid_stats);
1870 exp->exp_nid_stats = NULL;
1873 /* Return -EALREADY here so that we know that the /proc
1874 * entry already has been created */
1875 if (old_stat != new_stat) {
1876 exp->exp_nid_stats = old_stat;
1877 GOTO(destroy_new, rc = -EALREADY);
1879 /* not found - create */
1880 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1882 GOTO(destroy_new, rc = -ENOMEM);
1884 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1885 new_stat->nid_proc = lprocfs_register(buffer,
1886 obd->obd_proc_exports_entry,
1888 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1890 if (new_stat->nid_proc == NULL) {
1891 CERROR("Error making export directory for nid %s\n",
1892 libcfs_nid2str(*nid));
1893 GOTO(destroy_new_ns, rc = -ENOMEM);
1896 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1897 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1898 if (IS_ERR(entry)) {
1899 CWARN("Error adding the NID stats file\n");
1900 rc = PTR_ERR(entry);
1901 GOTO(destroy_new_ns, rc);
1904 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1905 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1906 if (IS_ERR(entry)) {
1907 CWARN("Error adding the hash file\n");
1908 rc = PTR_ERR(entry);
1909 GOTO(destroy_new_ns, rc);
1912 exp->exp_nid_stats = new_stat;
1914 /* protect competitive add to list, not need locking on destroy */
1915 cfs_spin_lock(&obd->obd_nid_lock);
1916 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1917 cfs_spin_unlock(&obd->obd_nid_lock);
1922 if (new_stat->nid_proc != NULL)
1923 lprocfs_remove(&new_stat->nid_proc);
1924 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1927 nidstat_putref(new_stat);
1928 OBD_FREE_PTR(new_stat);
1932 int lprocfs_exp_cleanup(struct obd_export *exp)
1934 struct nid_stat *stat = exp->exp_nid_stats;
1936 if(!stat || !exp->exp_obd)
1939 nidstat_putref(exp->exp_nid_stats);
1940 exp->exp_nid_stats = NULL;
1945 int lprocfs_write_helper(const char *buffer, unsigned long count,
1948 return lprocfs_write_frac_helper(buffer, count, val, 1);
1951 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1954 char kernbuf[20], *end, *pbuf;
1956 if (count > (sizeof(kernbuf) - 1))
1959 if (cfs_copy_from_user(kernbuf, buffer, count))
1962 kernbuf[count] = '\0';
1969 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1973 if (end != NULL && *end == '.') {
1974 int temp_val, pow = 1;
1978 if (strlen(pbuf) > 5)
1979 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1981 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1984 for (i = 0; i < (end - pbuf); i++)
1987 *val += temp_val / pow;
1993 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
1996 long decimal_val, frac_val;
2002 decimal_val = val / mult;
2003 prtn = snprintf(buffer, count, "%ld", decimal_val);
2004 frac_val = val % mult;
2006 if (prtn < (count - 4) && frac_val > 0) {
2008 int i, temp_mult = 1, frac_bits = 0;
2010 temp_frac = frac_val * 10;
2011 buffer[prtn++] = '.';
2012 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2013 /* only reserved 2 bits fraction */
2014 buffer[prtn++] ='0';
2019 * Need to think these cases :
2020 * 1. #echo x.00 > /proc/xxx output result : x
2021 * 2. #echo x.0x > /proc/xxx output result : x.0x
2022 * 3. #echo x.x0 > /proc/xxx output result : x.x
2023 * 4. #echo x.xx > /proc/xxx output result : x.xx
2024 * Only reserved 2 bits fraction.
2026 for (i = 0; i < (5 - prtn); i++)
2029 frac_bits = min((int)count - prtn, 3 - frac_bits);
2030 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2031 frac_val * temp_mult / mult);
2034 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2036 if (buffer[prtn] == '.') {
2043 buffer[prtn++] ='\n';
2047 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2049 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2052 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2053 __u64 *val, int mult)
2055 char kernbuf[22], *end, *pbuf;
2056 __u64 whole, frac = 0, units;
2057 unsigned frac_d = 1;
2059 if (count > (sizeof(kernbuf) - 1))
2062 if (cfs_copy_from_user(kernbuf, buffer, count))
2065 kernbuf[count] = '\0';
2072 whole = simple_strtoull(pbuf, &end, 10);
2076 if (end != NULL && *end == '.') {
2080 /* need to limit frac_d to a __u32 */
2081 if (strlen(pbuf) > 10)
2084 frac = simple_strtoull(pbuf, &end, 10);
2085 /* count decimal places */
2086 for (i = 0; i < (end - pbuf); i++)
2103 /* Specified units override the multiplier */
2105 mult = mult < 0 ? -units : units;
2108 do_div(frac, frac_d);
2109 *val = whole * mult + frac;
2113 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2114 struct file_operations *seq_fops, void *data)
2116 struct proc_dir_entry *entry;
2119 LPROCFS_WRITE_ENTRY();
2120 entry = create_proc_entry(name, mode, parent);
2122 entry->proc_fops = seq_fops;
2125 LPROCFS_WRITE_EXIT();
2132 EXPORT_SYMBOL(lprocfs_seq_create);
2134 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2136 struct file_operations *seq_fops,
2139 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2140 mode, seq_fops, data));
2142 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2144 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2146 if (value >= OBD_HIST_MAX)
2147 value = OBD_HIST_MAX - 1;
2149 cfs_spin_lock(&oh->oh_lock);
2150 oh->oh_buckets[value]++;
2151 cfs_spin_unlock(&oh->oh_lock);
2153 EXPORT_SYMBOL(lprocfs_oh_tally);
2155 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2159 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2162 lprocfs_oh_tally(oh, val);
2164 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2166 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2168 unsigned long ret = 0;
2171 for (i = 0; i < OBD_HIST_MAX; i++)
2172 ret += oh->oh_buckets[i];
2175 EXPORT_SYMBOL(lprocfs_oh_sum);
2177 void lprocfs_oh_clear(struct obd_histogram *oh)
2179 cfs_spin_lock(&oh->oh_lock);
2180 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2181 cfs_spin_unlock(&oh->oh_lock);
2183 EXPORT_SYMBOL(lprocfs_oh_clear);
2185 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2186 int count, int *eof, void *data)
2188 struct obd_device *obd = data;
2194 c += cfs_hash_debug_header(page, count);
2195 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2196 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2197 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2198 #ifdef HAVE_QUOTA_SUPPORT
2199 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2200 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2201 page + c, count - c);
2206 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2208 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2209 int count, int *eof, void *data)
2211 struct obd_device *obd = data;
2214 LASSERT(obd != NULL);
2215 LASSERT(count >= 0);
2217 /* Set start of user data returned to
2218 page + off since the user may have
2219 requested to read much smaller than
2220 what we need to read */
2221 *start = page + off;
2223 /* We know we are allocated a page here.
2224 Also we know that this function will
2225 not need to write more than a page
2226 so we can truncate at CFS_PAGE_SIZE. */
2227 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2229 /* Initialize the page */
2230 memset(page, 0, size);
2232 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2234 if (obd->obd_max_recoverable_clients == 0) {
2235 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2241 /* sampled unlocked, but really... */
2242 if (obd->obd_recovering == 0) {
2243 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2245 if (lprocfs_obd_snprintf(&page, size, &len,
2246 "recovery_start: %lu\n",
2247 obd->obd_recovery_start) <= 0)
2249 if (lprocfs_obd_snprintf(&page, size, &len,
2250 "recovery_duration: %lu\n",
2251 obd->obd_recovery_end -
2252 obd->obd_recovery_start) <= 0)
2254 /* Number of clients that have completed recovery */
2255 if (lprocfs_obd_snprintf(&page, size, &len,
2256 "completed_clients: %d/%d\n",
2257 obd->obd_max_recoverable_clients -
2258 obd->obd_stale_clients,
2259 obd->obd_max_recoverable_clients) <= 0)
2261 if (lprocfs_obd_snprintf(&page, size, &len,
2262 "replayed_requests: %d\n",
2263 obd->obd_replayed_requests) <= 0)
2265 if (lprocfs_obd_snprintf(&page, size, &len,
2266 "last_transno: "LPD64"\n",
2267 obd->obd_next_recovery_transno - 1)<=0)
2269 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2270 obd->obd_version_recov ? "ON" : "OFF")<=0)
2272 if (lprocfs_obd_snprintf(&page, size, &len, "IR: %s\n",
2273 obd->obd_no_ir ? "OFF" : "ON") <= 0)
2278 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2280 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2281 obd->obd_recovery_start) <= 0)
2283 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2284 cfs_time_current_sec() >= obd->obd_recovery_end ? 0 :
2285 obd->obd_recovery_end - cfs_time_current_sec()) <= 0)
2287 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2288 cfs_atomic_read(&obd->obd_connected_clients),
2289 obd->obd_max_recoverable_clients) <= 0)
2291 /* Number of clients that have completed recovery */
2292 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2293 cfs_atomic_read(&obd->obd_req_replay_clients))
2296 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2297 cfs_atomic_read(&obd->obd_lock_replay_clients))
2300 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2301 cfs_atomic_read(&obd->obd_connected_clients) -
2302 cfs_atomic_read(&obd->obd_lock_replay_clients))
2305 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2306 obd->obd_stale_clients) <= 0)
2308 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2309 obd->obd_replayed_requests) <= 0)
2311 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2312 obd->obd_requests_queued_for_recovery) <= 0)
2315 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2316 obd->obd_next_recovery_transno) <= 0)
2322 return min(count, len - (int)off);
2324 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2326 int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off,
2327 int count, int *eof, void *data)
2329 struct obd_device *obd = (struct obd_device *)data;
2330 LASSERT(obd != NULL);
2332 return snprintf(page, count, "%d\n",
2333 obd->obd_recovery_ir_factor);
2335 EXPORT_SYMBOL(lprocfs_obd_rd_ir_factor);
2337 int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer,
2338 unsigned long count, void *data)
2340 struct obd_device *obd = (struct obd_device *)data;
2342 LASSERT(obd != NULL);
2344 rc = lprocfs_write_helper(buffer, count, &val);
2348 if (val < OBD_IR_FACTOR_MIN || val > OBD_IR_FACTOR_MAX)
2351 obd->obd_recovery_ir_factor = val;
2354 EXPORT_SYMBOL(lprocfs_obd_wr_ir_factor);
2356 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2357 int count, int *eof, void *data)
2359 struct obd_device *obd = (struct obd_device *)data;
2360 LASSERT(obd != NULL);
2362 return snprintf(page, count, "%d\n",
2363 obd->obd_recovery_timeout);
2365 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2367 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2368 unsigned long count, void *data)
2370 struct obd_device *obd = (struct obd_device *)data;
2372 LASSERT(obd != NULL);
2374 rc = lprocfs_write_helper(buffer, count, &val);
2378 obd->obd_recovery_timeout = val;
2381 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2383 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2384 int count, int *eof, void *data)
2386 struct obd_device *obd = data;
2387 LASSERT(obd != NULL);
2389 return snprintf(page, count, "%u\n", obd->obd_recovery_time_hard);
2391 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2393 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2394 unsigned long count, void *data)
2396 struct obd_device *obd = data;
2398 LASSERT(obd != NULL);
2400 rc = lprocfs_write_helper(buffer, count, &val);
2404 obd->obd_recovery_time_hard = val;
2407 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2409 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2410 int count, int *eof, void *data)
2412 struct obd_device *obd = (struct obd_device *)data;
2414 LASSERT(obd != NULL);
2415 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2417 return snprintf(page, count, "%s\n",
2418 obd->u.obt.obt_vfsmnt->mnt_devname);
2420 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2422 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2423 int count, int *eof, void *data)
2425 struct obd_device *dev = data;
2426 struct client_obd *cli = &dev->u.cli;
2429 client_obd_list_lock(&cli->cl_loi_list_lock);
2430 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2431 client_obd_list_unlock(&cli->cl_loi_list_lock);
2434 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2436 int lprocfs_obd_wr_max_pages_per_rpc(struct file *file, const char *buffer,
2437 unsigned long count, void *data)
2439 struct obd_device *dev = data;
2440 struct client_obd *cli = &dev->u.cli;
2441 struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
2444 rc = lprocfs_write_helper(buffer, count, &val);
2448 LPROCFS_CLIMP_CHECK(dev);
2449 if (val < 1 || val > ocd->ocd_brw_size >> CFS_PAGE_SHIFT) {
2450 LPROCFS_CLIMP_EXIT(dev);
2453 client_obd_list_lock(&cli->cl_loi_list_lock);
2454 cli->cl_max_pages_per_rpc = val;
2455 client_obd_list_unlock(&cli->cl_loi_list_lock);
2457 LPROCFS_CLIMP_EXIT(dev);
2460 EXPORT_SYMBOL(lprocfs_obd_wr_max_pages_per_rpc);
2462 int lprocfs_target_rd_instance(char *page, char **start, off_t off,
2463 int count, int *eof, void *data)
2465 struct obd_device *obd = (struct obd_device *)data;
2466 struct obd_device_target *target = &obd->u.obt;
2468 LASSERT(obd != NULL);
2469 LASSERT(target->obt_magic == OBT_MAGIC);
2471 return snprintf(page, count, "%u\n", obd->u.obt.obt_instance);
2473 EXPORT_SYMBOL(lprocfs_target_rd_instance);
2475 EXPORT_SYMBOL(lprocfs_register);
2476 EXPORT_SYMBOL(lprocfs_srch);
2477 EXPORT_SYMBOL(lprocfs_remove);
2478 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2479 EXPORT_SYMBOL(lprocfs_add_vars);
2480 EXPORT_SYMBOL(lprocfs_obd_setup);
2481 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2482 EXPORT_SYMBOL(lprocfs_add_simple);
2483 EXPORT_SYMBOL(lprocfs_add_symlink);
2484 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2485 EXPORT_SYMBOL(lprocfs_alloc_stats);
2486 EXPORT_SYMBOL(lprocfs_free_stats);
2487 EXPORT_SYMBOL(lprocfs_clear_stats);
2488 EXPORT_SYMBOL(lprocfs_register_stats);
2489 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2490 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2491 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2492 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2493 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2494 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2495 EXPORT_SYMBOL(lprocfs_free_md_stats);
2496 EXPORT_SYMBOL(lprocfs_exp_setup);
2497 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2499 EXPORT_SYMBOL(lprocfs_rd_u64);
2500 EXPORT_SYMBOL(lprocfs_rd_atomic);
2501 EXPORT_SYMBOL(lprocfs_wr_atomic);
2502 EXPORT_SYMBOL(lprocfs_rd_uint);
2503 EXPORT_SYMBOL(lprocfs_wr_uint);
2504 EXPORT_SYMBOL(lprocfs_rd_uuid);
2505 EXPORT_SYMBOL(lprocfs_rd_name);
2506 EXPORT_SYMBOL(lprocfs_rd_fstype);
2507 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2508 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2509 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2510 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2511 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2512 EXPORT_SYMBOL(lprocfs_rd_import);
2513 EXPORT_SYMBOL(lprocfs_rd_state);
2514 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2515 EXPORT_SYMBOL(lprocfs_rd_blksize);
2516 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2517 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2518 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2519 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2520 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2522 EXPORT_SYMBOL(lprocfs_write_helper);
2523 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2524 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2525 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2526 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2527 EXPORT_SYMBOL(lprocfs_stats_collect);