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",
815 static int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
820 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
822 ret += snprintf(page + ret, count - ret, "%s%s",
823 ret ? sep : "", obd_connect_names[i]);
825 if (flags & ~(mask - 1))
826 ret += snprintf(page + ret, count - ret,
827 "%sunknown flags "LPX64,
828 ret ? sep : "", flags & ~(mask - 1));
832 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
833 int *eof, void *data)
835 struct lprocfs_counter ret;
836 struct obd_device *obd = (struct obd_device *)data;
837 struct obd_import *imp;
838 struct obd_import_conn *conn;
841 LASSERT(obd != NULL);
842 LPROCFS_CLIMP_CHECK(obd);
843 imp = obd->u.cli.cl_import;
846 i = snprintf(page, count,
854 ptlrpc_import_state_name(imp->imp_state));
855 i += obd_connect_flags2str(page + i, count - i,
856 imp->imp_connect_data.ocd_connect_flags,
858 i += snprintf(page + i, count - i,
861 i += obd_import_flags2str(imp, page + i, count - i);
863 i += snprintf(page + i, count - i,
866 " failover_nids: [");
867 cfs_spin_lock(&imp->imp_lock);
869 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
870 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
871 libcfs_nid2str(conn->oic_conn->c_peer.nid));
874 cfs_spin_unlock(&imp->imp_lock);
875 i += snprintf(page + i, count - i,
877 " current_connection: %s\n"
878 " connection_attempts: %u\n"
880 " in-progress_invalidations: %u\n",
881 libcfs_nid2str(imp->imp_connection->c_peer.nid),
884 cfs_atomic_read(&imp->imp_inval_count));
886 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
887 if (ret.lc_count != 0) {
888 /* first argument to do_div MUST be __u64 */
889 __u64 sum = ret.lc_sum;
890 do_div(sum, ret.lc_count);
894 i += snprintf(page + i, count - i,
897 " unregistering: %u\n"
899 " avg_waittime: "LPU64" %s\n",
900 cfs_atomic_read(&imp->imp_inflight),
901 cfs_atomic_read(&imp->imp_unregistering),
902 cfs_atomic_read(&imp->imp_timeouts),
903 ret.lc_sum, ret.lc_units);
906 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
907 if (imp->imp_at.iat_portal[j] == 0)
909 k = max_t(unsigned int, k,
910 at_get(&imp->imp_at.iat_service_estimate[j]));
912 i += snprintf(page + i, count - i,
913 " service_estimates:\n"
914 " services: %u sec\n"
915 " network: %u sec\n",
917 at_get(&imp->imp_at.iat_net_latency));
919 i += snprintf(page + i, count - i,
921 " last_replay: "LPU64"\n"
922 " peer_committed: "LPU64"\n"
923 " last_checked: "LPU64"\n",
924 imp->imp_last_replay_transno,
925 imp->imp_peer_committed_transno,
926 imp->imp_last_transno_checked);
929 for (rw = 0; rw <= 1; rw++) {
930 lprocfs_stats_collect(obd->obd_svc_stats,
931 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
933 if (ret.lc_sum > 0 && ret.lc_count > 0) {
934 /* first argument to do_div MUST be __u64 */
935 __u64 sum = ret.lc_sum;
936 do_div(sum, ret.lc_count);
938 i += snprintf(page + i, count - i,
939 " %s_data_averages:\n"
940 " bytes_per_rpc: "LPU64"\n",
941 rw ? "write" : "read",
945 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
946 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
947 if (ret.lc_sum > 0 && ret.lc_count != 0) {
948 /* first argument to do_div MUST be __u64 */
949 __u64 sum = ret.lc_sum;
950 do_div(sum, ret.lc_count);
952 i += snprintf(page + i, count - i,
953 " %s_per_rpc: "LPU64"\n",
954 ret.lc_units, ret.lc_sum);
957 i += snprintf(page + i, count - i,
958 " MB_per_sec: %u.%.02u\n",
959 k / j, (100 * k / j) % 100);
963 LPROCFS_CLIMP_EXIT(obd);
967 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
968 int *eof, void *data)
970 struct obd_device *obd = (struct obd_device *)data;
971 struct obd_import *imp;
974 LASSERT(obd != NULL);
975 LPROCFS_CLIMP_CHECK(obd);
976 imp = obd->u.cli.cl_import;
979 i = snprintf(page, count, "current_state: %s\n",
980 ptlrpc_import_state_name(imp->imp_state));
981 i += snprintf(page + i, count - i,
983 k = imp->imp_state_hist_idx;
984 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
985 struct import_state_hist *ish =
986 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
987 if (ish->ish_state == 0)
989 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
991 ptlrpc_import_state_name(ish->ish_state));
994 LPROCFS_CLIMP_EXIT(obd);
998 int lprocfs_at_hist_helper(char *page, int count, int rc,
999 struct adaptive_timeout *at)
1002 for (i = 0; i < AT_BINS; i++)
1003 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1004 rc += snprintf(page + rc, count - rc, "\n");
1008 /* See also ptlrpc_lprocfs_rd_timeouts */
1009 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1010 int *eof, void *data)
1012 struct obd_device *obd = (struct obd_device *)data;
1013 struct obd_import *imp;
1014 unsigned int cur, worst;
1019 LASSERT(obd != NULL);
1020 LPROCFS_CLIMP_CHECK(obd);
1021 imp = obd->u.cli.cl_import;
1024 now = cfs_time_current_sec();
1026 /* Some network health info for kicks */
1027 s2dhms(&ts, now - imp->imp_last_reply_time);
1028 rc += snprintf(page + rc, count - rc,
1029 "%-10s : %ld, "DHMS_FMT" ago\n",
1030 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1032 cur = at_get(&imp->imp_at.iat_net_latency);
1033 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1034 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1035 s2dhms(&ts, now - worstt);
1036 rc += snprintf(page + rc, count - rc,
1037 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1038 "network", cur, worst, worstt, DHMS_VARS(&ts));
1039 rc = lprocfs_at_hist_helper(page, count, rc,
1040 &imp->imp_at.iat_net_latency);
1042 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1043 if (imp->imp_at.iat_portal[i] == 0)
1045 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1046 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1047 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1048 s2dhms(&ts, now - worstt);
1049 rc += snprintf(page + rc, count - rc,
1050 "portal %-2d : cur %3u worst %3u (at %ld, "
1051 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1052 cur, worst, worstt, DHMS_VARS(&ts));
1053 rc = lprocfs_at_hist_helper(page, count, rc,
1054 &imp->imp_at.iat_service_estimate[i]);
1057 LPROCFS_CLIMP_EXIT(obd);
1061 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1062 int count, int *eof, void *data)
1064 struct obd_device *obd = data;
1068 LPROCFS_CLIMP_CHECK(obd);
1069 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1070 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1071 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1072 ret += snprintf(page + ret, count - ret, "\n");
1073 LPROCFS_CLIMP_EXIT(obd);
1076 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1078 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1079 int *eof, void *data)
1081 struct obd_device *obd = data;
1083 LASSERT(obd != NULL);
1085 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1088 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1089 int *eof, void *data)
1091 struct obd_type *class = (struct obd_type*) data;
1093 LASSERT(class != NULL);
1095 return snprintf(page, count, "%d\n", class->typ_refcnt);
1098 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1102 LASSERT(obd != NULL);
1103 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1104 LASSERT(obd->obd_type->typ_procroot != NULL);
1106 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1107 obd->obd_type->typ_procroot,
1109 if (IS_ERR(obd->obd_proc_entry)) {
1110 rc = PTR_ERR(obd->obd_proc_entry);
1111 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1112 obd->obd_proc_entry = NULL;
1117 int lprocfs_obd_cleanup(struct obd_device *obd)
1121 if (obd->obd_proc_exports_entry) {
1122 /* Should be no exports left */
1123 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1124 lprocfs_remove(&obd->obd_proc_exports_entry);
1125 obd->obd_proc_exports_entry = NULL;
1127 if (obd->obd_proc_entry) {
1128 lprocfs_remove(&obd->obd_proc_entry);
1129 obd->obd_proc_entry = NULL;
1134 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1136 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1137 client_stat->nid_proc, client_stat->nid_stats,
1138 client_stat->nid_brw_stats);
1140 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1141 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1142 atomic_read(&client_stat->nid_exp_ref_count));
1144 cfs_hlist_del_init(&client_stat->nid_hash);
1146 if (client_stat->nid_proc)
1147 lprocfs_remove(&client_stat->nid_proc);
1149 if (client_stat->nid_stats)
1150 lprocfs_free_stats(&client_stat->nid_stats);
1152 if (client_stat->nid_brw_stats)
1153 OBD_FREE_PTR(client_stat->nid_brw_stats);
1155 if (client_stat->nid_ldlm_stats)
1156 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1158 OBD_FREE_PTR(client_stat);
1163 void lprocfs_free_per_client_stats(struct obd_device *obd)
1165 struct nid_stat *stat;
1168 /* we need extra list - because hash_exit called to early */
1169 /* not need locking because all clients is died */
1170 while(!cfs_list_empty(&obd->obd_nid_stats)) {
1171 stat = cfs_list_entry(obd->obd_nid_stats.next,
1172 struct nid_stat, nid_list);
1173 cfs_list_del_init(&stat->nid_list);
1174 lprocfs_free_client_stats(stat);
1180 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1181 enum lprocfs_stats_flags flags)
1183 struct lprocfs_stats *stats;
1184 unsigned int percpusize;
1186 unsigned int num_cpu;
1191 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1194 num_cpu = cfs_num_possible_cpus();
1196 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1200 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1201 stats->ls_flags = flags;
1202 cfs_spin_lock_init(&stats->ls_lock);
1203 /* Use this lock only if there are no percpu areas */
1205 stats->ls_flags = 0;
1208 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1210 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1212 for (i = 0; i < num_cpu; i++) {
1213 OBD_ALLOC(stats->ls_percpu[i], percpusize);
1214 if (stats->ls_percpu[i] == NULL) {
1215 for (j = 0; j < i; j++) {
1216 OBD_FREE(stats->ls_percpu[j], percpusize);
1217 stats->ls_percpu[j] = NULL;
1222 if (stats->ls_percpu[0] == NULL) {
1223 OBD_FREE(stats, offsetof(typeof(*stats),
1224 ls_percpu[num_cpu]));
1228 stats->ls_num = num;
1232 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1234 struct lprocfs_stats *stats = *statsh;
1235 unsigned int num_cpu;
1236 unsigned int percpusize;
1239 if (stats == NULL || stats->ls_num == 0)
1243 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1246 num_cpu = cfs_num_possible_cpus();
1248 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1250 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1251 for (i = 0; i < num_cpu; i++)
1252 OBD_FREE(stats->ls_percpu[i], percpusize);
1253 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1256 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1258 struct lprocfs_counter *percpu_cntr;
1260 unsigned int num_cpu;
1262 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1264 for (i = 0; i < num_cpu; i++) {
1265 for (j = 0; j < stats->ls_num; j++) {
1266 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1267 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1268 percpu_cntr->lc_count = 0;
1269 percpu_cntr->lc_sum = 0;
1270 percpu_cntr->lc_min = LC_MIN_INIT;
1271 percpu_cntr->lc_max = 0;
1272 percpu_cntr->lc_sumsquare = 0;
1273 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1277 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1280 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1281 size_t len, loff_t *off)
1283 struct seq_file *seq = file->private_data;
1284 struct lprocfs_stats *stats = seq->private;
1286 lprocfs_clear_stats(stats);
1291 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1293 struct lprocfs_stats *stats = p->private;
1294 /* return 1st cpu location */
1295 return (*pos >= stats->ls_num) ? NULL :
1296 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1299 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1303 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1305 struct lprocfs_stats *stats = p->private;
1307 return (*pos >= stats->ls_num) ? NULL :
1308 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1311 /* seq file export of one lprocfs counter */
1312 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1314 struct lprocfs_stats *stats = p->private;
1315 struct lprocfs_counter *cntr = v;
1316 struct lprocfs_counter ret;
1319 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1321 cfs_gettimeofday(&now);
1322 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1323 "snapshot_time", now.tv_sec, now.tv_usec);
1327 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1329 lprocfs_stats_collect(stats, idx, &ret);
1331 if (ret.lc_count == 0)
1334 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1335 ret.lc_count, cntr->lc_units);
1340 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1341 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1342 ret.lc_min, ret.lc_max, ret.lc_sum);
1345 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1346 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1350 rc = seq_printf(p, "\n");
1352 return (rc < 0) ? rc : 0;
1355 struct seq_operations lprocfs_stats_seq_sops = {
1356 start: lprocfs_stats_seq_start,
1357 stop: lprocfs_stats_seq_stop,
1358 next: lprocfs_stats_seq_next,
1359 show: lprocfs_stats_seq_show,
1362 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1364 struct proc_dir_entry *dp = PDE(inode);
1365 struct seq_file *seq;
1368 if (LPROCFS_ENTRY_AND_CHECK(dp))
1371 rc = seq_open(file, &lprocfs_stats_seq_sops);
1376 seq = file->private_data;
1377 seq->private = dp->data;
1381 struct file_operations lprocfs_stats_seq_fops = {
1382 .owner = THIS_MODULE,
1383 .open = lprocfs_stats_seq_open,
1385 .write = lprocfs_stats_seq_write,
1386 .llseek = seq_lseek,
1387 .release = lprocfs_seq_release,
1390 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1391 struct lprocfs_stats *stats)
1393 struct proc_dir_entry *entry;
1394 LASSERT(root != NULL);
1396 LPROCFS_WRITE_ENTRY();
1397 entry = create_proc_entry(name, 0644, root);
1399 entry->proc_fops = &lprocfs_stats_seq_fops;
1400 entry->data = stats;
1403 LPROCFS_WRITE_EXIT();
1411 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1412 unsigned conf, const char *name, const char *units)
1414 struct lprocfs_counter *c;
1416 unsigned int num_cpu;
1418 LASSERT(stats != NULL);
1420 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1422 for (i = 0; i < num_cpu; i++) {
1423 c = &(stats->ls_percpu[i]->lp_cntr[index]);
1424 c->lc_config = conf;
1427 c->lc_min = LC_MIN_INIT;
1430 c->lc_units = units;
1433 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1435 EXPORT_SYMBOL(lprocfs_counter_init);
1437 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1439 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1440 LASSERT(coffset < stats->ls_num); \
1441 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1444 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1446 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1447 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1448 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1449 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1450 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1451 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1452 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1453 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1454 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1455 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1456 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1457 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1458 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1459 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1460 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1461 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1462 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1463 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1467 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1468 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1469 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1470 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1471 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1472 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1473 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1474 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1475 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1476 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1477 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1478 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1479 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1480 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1481 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1482 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1483 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1484 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1485 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1486 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1487 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1488 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1489 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1490 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1491 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1492 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1493 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1494 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1495 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1496 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1497 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1498 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1499 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1500 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1501 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1502 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1503 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1504 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1505 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1506 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1507 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1508 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1509 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1510 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1511 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1512 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1513 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1514 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1517 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1519 struct lprocfs_stats *stats;
1520 unsigned int num_stats;
1523 LASSERT(obd->obd_stats == NULL);
1524 LASSERT(obd->obd_proc_entry != NULL);
1525 LASSERT(obd->obd_cntr_base == 0);
1527 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1528 num_private_stats - 1 /* o_owner */;
1529 stats = lprocfs_alloc_stats(num_stats, 0);
1533 lprocfs_init_ops_stats(num_private_stats, stats);
1535 for (i = num_private_stats; i < num_stats; i++) {
1536 /* If this LBUGs, it is likely that an obd
1537 * operation was added to struct obd_ops in
1538 * <obd.h>, and that the corresponding line item
1539 * LPROCFS_OBD_OP_INIT(.., .., opname)
1540 * is missing from the list above. */
1541 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1542 "Missing obd_stat initializer obd_op "
1543 "operation at offset %d.\n", i - num_private_stats);
1545 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1547 lprocfs_free_stats(&stats);
1549 obd->obd_stats = stats;
1550 obd->obd_cntr_base = num_private_stats;
1555 void lprocfs_free_obd_stats(struct obd_device *obd)
1558 lprocfs_free_stats(&obd->obd_stats);
1561 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1563 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1564 LASSERT(coffset < stats->ls_num); \
1565 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1568 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1570 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1571 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1572 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1573 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1574 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1575 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1576 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1577 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1578 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1579 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1580 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1581 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1582 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1583 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1584 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1585 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1586 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1587 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1588 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1589 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1590 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1591 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1592 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1593 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1594 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1595 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1596 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1597 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1598 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1599 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1600 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1601 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1604 int lprocfs_alloc_md_stats(struct obd_device *obd,
1605 unsigned num_private_stats)
1607 struct lprocfs_stats *stats;
1608 unsigned int num_stats;
1611 LASSERT(obd->md_stats == NULL);
1612 LASSERT(obd->obd_proc_entry != NULL);
1613 LASSERT(obd->md_cntr_base == 0);
1615 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1617 stats = lprocfs_alloc_stats(num_stats, 0);
1621 lprocfs_init_mps_stats(num_private_stats, stats);
1623 for (i = num_private_stats; i < num_stats; i++) {
1624 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1625 CERROR("Missing md_stat initializer md_op "
1626 "operation at offset %d. Aborting.\n",
1627 i - num_private_stats);
1631 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1633 lprocfs_free_stats(&stats);
1635 obd->md_stats = stats;
1636 obd->md_cntr_base = num_private_stats;
1641 void lprocfs_free_md_stats(struct obd_device *obd)
1643 struct lprocfs_stats *stats = obd->md_stats;
1645 if (stats != NULL) {
1646 obd->md_stats = NULL;
1647 obd->md_cntr_base = 0;
1648 lprocfs_free_stats(&stats);
1652 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1654 lprocfs_counter_init(ldlm_stats,
1655 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1656 0, "ldlm_enqueue", "reqs");
1657 lprocfs_counter_init(ldlm_stats,
1658 LDLM_CONVERT - LDLM_FIRST_OPC,
1659 0, "ldlm_convert", "reqs");
1660 lprocfs_counter_init(ldlm_stats,
1661 LDLM_CANCEL - LDLM_FIRST_OPC,
1662 0, "ldlm_cancel", "reqs");
1663 lprocfs_counter_init(ldlm_stats,
1664 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1665 0, "ldlm_bl_callback", "reqs");
1666 lprocfs_counter_init(ldlm_stats,
1667 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1668 0, "ldlm_cp_callback", "reqs");
1669 lprocfs_counter_init(ldlm_stats,
1670 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1671 0, "ldlm_gl_callback", "reqs");
1674 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1675 int *eof, void *data)
1677 struct obd_export *exp = data;
1678 LASSERT(exp != NULL);
1680 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1683 struct exp_uuid_cb_data {
1691 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1692 int count, int *eof, int *len)
1694 cb_data->page = page;
1695 cb_data->count = count;
1700 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1701 cfs_hlist_node_t *hnode, void *cb_data)
1704 struct obd_export *exp = cfs_hash_object(hs, hnode);
1705 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1707 if (exp->exp_nid_stats)
1708 *data->len += snprintf((data->page + *data->len),
1709 data->count, "%s\n",
1710 obd_uuid2str(&exp->exp_client_uuid));
1714 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1715 int *eof, void *data)
1717 struct nid_stat *stats = (struct nid_stat *)data;
1718 struct exp_uuid_cb_data cb_data;
1719 struct obd_device *obd = stats->nid_obd;
1724 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1725 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1726 lprocfs_exp_print_uuid, &cb_data);
1727 return (*cb_data.len);
1730 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1731 cfs_hlist_node_t *hnode, void *cb_data)
1734 struct exp_uuid_cb_data *data = cb_data;
1735 struct obd_export *exp = cfs_hash_object(hs, hnode);
1737 if (exp->exp_lock_hash != NULL) {
1739 *data->len += cfs_hash_debug_header(data->page,
1742 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1749 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1750 int *eof, void *data)
1752 struct nid_stat *stats = (struct nid_stat *)data;
1753 struct exp_uuid_cb_data cb_data;
1754 struct obd_device *obd = stats->nid_obd;
1759 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1761 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1762 lprocfs_exp_print_hash, &cb_data);
1763 return (*cb_data.len);
1766 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1767 int count, int *eof, void *data)
1770 return snprintf(page, count, "%s\n",
1771 "Write into this file to clear all nid stats and "
1772 "stale nid entries");
1774 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1776 int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1778 struct nid_stat *stat = obj;
1782 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1783 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1784 /* object has only hash references. */
1785 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1786 cfs_list_move(&stat->nid_list, data);
1787 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1790 /* we has reference to object - only clear data*/
1791 if (stat->nid_stats)
1792 lprocfs_clear_stats(stat->nid_stats);
1794 if (stat->nid_brw_stats) {
1795 for (i = 0; i < BRW_LAST; i++)
1796 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1801 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1802 unsigned long count, void *data)
1804 struct obd_device *obd = (struct obd_device *)data;
1805 struct nid_stat *client_stat;
1806 CFS_LIST_HEAD(free_list);
1808 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1809 lprocfs_nid_stats_clear_write_cb, &free_list);
1811 while (!cfs_list_empty(&free_list)) {
1812 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1814 cfs_list_del_init(&client_stat->nid_list);
1815 lprocfs_free_client_stats(client_stat);
1820 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1822 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1824 struct nid_stat *new_stat, *old_stat;
1825 struct obd_device *obd = NULL;
1826 cfs_proc_dir_entry_t *entry;
1827 char *buffer = NULL;
1833 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1834 !exp->exp_obd->obd_nid_stats_hash)
1837 /* not test against zero because eric say:
1838 * You may only test nid against another nid, or LNET_NID_ANY.
1839 * Anything else is nonsense.*/
1840 if (!nid || *nid == LNET_NID_ANY)
1845 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1847 OBD_ALLOC_PTR(new_stat);
1848 if (new_stat == NULL)
1851 new_stat->nid = *nid;
1852 new_stat->nid_obd = exp->exp_obd;
1853 /* we need set default refcount to 1 to balance obd_disconnect */
1854 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1856 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1857 nid, &new_stat->nid_hash);
1858 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1859 old_stat, libcfs_nid2str(*nid),
1860 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1862 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1863 * been and will never be called. */
1864 if (exp->exp_nid_stats) {
1865 nidstat_putref(exp->exp_nid_stats);
1866 exp->exp_nid_stats = NULL;
1869 /* Return -EALREADY here so that we know that the /proc
1870 * entry already has been created */
1871 if (old_stat != new_stat) {
1872 exp->exp_nid_stats = old_stat;
1873 GOTO(destroy_new, rc = -EALREADY);
1875 /* not found - create */
1876 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1878 GOTO(destroy_new, rc = -ENOMEM);
1880 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1881 new_stat->nid_proc = lprocfs_register(buffer,
1882 obd->obd_proc_exports_entry,
1884 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1886 if (new_stat->nid_proc == NULL) {
1887 CERROR("Error making export directory for nid %s\n",
1888 libcfs_nid2str(*nid));
1889 GOTO(destroy_new_ns, rc = -ENOMEM);
1892 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1893 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1894 if (IS_ERR(entry)) {
1895 CWARN("Error adding the NID stats file\n");
1896 rc = PTR_ERR(entry);
1897 GOTO(destroy_new_ns, rc);
1900 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1901 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1902 if (IS_ERR(entry)) {
1903 CWARN("Error adding the hash file\n");
1904 rc = PTR_ERR(entry);
1905 GOTO(destroy_new_ns, rc);
1908 exp->exp_nid_stats = new_stat;
1910 /* protect competitive add to list, not need locking on destroy */
1911 cfs_spin_lock(&obd->obd_nid_lock);
1912 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1913 cfs_spin_unlock(&obd->obd_nid_lock);
1918 if (new_stat->nid_proc != NULL)
1919 lprocfs_remove(&new_stat->nid_proc);
1920 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1923 nidstat_putref(new_stat);
1924 OBD_FREE_PTR(new_stat);
1928 int lprocfs_exp_cleanup(struct obd_export *exp)
1930 struct nid_stat *stat = exp->exp_nid_stats;
1932 if(!stat || !exp->exp_obd)
1935 nidstat_putref(exp->exp_nid_stats);
1936 exp->exp_nid_stats = NULL;
1941 int lprocfs_write_helper(const char *buffer, unsigned long count,
1944 return lprocfs_write_frac_helper(buffer, count, val, 1);
1947 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1950 char kernbuf[20], *end, *pbuf;
1952 if (count > (sizeof(kernbuf) - 1))
1955 if (cfs_copy_from_user(kernbuf, buffer, count))
1958 kernbuf[count] = '\0';
1965 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1969 if (end != NULL && *end == '.') {
1970 int temp_val, pow = 1;
1974 if (strlen(pbuf) > 5)
1975 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1977 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1980 for (i = 0; i < (end - pbuf); i++)
1983 *val += temp_val / pow;
1989 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
1992 long decimal_val, frac_val;
1998 decimal_val = val / mult;
1999 prtn = snprintf(buffer, count, "%ld", decimal_val);
2000 frac_val = val % mult;
2002 if (prtn < (count - 4) && frac_val > 0) {
2004 int i, temp_mult = 1, frac_bits = 0;
2006 temp_frac = frac_val * 10;
2007 buffer[prtn++] = '.';
2008 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2009 /* only reserved 2 bits fraction */
2010 buffer[prtn++] ='0';
2015 * Need to think these cases :
2016 * 1. #echo x.00 > /proc/xxx output result : x
2017 * 2. #echo x.0x > /proc/xxx output result : x.0x
2018 * 3. #echo x.x0 > /proc/xxx output result : x.x
2019 * 4. #echo x.xx > /proc/xxx output result : x.xx
2020 * Only reserved 2 bits fraction.
2022 for (i = 0; i < (5 - prtn); i++)
2025 frac_bits = min((int)count - prtn, 3 - frac_bits);
2026 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2027 frac_val * temp_mult / mult);
2030 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2032 if (buffer[prtn] == '.') {
2039 buffer[prtn++] ='\n';
2043 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2045 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2048 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2049 __u64 *val, int mult)
2051 char kernbuf[22], *end, *pbuf;
2052 __u64 whole, frac = 0, units;
2053 unsigned frac_d = 1;
2055 if (count > (sizeof(kernbuf) - 1))
2058 if (cfs_copy_from_user(kernbuf, buffer, count))
2061 kernbuf[count] = '\0';
2068 whole = simple_strtoull(pbuf, &end, 10);
2072 if (end != NULL && *end == '.') {
2076 /* need to limit frac_d to a __u32 */
2077 if (strlen(pbuf) > 10)
2080 frac = simple_strtoull(pbuf, &end, 10);
2081 /* count decimal places */
2082 for (i = 0; i < (end - pbuf); i++)
2099 /* Specified units override the multiplier */
2101 mult = mult < 0 ? -units : units;
2104 do_div(frac, frac_d);
2105 *val = whole * mult + frac;
2109 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2110 struct file_operations *seq_fops, void *data)
2112 struct proc_dir_entry *entry;
2115 LPROCFS_WRITE_ENTRY();
2116 entry = create_proc_entry(name, mode, parent);
2118 entry->proc_fops = seq_fops;
2121 LPROCFS_WRITE_EXIT();
2128 EXPORT_SYMBOL(lprocfs_seq_create);
2130 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2132 struct file_operations *seq_fops,
2135 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2136 mode, seq_fops, data));
2138 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2140 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2142 if (value >= OBD_HIST_MAX)
2143 value = OBD_HIST_MAX - 1;
2145 cfs_spin_lock(&oh->oh_lock);
2146 oh->oh_buckets[value]++;
2147 cfs_spin_unlock(&oh->oh_lock);
2149 EXPORT_SYMBOL(lprocfs_oh_tally);
2151 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2155 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2158 lprocfs_oh_tally(oh, val);
2160 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2162 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2164 unsigned long ret = 0;
2167 for (i = 0; i < OBD_HIST_MAX; i++)
2168 ret += oh->oh_buckets[i];
2171 EXPORT_SYMBOL(lprocfs_oh_sum);
2173 void lprocfs_oh_clear(struct obd_histogram *oh)
2175 cfs_spin_lock(&oh->oh_lock);
2176 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2177 cfs_spin_unlock(&oh->oh_lock);
2179 EXPORT_SYMBOL(lprocfs_oh_clear);
2181 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2182 int count, int *eof, void *data)
2184 struct obd_device *obd = data;
2190 c += cfs_hash_debug_header(page, count);
2191 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2192 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2193 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2194 #ifdef HAVE_QUOTA_SUPPORT
2195 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2196 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2197 page + c, count - c);
2202 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2204 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2205 int count, int *eof, void *data)
2207 struct obd_device *obd = data;
2210 LASSERT(obd != NULL);
2211 LASSERT(count >= 0);
2213 /* Set start of user data returned to
2214 page + off since the user may have
2215 requested to read much smaller than
2216 what we need to read */
2217 *start = page + off;
2219 /* We know we are allocated a page here.
2220 Also we know that this function will
2221 not need to write more than a page
2222 so we can truncate at CFS_PAGE_SIZE. */
2223 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2225 /* Initialize the page */
2226 memset(page, 0, size);
2228 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2230 if (obd->obd_max_recoverable_clients == 0) {
2231 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2237 /* sampled unlocked, but really... */
2238 if (obd->obd_recovering == 0) {
2239 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2241 if (lprocfs_obd_snprintf(&page, size, &len,
2242 "recovery_start: %lu\n",
2243 obd->obd_recovery_start) <= 0)
2245 if (lprocfs_obd_snprintf(&page, size, &len,
2246 "recovery_duration: %lu\n",
2247 obd->obd_recovery_end -
2248 obd->obd_recovery_start) <= 0)
2250 /* Number of clients that have completed recovery */
2251 if (lprocfs_obd_snprintf(&page, size, &len,
2252 "completed_clients: %d/%d\n",
2253 obd->obd_max_recoverable_clients -
2254 obd->obd_stale_clients,
2255 obd->obd_max_recoverable_clients) <= 0)
2257 if (lprocfs_obd_snprintf(&page, size, &len,
2258 "replayed_requests: %d\n",
2259 obd->obd_replayed_requests) <= 0)
2261 if (lprocfs_obd_snprintf(&page, size, &len,
2262 "last_transno: "LPD64"\n",
2263 obd->obd_next_recovery_transno - 1)<=0)
2265 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2266 obd->obd_version_recov ? "ON" : "OFF")<=0)
2271 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2273 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2274 obd->obd_recovery_start) <= 0)
2276 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2277 cfs_time_current_sec() >= obd->obd_recovery_end ? 0 :
2278 obd->obd_recovery_end - cfs_time_current_sec()) <= 0)
2280 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2281 obd->obd_connected_clients,
2282 obd->obd_max_recoverable_clients) <= 0)
2284 /* Number of clients that have completed recovery */
2285 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2286 cfs_atomic_read(&obd->obd_req_replay_clients))
2289 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2290 cfs_atomic_read(&obd->obd_lock_replay_clients))
2293 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2294 obd->obd_connected_clients -
2295 cfs_atomic_read(&obd->obd_lock_replay_clients))
2298 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2299 obd->obd_stale_clients) <= 0)
2301 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2302 obd->obd_replayed_requests) <= 0)
2304 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2305 obd->obd_requests_queued_for_recovery) <= 0)
2308 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2309 obd->obd_next_recovery_transno) <= 0)
2315 return min(count, len - (int)off);
2317 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2319 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2320 int count, int *eof, void *data)
2322 struct obd_device *obd = (struct obd_device *)data;
2323 LASSERT(obd != NULL);
2325 return snprintf(page, count, "%d\n",
2326 obd->obd_recovery_timeout);
2328 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2330 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2331 unsigned long count, void *data)
2333 struct obd_device *obd = (struct obd_device *)data;
2335 LASSERT(obd != NULL);
2337 rc = lprocfs_write_helper(buffer, count, &val);
2341 obd->obd_recovery_timeout = val;
2344 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2346 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2347 int count, int *eof, void *data)
2349 struct obd_device *obd = data;
2350 LASSERT(obd != NULL);
2352 return snprintf(page, count, "%lu\n", obd->obd_recovery_time_hard);
2354 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2356 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2357 unsigned long count, void *data)
2359 struct obd_device *obd = data;
2361 LASSERT(obd != NULL);
2363 rc = lprocfs_write_helper(buffer, count, &val);
2367 obd->obd_recovery_time_hard = val;
2370 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2372 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2373 int count, int *eof, void *data)
2375 struct obd_device *obd = (struct obd_device *)data;
2377 LASSERT(obd != NULL);
2378 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2380 return snprintf(page, count, "%s\n",
2381 obd->u.obt.obt_vfsmnt->mnt_devname);
2383 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2385 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2386 int count, int *eof, void *data)
2388 struct obd_device *dev = data;
2389 struct client_obd *cli = &dev->u.cli;
2392 client_obd_list_lock(&cli->cl_loi_list_lock);
2393 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2394 client_obd_list_unlock(&cli->cl_loi_list_lock);
2397 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2399 int lprocfs_obd_wr_max_pages_per_rpc(struct file *file, const char *buffer,
2400 unsigned long count, void *data)
2402 struct obd_device *dev = data;
2403 struct client_obd *cli = &dev->u.cli;
2404 struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
2407 rc = lprocfs_write_helper(buffer, count, &val);
2411 LPROCFS_CLIMP_CHECK(dev);
2412 if (val < 1 || val > ocd->ocd_brw_size >> CFS_PAGE_SHIFT) {
2413 LPROCFS_CLIMP_EXIT(dev);
2416 client_obd_list_lock(&cli->cl_loi_list_lock);
2417 cli->cl_max_pages_per_rpc = val;
2418 client_obd_list_unlock(&cli->cl_loi_list_lock);
2420 LPROCFS_CLIMP_EXIT(dev);
2423 EXPORT_SYMBOL(lprocfs_obd_wr_max_pages_per_rpc);
2425 EXPORT_SYMBOL(lprocfs_register);
2426 EXPORT_SYMBOL(lprocfs_srch);
2427 EXPORT_SYMBOL(lprocfs_remove);
2428 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2429 EXPORT_SYMBOL(lprocfs_add_vars);
2430 EXPORT_SYMBOL(lprocfs_obd_setup);
2431 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2432 EXPORT_SYMBOL(lprocfs_add_simple);
2433 EXPORT_SYMBOL(lprocfs_add_symlink);
2434 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2435 EXPORT_SYMBOL(lprocfs_alloc_stats);
2436 EXPORT_SYMBOL(lprocfs_free_stats);
2437 EXPORT_SYMBOL(lprocfs_clear_stats);
2438 EXPORT_SYMBOL(lprocfs_register_stats);
2439 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2440 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2441 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2442 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2443 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2444 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2445 EXPORT_SYMBOL(lprocfs_free_md_stats);
2446 EXPORT_SYMBOL(lprocfs_exp_setup);
2447 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2449 EXPORT_SYMBOL(lprocfs_rd_u64);
2450 EXPORT_SYMBOL(lprocfs_rd_atomic);
2451 EXPORT_SYMBOL(lprocfs_wr_atomic);
2452 EXPORT_SYMBOL(lprocfs_rd_uint);
2453 EXPORT_SYMBOL(lprocfs_wr_uint);
2454 EXPORT_SYMBOL(lprocfs_rd_uuid);
2455 EXPORT_SYMBOL(lprocfs_rd_name);
2456 EXPORT_SYMBOL(lprocfs_rd_fstype);
2457 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2458 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2459 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2460 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2461 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2462 EXPORT_SYMBOL(lprocfs_rd_import);
2463 EXPORT_SYMBOL(lprocfs_rd_state);
2464 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2465 EXPORT_SYMBOL(lprocfs_rd_blksize);
2466 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2467 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2468 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2469 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2470 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2472 EXPORT_SYMBOL(lprocfs_write_helper);
2473 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2474 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2475 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2476 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2477 EXPORT_SYMBOL(lprocfs_stats_collect);