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 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/obdclass/lprocfs_status.c
38 * Author: Hariharan Thantry <thantry@users.sourceforge.net>
42 # define EXPORT_SYMTAB
44 #define DEBUG_SUBSYSTEM S_CLASS
47 # include <liblustre.h>
50 #include <obd_class.h>
51 #include <lprocfs_status.h>
52 #include <lustre_fsfilt.h>
53 #include <lustre_log.h>
54 #include <lustre/lustre_idl.h>
58 #define MAX_STRING_SIZE 128
60 /* for bug 10866, global variable */
61 CFS_DECLARE_RWSEM(_lprocfs_lock);
62 EXPORT_SYMBOL(_lprocfs_lock);
64 int lprocfs_seq_release(struct inode *inode, struct file *file)
67 return seq_release(inode, file);
69 EXPORT_SYMBOL(lprocfs_seq_release);
71 static struct proc_dir_entry *__lprocfs_srch(struct proc_dir_entry *head,
74 struct proc_dir_entry *temp;
80 while (temp != NULL) {
81 if (strcmp(temp->name, name) == 0) {
90 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
93 struct proc_dir_entry *temp;
96 temp = __lprocfs_srch(head, name);
101 /* lprocfs API calls */
103 /* Function that emulates snprintf but also has the side effect of advancing
104 the page pointer for the next write into the buffer, incrementing the total
105 length written to the buffer, and decrementing the size left in the
107 static int lprocfs_obd_snprintf(char **page, int end, int *len,
108 const char *format, ...)
116 va_start(list, format);
117 n = vsnprintf(*page, end - *len, format, list);
120 *page += n; *len += n;
124 cfs_proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
126 read_proc_t *read_proc,
127 write_proc_t *write_proc,
129 struct file_operations *fops)
131 cfs_proc_dir_entry_t *proc;
134 if (root == NULL || name == NULL)
135 return ERR_PTR(-EINVAL);
142 LPROCFS_WRITE_ENTRY();
143 proc = create_proc_entry(name, mode, root);
145 CERROR("LprocFS: No memory to create /proc entry %s", name);
146 LPROCFS_WRITE_EXIT();
147 return ERR_PTR(-ENOMEM);
149 proc->read_proc = read_proc;
150 proc->write_proc = write_proc;
153 proc->proc_fops = fops;
154 LPROCFS_WRITE_EXIT();
158 struct proc_dir_entry *lprocfs_add_symlink(const char *name,
159 struct proc_dir_entry *parent, const char *format, ...)
161 struct proc_dir_entry *entry;
165 if (parent == NULL || format == NULL)
168 OBD_ALLOC_WAIT(dest, MAX_STRING_SIZE + 1);
172 va_start(ap, format);
173 vsnprintf(dest, MAX_STRING_SIZE, format, ap);
176 entry = proc_symlink(name, parent, dest);
178 CERROR("LprocFS: Could not create symbolic link from %s to %s",
181 OBD_FREE(dest, MAX_STRING_SIZE + 1);
185 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
186 size_t size, loff_t *ppos)
188 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
189 char *page, *start = NULL;
190 int rc = 0, eof = 1, count;
192 if (*ppos >= CFS_PAGE_SIZE)
195 page = (char *)__get_free_page(GFP_KERNEL);
199 if (LPROCFS_ENTRY_AND_CHECK(dp)) {
204 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
206 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
212 /* for lustre proc read, the read count must be less than PAGE_SIZE */
221 start = page + *ppos;
222 } else if (start < page) {
226 count = (rc < size) ? rc : size;
227 if (cfs_copy_to_user(buf, start, count)) {
234 free_page((unsigned long)page);
238 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
239 size_t size, loff_t *ppos)
241 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
244 if (LPROCFS_ENTRY_AND_CHECK(dp))
247 rc = dp->write_proc(f, buf, size, dp->data);
252 static struct file_operations lprocfs_generic_fops = {
253 .owner = THIS_MODULE,
254 .read = lprocfs_fops_read,
255 .write = lprocfs_fops_write,
258 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
260 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
261 struct obd_device *obd = dp->data;
263 cfs_atomic_inc(&obd->obd_evict_inprogress);
268 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
270 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
271 struct obd_device *obd = dp->data;
273 cfs_atomic_dec(&obd->obd_evict_inprogress);
274 cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
279 struct file_operations lprocfs_evict_client_fops = {
280 .owner = THIS_MODULE,
281 .read = lprocfs_fops_read,
282 .write = lprocfs_fops_write,
283 .open = lprocfs_evict_client_open,
284 .release = lprocfs_evict_client_release,
286 EXPORT_SYMBOL(lprocfs_evict_client_fops);
291 * \param root [in] The parent proc entry on which new entry will be added.
292 * \param list [in] Array of proc entries to be added.
293 * \param data [in] The argument to be passed when entries read/write routines
294 * are called through /proc file.
296 * \retval 0 on success
299 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
304 if (root == NULL || list == NULL)
307 LPROCFS_WRITE_ENTRY();
308 while (list->name != NULL) {
309 struct proc_dir_entry *cur_root, *proc;
310 char *pathcopy, *cur, *next, pathbuf[64];
311 int pathsize = strlen(list->name) + 1;
316 /* need copy of path for strsep */
317 if (strlen(list->name) > sizeof(pathbuf) - 1) {
318 OBD_ALLOC(pathcopy, pathsize);
319 if (pathcopy == NULL)
320 GOTO(out, rc = -ENOMEM);
326 strcpy(pathcopy, list->name);
328 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
329 if (*cur =='\0') /* skip double/trailing "/" */
332 proc = __lprocfs_srch(cur_root, cur);
333 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
334 cur_root->name, cur, next,
335 (proc ? "exists" : "new"));
337 cur_root = (proc ? proc :
338 proc_mkdir(cur, cur_root));
339 } else if (proc == NULL) {
341 if (list->proc_mode != 0000) {
342 mode = list->proc_mode;
346 if (list->write_fptr)
349 proc = create_proc_entry(cur, mode, cur_root);
353 if (pathcopy != pathbuf)
354 OBD_FREE(pathcopy, pathsize);
356 if (cur_root == NULL || proc == NULL) {
357 CERROR("LprocFS: No memory to create /proc entry %s",
359 GOTO(out, rc = -ENOMEM);
363 proc->proc_fops = list->fops;
365 proc->proc_fops = &lprocfs_generic_fops;
366 proc->read_proc = list->read_fptr;
367 proc->write_proc = list->write_fptr;
368 proc->data = (list->data ? list->data : data);
372 LPROCFS_WRITE_EXIT();
376 void lprocfs_remove(struct proc_dir_entry **rooth)
378 struct proc_dir_entry *root = *rooth;
379 struct proc_dir_entry *temp = root;
380 struct proc_dir_entry *rm_entry;
381 struct proc_dir_entry *parent;
387 parent = root->parent;
388 LASSERT(parent != NULL);
389 LPROCFS_WRITE_ENTRY(); /* search vs remove race */
392 while (temp->subdir != NULL)
398 /* Memory corruption once caused this to fail, and
399 without this LASSERT we would loop here forever. */
400 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
401 "0x%p %s/%s len %d\n", rm_entry, temp->name,
402 rm_entry->name, (int)strlen(rm_entry->name));
404 #ifdef HAVE_PROCFS_USERS
405 /* if procfs uses user count to synchronize deletion of
406 * proc entry, there is no protection for rm_entry->data,
407 * then lprocfs_fops_read and lprocfs_fops_write maybe
408 * call proc_dir_entry->read_proc (or write_proc) with
409 * proc_dir_entry->data == NULL, then cause kernel Oops.
410 * see bug19706 for detailed information */
412 /* procfs won't free rm_entry->data if it isn't a LINK,
413 * and Lustre won't use rm_entry->data if it is a LINK */
414 if (S_ISLNK(rm_entry->mode))
415 rm_entry->data = NULL;
417 /* Now, the rm_entry->deleted flags is protected
418 * by _lprocfs_lock. */
419 rm_entry->data = NULL;
421 remove_proc_entry(rm_entry->name, temp);
425 LPROCFS_WRITE_EXIT();
428 void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
430 LASSERT(parent != NULL);
431 remove_proc_entry(name, parent);
434 struct proc_dir_entry *lprocfs_register(const char *name,
435 struct proc_dir_entry *parent,
436 struct lprocfs_vars *list, void *data)
438 struct proc_dir_entry *newchild;
440 newchild = lprocfs_srch(parent, name);
441 if (newchild != NULL) {
442 CERROR(" Lproc: Attempting to register %s more than once \n",
444 return ERR_PTR(-EALREADY);
447 newchild = proc_mkdir(name, parent);
448 if (newchild != NULL && list != NULL) {
449 int rc = lprocfs_add_vars(newchild, list, data);
451 lprocfs_remove(&newchild);
458 /* Generic callbacks */
459 int lprocfs_rd_uint(char *page, char **start, off_t off,
460 int count, int *eof, void *data)
462 unsigned int *temp = data;
463 return snprintf(page, count, "%u\n", *temp);
466 int lprocfs_wr_uint(struct file *file, const char *buffer,
467 unsigned long count, void *data)
470 char dummy[MAX_STRING_SIZE + 1], *end;
473 dummy[MAX_STRING_SIZE] = '\0';
474 if (cfs_copy_from_user(dummy, buffer, MAX_STRING_SIZE))
477 tmp = simple_strtoul(dummy, &end, 0);
481 *p = (unsigned int)tmp;
485 int lprocfs_rd_u64(char *page, char **start, off_t off,
486 int count, int *eof, void *data)
488 LASSERT(data != NULL);
490 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
493 int lprocfs_rd_atomic(char *page, char **start, off_t off,
494 int count, int *eof, void *data)
496 cfs_atomic_t *atom = data;
497 LASSERT(atom != NULL);
499 return snprintf(page, count, "%d\n", cfs_atomic_read(atom));
502 int lprocfs_wr_atomic(struct file *file, const char *buffer,
503 unsigned long count, void *data)
505 cfs_atomic_t *atm = data;
509 rc = lprocfs_write_helper(buffer, count, &val);
516 cfs_atomic_set(atm, val);
520 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
521 int *eof, void *data)
523 struct obd_device *obd = data;
525 LASSERT(obd != NULL);
527 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
530 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
531 int *eof, void *data)
533 struct obd_device *dev = data;
535 LASSERT(dev != NULL);
536 LASSERT(dev->obd_name != NULL);
538 return snprintf(page, count, "%s\n", dev->obd_name);
541 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
544 struct obd_device *obd = data;
546 LASSERT(obd != NULL);
547 LASSERT(obd->obd_fsops != NULL);
548 LASSERT(obd->obd_fsops->fs_type != NULL);
549 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
552 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
553 int *eof, void *data)
555 struct obd_statfs osfs;
556 int rc = obd_statfs(data, &osfs,
557 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
561 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
566 int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
567 int *eof, void *data)
569 struct obd_statfs osfs;
570 int rc = obd_statfs(data, &osfs,
571 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
574 __u32 blk_size = osfs.os_bsize >> 10;
575 __u64 result = osfs.os_blocks;
577 while (blk_size >>= 1)
581 rc = snprintf(page, count, LPU64"\n", result);
586 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
587 int *eof, void *data)
589 struct obd_statfs osfs;
590 int rc = obd_statfs(data, &osfs,
591 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
594 __u32 blk_size = osfs.os_bsize >> 10;
595 __u64 result = osfs.os_bfree;
597 while (blk_size >>= 1)
601 rc = snprintf(page, count, LPU64"\n", result);
606 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
607 int *eof, void *data)
609 struct obd_statfs osfs;
610 int rc = obd_statfs(data, &osfs,
611 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
614 __u32 blk_size = osfs.os_bsize >> 10;
615 __u64 result = osfs.os_bavail;
617 while (blk_size >>= 1)
621 rc = snprintf(page, count, LPU64"\n", result);
626 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
627 int *eof, void *data)
629 struct obd_statfs osfs;
630 int rc = obd_statfs(data, &osfs,
631 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
635 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
641 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
642 int *eof, void *data)
644 struct obd_statfs osfs;
645 int rc = obd_statfs(data, &osfs,
646 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
650 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
655 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
656 int *eof, void *data)
658 struct obd_device *obd = data;
659 struct obd_import *imp;
660 char *imp_state_name = NULL;
663 LASSERT(obd != NULL);
664 LPROCFS_CLIMP_CHECK(obd);
665 imp = obd->u.cli.cl_import;
666 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
668 rc = snprintf(page, count, "%s\t%s%s\n",
669 obd2cli_tgt(obd), imp_state_name,
670 imp->imp_deactive ? "\tDEACTIVATED" : "");
672 LPROCFS_CLIMP_EXIT(obd);
676 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
677 int *eof, void *data)
679 struct obd_device *obd = data;
680 struct ptlrpc_connection *conn;
683 LASSERT(obd != NULL);
685 LPROCFS_CLIMP_CHECK(obd);
686 conn = obd->u.cli.cl_import->imp_connection;
688 if (conn && obd->u.cli.cl_import) {
689 rc = snprintf(page, count, "%s\n",
690 conn->c_remote_uuid.uuid);
692 rc = snprintf(page, count, "%s\n", "<none>");
695 LPROCFS_CLIMP_EXIT(obd);
699 /** add up per-cpu counters */
700 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
701 struct lprocfs_counter *cnt)
703 unsigned int num_cpu;
704 struct lprocfs_counter t;
705 struct lprocfs_counter *percpu_cntr;
708 memset(cnt, 0, sizeof(*cnt));
711 /* set count to 1 to avoid divide-by-zero errs in callers */
716 cnt->lc_min = LC_MIN_INIT;
718 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
720 for (i = 0; i < num_cpu; i++) {
721 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
724 centry = cfs_atomic_read(&percpu_cntr-> \
726 t.lc_count = percpu_cntr->lc_count;
727 t.lc_sum = percpu_cntr->lc_sum;
728 t.lc_min = percpu_cntr->lc_min;
729 t.lc_max = percpu_cntr->lc_max;
730 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
731 } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
733 centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
735 cnt->lc_count += t.lc_count;
736 cnt->lc_sum += t.lc_sum;
737 if (t.lc_min < cnt->lc_min)
738 cnt->lc_min = t.lc_min;
739 if (t.lc_max > cnt->lc_max)
740 cnt->lc_max = t.lc_max;
741 cnt->lc_sumsquare += t.lc_sumsquare;
744 cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
745 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
749 * Append a space separated list of current set flags to str.
751 #define flag2str(flag) \
752 if (imp->imp_##flag && max - len > 0) \
753 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
754 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
758 if (imp->imp_obd->obd_no_recov)
759 len += snprintf(str, max - len, "no_recov");
763 flag2str(replayable);
769 static const char *obd_connect_names[] = {
783 "join_file(obsolete)",
787 "remote_client_by_force",
796 "mds_mds_connection",
799 "alt_checksum_algorithm",
812 static int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
817 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
819 ret += snprintf(page + ret, count - ret, "%s%s",
820 ret ? sep : "", obd_connect_names[i]);
822 if (flags & ~(mask - 1))
823 ret += snprintf(page + ret, count - ret,
824 "%sunknown flags "LPX64,
825 ret ? sep : "", flags & ~(mask - 1));
829 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
830 int *eof, void *data)
832 struct lprocfs_counter ret;
833 struct obd_device *obd = (struct obd_device *)data;
834 struct obd_import *imp;
835 struct obd_import_conn *conn;
838 LASSERT(obd != NULL);
839 LPROCFS_CLIMP_CHECK(obd);
840 imp = obd->u.cli.cl_import;
843 i = snprintf(page, count,
851 ptlrpc_import_state_name(imp->imp_state));
852 i += obd_connect_flags2str(page + i, count - i,
853 imp->imp_connect_data.ocd_connect_flags,
855 i += snprintf(page + i, count - i,
858 i += obd_import_flags2str(imp, page + i, count - i);
860 i += snprintf(page + i, count - i,
863 " failover_nids: [");
864 cfs_spin_lock(&imp->imp_lock);
866 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
867 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
868 libcfs_nid2str(conn->oic_conn->c_peer.nid));
871 cfs_spin_unlock(&imp->imp_lock);
872 i += snprintf(page + i, count - i,
874 " current_connection: %s\n"
875 " connection_attempts: %u\n"
877 " in-progress_invalidations: %u\n",
878 libcfs_nid2str(imp->imp_connection->c_peer.nid),
881 cfs_atomic_read(&imp->imp_inval_count));
883 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
884 if (ret.lc_count != 0) {
885 /* first argument to do_div MUST be __u64 */
886 __u64 sum = ret.lc_sum;
887 do_div(sum, ret.lc_count);
891 i += snprintf(page + i, count - i,
894 " unregistering: %u\n"
896 " avg_waittime: "LPU64" %s\n",
897 cfs_atomic_read(&imp->imp_inflight),
898 cfs_atomic_read(&imp->imp_unregistering),
899 cfs_atomic_read(&imp->imp_timeouts),
900 ret.lc_sum, ret.lc_units);
903 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
904 if (imp->imp_at.iat_portal[j] == 0)
906 k = max_t(unsigned int, k,
907 at_get(&imp->imp_at.iat_service_estimate[j]));
909 i += snprintf(page + i, count - i,
910 " service_estimates:\n"
911 " services: %u sec\n"
912 " network: %u sec\n",
914 at_get(&imp->imp_at.iat_net_latency));
916 i += snprintf(page + i, count - i,
918 " last_replay: "LPU64"\n"
919 " peer_committed: "LPU64"\n"
920 " last_checked: "LPU64"\n",
921 imp->imp_last_replay_transno,
922 imp->imp_peer_committed_transno,
923 imp->imp_last_transno_checked);
926 for (rw = 0; rw <= 1; rw++) {
927 lprocfs_stats_collect(obd->obd_svc_stats,
928 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
930 if (ret.lc_sum > 0 && ret.lc_count > 0) {
931 /* first argument to do_div MUST be __u64 */
932 __u64 sum = ret.lc_sum;
933 do_div(sum, ret.lc_count);
935 i += snprintf(page + i, count - i,
936 " %s_data_averages:\n"
937 " bytes_per_rpc: "LPU64"\n",
938 rw ? "write" : "read",
942 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
943 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
944 if (ret.lc_sum > 0 && ret.lc_count != 0) {
945 /* first argument to do_div MUST be __u64 */
946 __u64 sum = ret.lc_sum;
947 do_div(sum, ret.lc_count);
949 i += snprintf(page + i, count - i,
950 " %s_per_rpc: "LPU64"\n",
951 ret.lc_units, ret.lc_sum);
954 i += snprintf(page + i, count - i,
955 " MB_per_sec: %u.%.02u\n",
956 k / j, (100 * k / j) % 100);
960 LPROCFS_CLIMP_EXIT(obd);
964 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
965 int *eof, void *data)
967 struct obd_device *obd = (struct obd_device *)data;
968 struct obd_import *imp;
971 LASSERT(obd != NULL);
972 LPROCFS_CLIMP_CHECK(obd);
973 imp = obd->u.cli.cl_import;
976 i = snprintf(page, count, "current_state: %s\n",
977 ptlrpc_import_state_name(imp->imp_state));
978 i += snprintf(page + i, count - i,
980 k = imp->imp_state_hist_idx;
981 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
982 struct import_state_hist *ish =
983 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
984 if (ish->ish_state == 0)
986 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
988 ptlrpc_import_state_name(ish->ish_state));
991 LPROCFS_CLIMP_EXIT(obd);
995 int lprocfs_at_hist_helper(char *page, int count, int rc,
996 struct adaptive_timeout *at)
999 for (i = 0; i < AT_BINS; i++)
1000 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1001 rc += snprintf(page + rc, count - rc, "\n");
1005 /* See also ptlrpc_lprocfs_rd_timeouts */
1006 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1007 int *eof, void *data)
1009 struct obd_device *obd = (struct obd_device *)data;
1010 struct obd_import *imp;
1011 unsigned int cur, worst;
1016 LASSERT(obd != NULL);
1017 LPROCFS_CLIMP_CHECK(obd);
1018 imp = obd->u.cli.cl_import;
1021 now = cfs_time_current_sec();
1023 /* Some network health info for kicks */
1024 s2dhms(&ts, now - imp->imp_last_reply_time);
1025 rc += snprintf(page + rc, count - rc,
1026 "%-10s : %ld, "DHMS_FMT" ago\n",
1027 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1029 cur = at_get(&imp->imp_at.iat_net_latency);
1030 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1031 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1032 s2dhms(&ts, now - worstt);
1033 rc += snprintf(page + rc, count - rc,
1034 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1035 "network", cur, worst, worstt, DHMS_VARS(&ts));
1036 rc = lprocfs_at_hist_helper(page, count, rc,
1037 &imp->imp_at.iat_net_latency);
1039 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1040 if (imp->imp_at.iat_portal[i] == 0)
1042 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1043 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1044 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1045 s2dhms(&ts, now - worstt);
1046 rc += snprintf(page + rc, count - rc,
1047 "portal %-2d : cur %3u worst %3u (at %ld, "
1048 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1049 cur, worst, worstt, DHMS_VARS(&ts));
1050 rc = lprocfs_at_hist_helper(page, count, rc,
1051 &imp->imp_at.iat_service_estimate[i]);
1054 LPROCFS_CLIMP_EXIT(obd);
1058 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1059 int count, int *eof, void *data)
1061 struct obd_device *obd = data;
1065 LPROCFS_CLIMP_CHECK(obd);
1066 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1067 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1068 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1069 ret += snprintf(page + ret, count - ret, "\n");
1070 LPROCFS_CLIMP_EXIT(obd);
1073 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1075 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1076 int *eof, void *data)
1078 struct obd_device *obd = data;
1080 LASSERT(obd != NULL);
1082 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1085 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1086 int *eof, void *data)
1088 struct obd_type *class = (struct obd_type*) data;
1090 LASSERT(class != NULL);
1092 return snprintf(page, count, "%d\n", class->typ_refcnt);
1095 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1099 LASSERT(obd != NULL);
1100 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1101 LASSERT(obd->obd_type->typ_procroot != NULL);
1103 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1104 obd->obd_type->typ_procroot,
1106 if (IS_ERR(obd->obd_proc_entry)) {
1107 rc = PTR_ERR(obd->obd_proc_entry);
1108 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1109 obd->obd_proc_entry = NULL;
1114 int lprocfs_obd_cleanup(struct obd_device *obd)
1118 if (obd->obd_proc_exports_entry) {
1119 /* Should be no exports left */
1120 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1121 lprocfs_remove(&obd->obd_proc_exports_entry);
1122 obd->obd_proc_exports_entry = NULL;
1124 if (obd->obd_proc_entry) {
1125 lprocfs_remove(&obd->obd_proc_entry);
1126 obd->obd_proc_entry = NULL;
1131 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1133 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1134 client_stat->nid_proc, client_stat->nid_stats,
1135 client_stat->nid_brw_stats);
1137 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1138 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1139 atomic_read(&client_stat->nid_exp_ref_count));
1141 cfs_hlist_del_init(&client_stat->nid_hash);
1143 if (client_stat->nid_proc)
1144 lprocfs_remove(&client_stat->nid_proc);
1146 if (client_stat->nid_stats)
1147 lprocfs_free_stats(&client_stat->nid_stats);
1149 if (client_stat->nid_brw_stats)
1150 OBD_FREE_PTR(client_stat->nid_brw_stats);
1152 if (client_stat->nid_ldlm_stats)
1153 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1155 OBD_FREE_PTR(client_stat);
1160 void lprocfs_free_per_client_stats(struct obd_device *obd)
1162 struct nid_stat *stat;
1165 /* we need extra list - because hash_exit called to early */
1166 /* not need locking because all clients is died */
1167 while(!cfs_list_empty(&obd->obd_nid_stats)) {
1168 stat = cfs_list_entry(obd->obd_nid_stats.next,
1169 struct nid_stat, nid_list);
1170 cfs_list_del_init(&stat->nid_list);
1171 lprocfs_free_client_stats(stat);
1177 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1178 enum lprocfs_stats_flags flags)
1180 struct lprocfs_stats *stats;
1181 unsigned int percpusize;
1183 unsigned int num_cpu;
1188 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1191 num_cpu = cfs_num_possible_cpus();
1193 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1197 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1198 stats->ls_flags = flags;
1199 cfs_spin_lock_init(&stats->ls_lock);
1200 /* Use this lock only if there are no percpu areas */
1202 stats->ls_flags = 0;
1205 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1207 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1209 for (i = 0; i < num_cpu; i++) {
1210 OBD_ALLOC(stats->ls_percpu[i], percpusize);
1211 if (stats->ls_percpu[i] == NULL) {
1212 for (j = 0; j < i; j++) {
1213 OBD_FREE(stats->ls_percpu[j], percpusize);
1214 stats->ls_percpu[j] = NULL;
1219 if (stats->ls_percpu[0] == NULL) {
1220 OBD_FREE(stats, offsetof(typeof(*stats),
1221 ls_percpu[num_cpu]));
1225 stats->ls_num = num;
1229 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1231 struct lprocfs_stats *stats = *statsh;
1232 unsigned int num_cpu;
1233 unsigned int percpusize;
1236 if (stats == NULL || stats->ls_num == 0)
1240 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1243 num_cpu = cfs_num_possible_cpus();
1245 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1247 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1248 for (i = 0; i < num_cpu; i++)
1249 OBD_FREE(stats->ls_percpu[i], percpusize);
1250 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1253 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1255 struct lprocfs_counter *percpu_cntr;
1257 unsigned int num_cpu;
1259 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1261 for (i = 0; i < num_cpu; i++) {
1262 for (j = 0; j < stats->ls_num; j++) {
1263 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1264 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1265 percpu_cntr->lc_count = 0;
1266 percpu_cntr->lc_sum = 0;
1267 percpu_cntr->lc_min = LC_MIN_INIT;
1268 percpu_cntr->lc_max = 0;
1269 percpu_cntr->lc_sumsquare = 0;
1270 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1274 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1277 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1278 size_t len, loff_t *off)
1280 struct seq_file *seq = file->private_data;
1281 struct lprocfs_stats *stats = seq->private;
1283 lprocfs_clear_stats(stats);
1288 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1290 struct lprocfs_stats *stats = p->private;
1291 /* return 1st cpu location */
1292 return (*pos >= stats->ls_num) ? NULL :
1293 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1296 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1300 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1302 struct lprocfs_stats *stats = p->private;
1304 return (*pos >= stats->ls_num) ? NULL :
1305 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1308 /* seq file export of one lprocfs counter */
1309 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1311 struct lprocfs_stats *stats = p->private;
1312 struct lprocfs_counter *cntr = v;
1313 struct lprocfs_counter ret;
1316 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1318 cfs_gettimeofday(&now);
1319 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1320 "snapshot_time", now.tv_sec, now.tv_usec);
1324 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1326 lprocfs_stats_collect(stats, idx, &ret);
1328 if (ret.lc_count == 0)
1331 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1332 ret.lc_count, cntr->lc_units);
1337 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1338 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1339 ret.lc_min, ret.lc_max, ret.lc_sum);
1342 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1343 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1347 rc = seq_printf(p, "\n");
1349 return (rc < 0) ? rc : 0;
1352 struct seq_operations lprocfs_stats_seq_sops = {
1353 start: lprocfs_stats_seq_start,
1354 stop: lprocfs_stats_seq_stop,
1355 next: lprocfs_stats_seq_next,
1356 show: lprocfs_stats_seq_show,
1359 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1361 struct proc_dir_entry *dp = PDE(inode);
1362 struct seq_file *seq;
1365 if (LPROCFS_ENTRY_AND_CHECK(dp))
1368 rc = seq_open(file, &lprocfs_stats_seq_sops);
1373 seq = file->private_data;
1374 seq->private = dp->data;
1378 struct file_operations lprocfs_stats_seq_fops = {
1379 .owner = THIS_MODULE,
1380 .open = lprocfs_stats_seq_open,
1382 .write = lprocfs_stats_seq_write,
1383 .llseek = seq_lseek,
1384 .release = lprocfs_seq_release,
1387 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1388 struct lprocfs_stats *stats)
1390 struct proc_dir_entry *entry;
1391 LASSERT(root != NULL);
1393 LPROCFS_WRITE_ENTRY();
1394 entry = create_proc_entry(name, 0644, root);
1396 entry->proc_fops = &lprocfs_stats_seq_fops;
1397 entry->data = stats;
1400 LPROCFS_WRITE_EXIT();
1408 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1409 unsigned conf, const char *name, const char *units)
1411 struct lprocfs_counter *c;
1413 unsigned int num_cpu;
1415 LASSERT(stats != NULL);
1417 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1419 for (i = 0; i < num_cpu; i++) {
1420 c = &(stats->ls_percpu[i]->lp_cntr[index]);
1421 c->lc_config = conf;
1424 c->lc_min = LC_MIN_INIT;
1427 c->lc_units = units;
1430 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1432 EXPORT_SYMBOL(lprocfs_counter_init);
1434 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1436 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1437 LASSERT(coffset < stats->ls_num); \
1438 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1441 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1443 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1444 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1445 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1446 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1447 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1448 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1449 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1450 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1451 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1452 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1453 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1454 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1455 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1456 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1457 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1458 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1459 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1460 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1461 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1462 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1463 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1467 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1468 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1469 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1470 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1471 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1472 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1473 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1474 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1475 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1476 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1477 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1478 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1479 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1480 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1481 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1482 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1483 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1484 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1485 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1486 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1487 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1488 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1489 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1490 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1491 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1492 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1493 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1494 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1495 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1496 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1497 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1498 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1499 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1500 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1501 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1502 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1503 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1504 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1505 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1506 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1507 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1508 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1509 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1510 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1511 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1514 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1516 struct lprocfs_stats *stats;
1517 unsigned int num_stats;
1520 LASSERT(obd->obd_stats == NULL);
1521 LASSERT(obd->obd_proc_entry != NULL);
1522 LASSERT(obd->obd_cntr_base == 0);
1524 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1525 num_private_stats - 1 /* o_owner */;
1526 stats = lprocfs_alloc_stats(num_stats, 0);
1530 lprocfs_init_ops_stats(num_private_stats, stats);
1532 for (i = num_private_stats; i < num_stats; i++) {
1533 /* If this LBUGs, it is likely that an obd
1534 * operation was added to struct obd_ops in
1535 * <obd.h>, and that the corresponding line item
1536 * LPROCFS_OBD_OP_INIT(.., .., opname)
1537 * is missing from the list above. */
1538 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1539 "Missing obd_stat initializer obd_op "
1540 "operation at offset %d.\n", i - num_private_stats);
1542 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1544 lprocfs_free_stats(&stats);
1546 obd->obd_stats = stats;
1547 obd->obd_cntr_base = num_private_stats;
1552 void lprocfs_free_obd_stats(struct obd_device *obd)
1555 lprocfs_free_stats(&obd->obd_stats);
1558 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1560 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1561 LASSERT(coffset < stats->ls_num); \
1562 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1565 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1567 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1568 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1569 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1570 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1571 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1572 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1573 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1574 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1575 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1576 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1577 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1578 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1579 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1580 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1581 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1582 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1583 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1584 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1585 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1586 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1587 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1588 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1589 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1590 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1591 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1592 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1593 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1594 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1595 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1596 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1597 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1598 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1601 int lprocfs_alloc_md_stats(struct obd_device *obd,
1602 unsigned num_private_stats)
1604 struct lprocfs_stats *stats;
1605 unsigned int num_stats;
1608 LASSERT(obd->md_stats == NULL);
1609 LASSERT(obd->obd_proc_entry != NULL);
1610 LASSERT(obd->md_cntr_base == 0);
1612 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1614 stats = lprocfs_alloc_stats(num_stats, 0);
1618 lprocfs_init_mps_stats(num_private_stats, stats);
1620 for (i = num_private_stats; i < num_stats; i++) {
1621 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1622 CERROR("Missing md_stat initializer md_op "
1623 "operation at offset %d. Aborting.\n",
1624 i - num_private_stats);
1628 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1630 lprocfs_free_stats(&stats);
1632 obd->md_stats = stats;
1633 obd->md_cntr_base = num_private_stats;
1638 void lprocfs_free_md_stats(struct obd_device *obd)
1640 struct lprocfs_stats *stats = obd->md_stats;
1642 if (stats != NULL) {
1643 obd->md_stats = NULL;
1644 obd->md_cntr_base = 0;
1645 lprocfs_free_stats(&stats);
1649 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1651 lprocfs_counter_init(ldlm_stats,
1652 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1653 0, "ldlm_enqueue", "reqs");
1654 lprocfs_counter_init(ldlm_stats,
1655 LDLM_CONVERT - LDLM_FIRST_OPC,
1656 0, "ldlm_convert", "reqs");
1657 lprocfs_counter_init(ldlm_stats,
1658 LDLM_CANCEL - LDLM_FIRST_OPC,
1659 0, "ldlm_cancel", "reqs");
1660 lprocfs_counter_init(ldlm_stats,
1661 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1662 0, "ldlm_bl_callback", "reqs");
1663 lprocfs_counter_init(ldlm_stats,
1664 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1665 0, "ldlm_cp_callback", "reqs");
1666 lprocfs_counter_init(ldlm_stats,
1667 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1668 0, "ldlm_gl_callback", "reqs");
1671 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1672 int *eof, void *data)
1674 struct obd_export *exp = data;
1675 LASSERT(exp != NULL);
1677 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1680 struct exp_uuid_cb_data {
1688 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1689 int count, int *eof, int *len)
1691 cb_data->page = page;
1692 cb_data->count = count;
1697 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1698 cfs_hlist_node_t *hnode, void *cb_data)
1701 struct obd_export *exp = cfs_hash_object(hs, hnode);
1702 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1704 if (exp->exp_nid_stats)
1705 *data->len += snprintf((data->page + *data->len),
1706 data->count, "%s\n",
1707 obd_uuid2str(&exp->exp_client_uuid));
1711 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1712 int *eof, void *data)
1714 struct nid_stat *stats = (struct nid_stat *)data;
1715 struct exp_uuid_cb_data cb_data;
1716 struct obd_device *obd = stats->nid_obd;
1721 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1722 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1723 lprocfs_exp_print_uuid, &cb_data);
1724 return (*cb_data.len);
1727 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1728 cfs_hlist_node_t *hnode, void *cb_data)
1731 struct exp_uuid_cb_data *data = cb_data;
1732 struct obd_export *exp = cfs_hash_object(hs, hnode);
1734 if (exp->exp_lock_hash != NULL) {
1736 *data->len += cfs_hash_debug_header(data->page,
1739 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1746 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1747 int *eof, void *data)
1749 struct nid_stat *stats = (struct nid_stat *)data;
1750 struct exp_uuid_cb_data cb_data;
1751 struct obd_device *obd = stats->nid_obd;
1756 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1758 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1759 lprocfs_exp_print_hash, &cb_data);
1760 return (*cb_data.len);
1763 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1764 int count, int *eof, void *data)
1767 return snprintf(page, count, "%s\n",
1768 "Write into this file to clear all nid stats and "
1769 "stale nid entries");
1771 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1773 int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1775 struct nid_stat *stat = obj;
1779 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1780 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1781 /* object has only hash references. */
1782 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1783 cfs_list_move(&stat->nid_list, data);
1784 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1787 /* we has reference to object - only clear data*/
1788 if (stat->nid_stats)
1789 lprocfs_clear_stats(stat->nid_stats);
1791 if (stat->nid_brw_stats) {
1792 for (i = 0; i < BRW_LAST; i++)
1793 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1798 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1799 unsigned long count, void *data)
1801 struct obd_device *obd = (struct obd_device *)data;
1802 struct nid_stat *client_stat;
1803 CFS_LIST_HEAD(free_list);
1805 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1806 lprocfs_nid_stats_clear_write_cb, &free_list);
1808 while (!cfs_list_empty(&free_list)) {
1809 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1811 cfs_list_del_init(&client_stat->nid_list);
1812 lprocfs_free_client_stats(client_stat);
1817 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1819 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1821 struct nid_stat *new_stat, *old_stat;
1822 struct obd_device *obd = NULL;
1823 cfs_proc_dir_entry_t *entry;
1824 char *buffer = NULL;
1830 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1831 !exp->exp_obd->obd_nid_stats_hash)
1834 /* not test against zero because eric say:
1835 * You may only test nid against another nid, or LNET_NID_ANY.
1836 * Anything else is nonsense.*/
1837 if (!nid || *nid == LNET_NID_ANY)
1842 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1844 OBD_ALLOC_PTR(new_stat);
1845 if (new_stat == NULL)
1848 new_stat->nid = *nid;
1849 new_stat->nid_obd = exp->exp_obd;
1850 /* we need set default refcount to 1 to balance obd_disconnect */
1851 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1853 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1854 nid, &new_stat->nid_hash);
1855 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1856 old_stat, libcfs_nid2str(*nid),
1857 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1859 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1860 * been and will never be called. */
1861 if (exp->exp_nid_stats) {
1862 nidstat_putref(exp->exp_nid_stats);
1863 exp->exp_nid_stats = NULL;
1866 /* Return -EALREADY here so that we know that the /proc
1867 * entry already has been created */
1868 if (old_stat != new_stat) {
1869 exp->exp_nid_stats = old_stat;
1870 GOTO(destroy_new, rc = -EALREADY);
1872 /* not found - create */
1873 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1875 GOTO(destroy_new, rc = -ENOMEM);
1877 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1878 new_stat->nid_proc = lprocfs_register(buffer,
1879 obd->obd_proc_exports_entry,
1881 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1883 if (new_stat->nid_proc == NULL) {
1884 CERROR("Error making export directory for nid %s\n",
1885 libcfs_nid2str(*nid));
1886 GOTO(destroy_new_ns, rc = -ENOMEM);
1889 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1890 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1891 if (IS_ERR(entry)) {
1892 CWARN("Error adding the NID stats file\n");
1893 rc = PTR_ERR(entry);
1894 GOTO(destroy_new_ns, rc);
1897 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1898 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1899 if (IS_ERR(entry)) {
1900 CWARN("Error adding the hash file\n");
1901 rc = PTR_ERR(entry);
1902 GOTO(destroy_new_ns, rc);
1905 exp->exp_nid_stats = new_stat;
1907 /* protect competitive add to list, not need locking on destroy */
1908 cfs_spin_lock(&obd->obd_nid_lock);
1909 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1910 cfs_spin_unlock(&obd->obd_nid_lock);
1915 if (new_stat->nid_proc != NULL)
1916 lprocfs_remove(&new_stat->nid_proc);
1917 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1920 nidstat_putref(new_stat);
1921 OBD_FREE_PTR(new_stat);
1925 int lprocfs_exp_cleanup(struct obd_export *exp)
1927 struct nid_stat *stat = exp->exp_nid_stats;
1929 if(!stat || !exp->exp_obd)
1932 nidstat_putref(exp->exp_nid_stats);
1933 exp->exp_nid_stats = NULL;
1938 int lprocfs_write_helper(const char *buffer, unsigned long count,
1941 return lprocfs_write_frac_helper(buffer, count, val, 1);
1944 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1947 char kernbuf[20], *end, *pbuf;
1949 if (count > (sizeof(kernbuf) - 1))
1952 if (cfs_copy_from_user(kernbuf, buffer, count))
1955 kernbuf[count] = '\0';
1962 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1966 if (end != NULL && *end == '.') {
1967 int temp_val, pow = 1;
1971 if (strlen(pbuf) > 5)
1972 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1974 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1977 for (i = 0; i < (end - pbuf); i++)
1980 *val += temp_val / pow;
1986 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
1989 long decimal_val, frac_val;
1995 decimal_val = val / mult;
1996 prtn = snprintf(buffer, count, "%ld", decimal_val);
1997 frac_val = val % mult;
1999 if (prtn < (count - 4) && frac_val > 0) {
2001 int i, temp_mult = 1, frac_bits = 0;
2003 temp_frac = frac_val * 10;
2004 buffer[prtn++] = '.';
2005 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2006 /* only reserved 2 bits fraction */
2007 buffer[prtn++] ='0';
2012 * Need to think these cases :
2013 * 1. #echo x.00 > /proc/xxx output result : x
2014 * 2. #echo x.0x > /proc/xxx output result : x.0x
2015 * 3. #echo x.x0 > /proc/xxx output result : x.x
2016 * 4. #echo x.xx > /proc/xxx output result : x.xx
2017 * Only reserved 2 bits fraction.
2019 for (i = 0; i < (5 - prtn); i++)
2022 frac_bits = min((int)count - prtn, 3 - frac_bits);
2023 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2024 frac_val * temp_mult / mult);
2027 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2029 if (buffer[prtn] == '.') {
2036 buffer[prtn++] ='\n';
2040 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2042 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2045 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2046 __u64 *val, int mult)
2048 char kernbuf[22], *end, *pbuf;
2049 __u64 whole, frac = 0, units;
2050 unsigned frac_d = 1;
2052 if (count > (sizeof(kernbuf) - 1))
2055 if (cfs_copy_from_user(kernbuf, buffer, count))
2058 kernbuf[count] = '\0';
2065 whole = simple_strtoull(pbuf, &end, 10);
2069 if (end != NULL && *end == '.') {
2073 /* need to limit frac_d to a __u32 */
2074 if (strlen(pbuf) > 10)
2077 frac = simple_strtoull(pbuf, &end, 10);
2078 /* count decimal places */
2079 for (i = 0; i < (end - pbuf); i++)
2096 /* Specified units override the multiplier */
2098 mult = mult < 0 ? -units : units;
2101 do_div(frac, frac_d);
2102 *val = whole * mult + frac;
2106 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2107 struct file_operations *seq_fops, void *data)
2109 struct proc_dir_entry *entry;
2112 LPROCFS_WRITE_ENTRY();
2113 entry = create_proc_entry(name, mode, parent);
2115 entry->proc_fops = seq_fops;
2118 LPROCFS_WRITE_EXIT();
2125 EXPORT_SYMBOL(lprocfs_seq_create);
2127 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2129 struct file_operations *seq_fops,
2132 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2133 mode, seq_fops, data));
2135 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2137 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2139 if (value >= OBD_HIST_MAX)
2140 value = OBD_HIST_MAX - 1;
2142 cfs_spin_lock(&oh->oh_lock);
2143 oh->oh_buckets[value]++;
2144 cfs_spin_unlock(&oh->oh_lock);
2146 EXPORT_SYMBOL(lprocfs_oh_tally);
2148 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2152 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2155 lprocfs_oh_tally(oh, val);
2157 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2159 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2161 unsigned long ret = 0;
2164 for (i = 0; i < OBD_HIST_MAX; i++)
2165 ret += oh->oh_buckets[i];
2168 EXPORT_SYMBOL(lprocfs_oh_sum);
2170 void lprocfs_oh_clear(struct obd_histogram *oh)
2172 cfs_spin_lock(&oh->oh_lock);
2173 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2174 cfs_spin_unlock(&oh->oh_lock);
2176 EXPORT_SYMBOL(lprocfs_oh_clear);
2178 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2179 int count, int *eof, void *data)
2181 struct obd_device *obd = data;
2187 c += cfs_hash_debug_header(page, count);
2188 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2189 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2190 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2191 #ifdef HAVE_QUOTA_SUPPORT
2192 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2193 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2194 page + c, count - c);
2199 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2201 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2202 int count, int *eof, void *data)
2204 struct obd_device *obd = data;
2207 LASSERT(obd != NULL);
2208 LASSERT(count >= 0);
2210 /* Set start of user data returned to
2211 page + off since the user may have
2212 requested to read much smaller than
2213 what we need to read */
2214 *start = page + off;
2216 /* We know we are allocated a page here.
2217 Also we know that this function will
2218 not need to write more than a page
2219 so we can truncate at CFS_PAGE_SIZE. */
2220 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2222 /* Initialize the page */
2223 memset(page, 0, size);
2225 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2227 if (obd->obd_max_recoverable_clients == 0) {
2228 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2234 /* sampled unlocked, but really... */
2235 if (obd->obd_recovering == 0) {
2236 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2238 if (lprocfs_obd_snprintf(&page, size, &len,
2239 "recovery_start: %lu\n",
2240 obd->obd_recovery_start) <= 0)
2242 if (lprocfs_obd_snprintf(&page, size, &len,
2243 "recovery_duration: %lu\n",
2244 obd->obd_recovery_end -
2245 obd->obd_recovery_start) <= 0)
2247 /* Number of clients that have completed recovery */
2248 if (lprocfs_obd_snprintf(&page, size, &len,
2249 "completed_clients: %d/%d\n",
2250 obd->obd_max_recoverable_clients -
2251 obd->obd_stale_clients,
2252 obd->obd_max_recoverable_clients) <= 0)
2254 if (lprocfs_obd_snprintf(&page, size, &len,
2255 "replayed_requests: %d\n",
2256 obd->obd_replayed_requests) <= 0)
2258 if (lprocfs_obd_snprintf(&page, size, &len,
2259 "last_transno: "LPD64"\n",
2260 obd->obd_next_recovery_transno - 1)<=0)
2262 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2263 obd->obd_version_recov ? "ON" : "OFF")<=0)
2268 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2270 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2271 obd->obd_recovery_start) <= 0)
2273 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2274 cfs_time_current_sec() >= obd->obd_recovery_end ? 0 :
2275 obd->obd_recovery_end - cfs_time_current_sec()) <= 0)
2277 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2278 obd->obd_connected_clients,
2279 obd->obd_max_recoverable_clients) <= 0)
2281 /* Number of clients that have completed recovery */
2282 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2283 cfs_atomic_read(&obd->obd_req_replay_clients))
2286 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2287 cfs_atomic_read(&obd->obd_lock_replay_clients))
2290 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2291 obd->obd_connected_clients -
2292 cfs_atomic_read(&obd->obd_lock_replay_clients))
2295 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2296 obd->obd_stale_clients) <= 0)
2298 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2299 obd->obd_replayed_requests) <= 0)
2301 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2302 obd->obd_requests_queued_for_recovery) <= 0)
2305 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2306 obd->obd_next_recovery_transno) <= 0)
2312 return min(count, len - (int)off);
2314 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2316 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2317 int count, int *eof, void *data)
2319 struct obd_device *obd = (struct obd_device *)data;
2320 LASSERT(obd != NULL);
2322 return snprintf(page, count, "%d\n",
2323 obd->obd_recovery_timeout);
2325 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2327 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2328 unsigned long count, void *data)
2330 struct obd_device *obd = (struct obd_device *)data;
2332 LASSERT(obd != NULL);
2334 rc = lprocfs_write_helper(buffer, count, &val);
2338 obd->obd_recovery_timeout = val;
2341 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2343 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2344 int count, int *eof, void *data)
2346 struct obd_device *obd = data;
2347 LASSERT(obd != NULL);
2349 return snprintf(page, count, "%lu\n", obd->obd_recovery_time_hard);
2351 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2353 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2354 unsigned long count, void *data)
2356 struct obd_device *obd = data;
2358 LASSERT(obd != NULL);
2360 rc = lprocfs_write_helper(buffer, count, &val);
2364 obd->obd_recovery_time_hard = val;
2367 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2369 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2370 int count, int *eof, void *data)
2372 struct obd_device *obd = (struct obd_device *)data;
2374 LASSERT(obd != NULL);
2375 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2377 return snprintf(page, count, "%s\n",
2378 obd->u.obt.obt_vfsmnt->mnt_devname);
2380 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2382 EXPORT_SYMBOL(lprocfs_register);
2383 EXPORT_SYMBOL(lprocfs_srch);
2384 EXPORT_SYMBOL(lprocfs_remove);
2385 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2386 EXPORT_SYMBOL(lprocfs_add_vars);
2387 EXPORT_SYMBOL(lprocfs_obd_setup);
2388 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2389 EXPORT_SYMBOL(lprocfs_add_simple);
2390 EXPORT_SYMBOL(lprocfs_add_symlink);
2391 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2392 EXPORT_SYMBOL(lprocfs_alloc_stats);
2393 EXPORT_SYMBOL(lprocfs_free_stats);
2394 EXPORT_SYMBOL(lprocfs_clear_stats);
2395 EXPORT_SYMBOL(lprocfs_register_stats);
2396 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2397 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2398 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2399 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2400 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2401 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2402 EXPORT_SYMBOL(lprocfs_free_md_stats);
2403 EXPORT_SYMBOL(lprocfs_exp_setup);
2404 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2406 EXPORT_SYMBOL(lprocfs_rd_u64);
2407 EXPORT_SYMBOL(lprocfs_rd_atomic);
2408 EXPORT_SYMBOL(lprocfs_wr_atomic);
2409 EXPORT_SYMBOL(lprocfs_rd_uint);
2410 EXPORT_SYMBOL(lprocfs_wr_uint);
2411 EXPORT_SYMBOL(lprocfs_rd_uuid);
2412 EXPORT_SYMBOL(lprocfs_rd_name);
2413 EXPORT_SYMBOL(lprocfs_rd_fstype);
2414 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2415 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2416 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2417 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2418 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2419 EXPORT_SYMBOL(lprocfs_rd_import);
2420 EXPORT_SYMBOL(lprocfs_rd_state);
2421 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2422 EXPORT_SYMBOL(lprocfs_rd_blksize);
2423 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2424 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2425 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2426 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2427 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2429 EXPORT_SYMBOL(lprocfs_write_helper);
2430 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2431 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2432 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2433 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2434 EXPORT_SYMBOL(lprocfs_stats_collect);