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",
816 int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
821 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
823 ret += snprintf(page + ret, count - ret, "%s%s",
824 ret ? sep : "", obd_connect_names[i]);
826 if (flags & ~(mask - 1))
827 ret += snprintf(page + ret, count - ret,
828 "%sunknown flags "LPX64,
829 ret ? sep : "", flags & ~(mask - 1));
832 EXPORT_SYMBOL(obd_connect_flags2str);
834 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
835 int *eof, void *data)
837 struct lprocfs_counter ret;
838 struct obd_device *obd = (struct obd_device *)data;
839 struct obd_import *imp;
840 struct obd_import_conn *conn;
843 LASSERT(obd != NULL);
844 LPROCFS_CLIMP_CHECK(obd);
845 imp = obd->u.cli.cl_import;
848 i = snprintf(page, count,
856 ptlrpc_import_state_name(imp->imp_state));
857 i += obd_connect_flags2str(page + i, count - i,
858 imp->imp_connect_data.ocd_connect_flags,
860 i += snprintf(page + i, count - i,
863 i += obd_import_flags2str(imp, page + i, count - i);
865 i += snprintf(page + i, count - i,
868 " failover_nids: [");
869 cfs_spin_lock(&imp->imp_lock);
871 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
872 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
873 libcfs_nid2str(conn->oic_conn->c_peer.nid));
876 cfs_spin_unlock(&imp->imp_lock);
877 i += snprintf(page + i, count - i,
879 " current_connection: %s\n"
880 " connection_attempts: %u\n"
882 " in-progress_invalidations: %u\n",
883 libcfs_nid2str(imp->imp_connection->c_peer.nid),
886 cfs_atomic_read(&imp->imp_inval_count));
888 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
889 if (ret.lc_count != 0) {
890 /* first argument to do_div MUST be __u64 */
891 __u64 sum = ret.lc_sum;
892 do_div(sum, ret.lc_count);
896 i += snprintf(page + i, count - i,
899 " unregistering: %u\n"
901 " avg_waittime: "LPU64" %s\n",
902 cfs_atomic_read(&imp->imp_inflight),
903 cfs_atomic_read(&imp->imp_unregistering),
904 cfs_atomic_read(&imp->imp_timeouts),
905 ret.lc_sum, ret.lc_units);
908 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
909 if (imp->imp_at.iat_portal[j] == 0)
911 k = max_t(unsigned int, k,
912 at_get(&imp->imp_at.iat_service_estimate[j]));
914 i += snprintf(page + i, count - i,
915 " service_estimates:\n"
916 " services: %u sec\n"
917 " network: %u sec\n",
919 at_get(&imp->imp_at.iat_net_latency));
921 i += snprintf(page + i, count - i,
923 " last_replay: "LPU64"\n"
924 " peer_committed: "LPU64"\n"
925 " last_checked: "LPU64"\n",
926 imp->imp_last_replay_transno,
927 imp->imp_peer_committed_transno,
928 imp->imp_last_transno_checked);
931 for (rw = 0; rw <= 1; rw++) {
932 lprocfs_stats_collect(obd->obd_svc_stats,
933 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
935 if (ret.lc_sum > 0 && ret.lc_count > 0) {
936 /* first argument to do_div MUST be __u64 */
937 __u64 sum = ret.lc_sum;
938 do_div(sum, ret.lc_count);
940 i += snprintf(page + i, count - i,
941 " %s_data_averages:\n"
942 " bytes_per_rpc: "LPU64"\n",
943 rw ? "write" : "read",
947 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
948 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
949 if (ret.lc_sum > 0 && ret.lc_count != 0) {
950 /* first argument to do_div MUST be __u64 */
951 __u64 sum = ret.lc_sum;
952 do_div(sum, ret.lc_count);
954 i += snprintf(page + i, count - i,
955 " %s_per_rpc: "LPU64"\n",
956 ret.lc_units, ret.lc_sum);
959 i += snprintf(page + i, count - i,
960 " MB_per_sec: %u.%.02u\n",
961 k / j, (100 * k / j) % 100);
965 LPROCFS_CLIMP_EXIT(obd);
969 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
970 int *eof, void *data)
972 struct obd_device *obd = (struct obd_device *)data;
973 struct obd_import *imp;
976 LASSERT(obd != NULL);
977 LPROCFS_CLIMP_CHECK(obd);
978 imp = obd->u.cli.cl_import;
981 i = snprintf(page, count, "current_state: %s\n",
982 ptlrpc_import_state_name(imp->imp_state));
983 i += snprintf(page + i, count - i,
985 k = imp->imp_state_hist_idx;
986 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
987 struct import_state_hist *ish =
988 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
989 if (ish->ish_state == 0)
991 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
993 ptlrpc_import_state_name(ish->ish_state));
996 LPROCFS_CLIMP_EXIT(obd);
1000 int lprocfs_at_hist_helper(char *page, int count, int rc,
1001 struct adaptive_timeout *at)
1004 for (i = 0; i < AT_BINS; i++)
1005 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1006 rc += snprintf(page + rc, count - rc, "\n");
1010 /* See also ptlrpc_lprocfs_rd_timeouts */
1011 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1012 int *eof, void *data)
1014 struct obd_device *obd = (struct obd_device *)data;
1015 struct obd_import *imp;
1016 unsigned int cur, worst;
1021 LASSERT(obd != NULL);
1022 LPROCFS_CLIMP_CHECK(obd);
1023 imp = obd->u.cli.cl_import;
1026 now = cfs_time_current_sec();
1028 /* Some network health info for kicks */
1029 s2dhms(&ts, now - imp->imp_last_reply_time);
1030 rc += snprintf(page + rc, count - rc,
1031 "%-10s : %ld, "DHMS_FMT" ago\n",
1032 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1034 cur = at_get(&imp->imp_at.iat_net_latency);
1035 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1036 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1037 s2dhms(&ts, now - worstt);
1038 rc += snprintf(page + rc, count - rc,
1039 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1040 "network", cur, worst, worstt, DHMS_VARS(&ts));
1041 rc = lprocfs_at_hist_helper(page, count, rc,
1042 &imp->imp_at.iat_net_latency);
1044 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1045 if (imp->imp_at.iat_portal[i] == 0)
1047 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1048 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1049 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1050 s2dhms(&ts, now - worstt);
1051 rc += snprintf(page + rc, count - rc,
1052 "portal %-2d : cur %3u worst %3u (at %ld, "
1053 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1054 cur, worst, worstt, DHMS_VARS(&ts));
1055 rc = lprocfs_at_hist_helper(page, count, rc,
1056 &imp->imp_at.iat_service_estimate[i]);
1059 LPROCFS_CLIMP_EXIT(obd);
1063 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1064 int count, int *eof, void *data)
1066 struct obd_device *obd = data;
1070 LPROCFS_CLIMP_CHECK(obd);
1071 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1072 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1073 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1074 ret += snprintf(page + ret, count - ret, "\n");
1075 LPROCFS_CLIMP_EXIT(obd);
1078 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1080 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1081 int *eof, void *data)
1083 struct obd_device *obd = data;
1085 LASSERT(obd != NULL);
1087 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1090 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1091 int *eof, void *data)
1093 struct obd_type *class = (struct obd_type*) data;
1095 LASSERT(class != NULL);
1097 return snprintf(page, count, "%d\n", class->typ_refcnt);
1100 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1104 LASSERT(obd != NULL);
1105 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1106 LASSERT(obd->obd_type->typ_procroot != NULL);
1108 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1109 obd->obd_type->typ_procroot,
1111 if (IS_ERR(obd->obd_proc_entry)) {
1112 rc = PTR_ERR(obd->obd_proc_entry);
1113 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1114 obd->obd_proc_entry = NULL;
1119 int lprocfs_obd_cleanup(struct obd_device *obd)
1123 if (obd->obd_proc_exports_entry) {
1124 /* Should be no exports left */
1125 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1126 lprocfs_remove(&obd->obd_proc_exports_entry);
1127 obd->obd_proc_exports_entry = NULL;
1129 if (obd->obd_proc_entry) {
1130 lprocfs_remove(&obd->obd_proc_entry);
1131 obd->obd_proc_entry = NULL;
1136 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1138 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1139 client_stat->nid_proc, client_stat->nid_stats,
1140 client_stat->nid_brw_stats);
1142 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1143 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1144 atomic_read(&client_stat->nid_exp_ref_count));
1146 cfs_hlist_del_init(&client_stat->nid_hash);
1148 if (client_stat->nid_proc)
1149 lprocfs_remove(&client_stat->nid_proc);
1151 if (client_stat->nid_stats)
1152 lprocfs_free_stats(&client_stat->nid_stats);
1154 if (client_stat->nid_brw_stats)
1155 OBD_FREE_PTR(client_stat->nid_brw_stats);
1157 if (client_stat->nid_ldlm_stats)
1158 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1160 OBD_FREE_PTR(client_stat);
1165 void lprocfs_free_per_client_stats(struct obd_device *obd)
1167 struct nid_stat *stat;
1170 /* we need extra list - because hash_exit called to early */
1171 /* not need locking because all clients is died */
1172 while(!cfs_list_empty(&obd->obd_nid_stats)) {
1173 stat = cfs_list_entry(obd->obd_nid_stats.next,
1174 struct nid_stat, nid_list);
1175 cfs_list_del_init(&stat->nid_list);
1176 lprocfs_free_client_stats(stat);
1182 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1183 enum lprocfs_stats_flags flags)
1185 struct lprocfs_stats *stats;
1186 unsigned int percpusize;
1188 unsigned int num_cpu;
1193 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1196 num_cpu = cfs_num_possible_cpus();
1198 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1202 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1203 stats->ls_flags = flags;
1204 cfs_spin_lock_init(&stats->ls_lock);
1205 /* Use this lock only if there are no percpu areas */
1207 stats->ls_flags = 0;
1210 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1212 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1214 for (i = 0; i < num_cpu; i++) {
1215 OBD_ALLOC(stats->ls_percpu[i], percpusize);
1216 if (stats->ls_percpu[i] == NULL) {
1217 for (j = 0; j < i; j++) {
1218 OBD_FREE(stats->ls_percpu[j], percpusize);
1219 stats->ls_percpu[j] = NULL;
1224 if (stats->ls_percpu[0] == NULL) {
1225 OBD_FREE(stats, offsetof(typeof(*stats),
1226 ls_percpu[num_cpu]));
1230 stats->ls_num = num;
1234 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1236 struct lprocfs_stats *stats = *statsh;
1237 unsigned int num_cpu;
1238 unsigned int percpusize;
1241 if (stats == NULL || stats->ls_num == 0)
1245 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1248 num_cpu = cfs_num_possible_cpus();
1250 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1252 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1253 for (i = 0; i < num_cpu; i++)
1254 OBD_FREE(stats->ls_percpu[i], percpusize);
1255 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1258 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1260 struct lprocfs_counter *percpu_cntr;
1262 unsigned int num_cpu;
1264 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1266 for (i = 0; i < num_cpu; i++) {
1267 for (j = 0; j < stats->ls_num; j++) {
1268 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1269 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1270 percpu_cntr->lc_count = 0;
1271 percpu_cntr->lc_sum = 0;
1272 percpu_cntr->lc_min = LC_MIN_INIT;
1273 percpu_cntr->lc_max = 0;
1274 percpu_cntr->lc_sumsquare = 0;
1275 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1279 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1282 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1283 size_t len, loff_t *off)
1285 struct seq_file *seq = file->private_data;
1286 struct lprocfs_stats *stats = seq->private;
1288 lprocfs_clear_stats(stats);
1293 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1295 struct lprocfs_stats *stats = p->private;
1296 /* return 1st cpu location */
1297 return (*pos >= stats->ls_num) ? NULL :
1298 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1301 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1305 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1307 struct lprocfs_stats *stats = p->private;
1309 return (*pos >= stats->ls_num) ? NULL :
1310 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1313 /* seq file export of one lprocfs counter */
1314 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1316 struct lprocfs_stats *stats = p->private;
1317 struct lprocfs_counter *cntr = v;
1318 struct lprocfs_counter ret;
1321 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1323 cfs_gettimeofday(&now);
1324 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1325 "snapshot_time", now.tv_sec, now.tv_usec);
1329 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1331 lprocfs_stats_collect(stats, idx, &ret);
1333 if (ret.lc_count == 0)
1336 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1337 ret.lc_count, cntr->lc_units);
1342 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1343 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1344 ret.lc_min, ret.lc_max, ret.lc_sum);
1347 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1348 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1352 rc = seq_printf(p, "\n");
1354 return (rc < 0) ? rc : 0;
1357 struct seq_operations lprocfs_stats_seq_sops = {
1358 start: lprocfs_stats_seq_start,
1359 stop: lprocfs_stats_seq_stop,
1360 next: lprocfs_stats_seq_next,
1361 show: lprocfs_stats_seq_show,
1364 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1366 struct proc_dir_entry *dp = PDE(inode);
1367 struct seq_file *seq;
1370 if (LPROCFS_ENTRY_AND_CHECK(dp))
1373 rc = seq_open(file, &lprocfs_stats_seq_sops);
1378 seq = file->private_data;
1379 seq->private = dp->data;
1383 struct file_operations lprocfs_stats_seq_fops = {
1384 .owner = THIS_MODULE,
1385 .open = lprocfs_stats_seq_open,
1387 .write = lprocfs_stats_seq_write,
1388 .llseek = seq_lseek,
1389 .release = lprocfs_seq_release,
1392 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1393 struct lprocfs_stats *stats)
1395 struct proc_dir_entry *entry;
1396 LASSERT(root != NULL);
1398 LPROCFS_WRITE_ENTRY();
1399 entry = create_proc_entry(name, 0644, root);
1401 entry->proc_fops = &lprocfs_stats_seq_fops;
1402 entry->data = stats;
1405 LPROCFS_WRITE_EXIT();
1413 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1414 unsigned conf, const char *name, const char *units)
1416 struct lprocfs_counter *c;
1418 unsigned int num_cpu;
1420 LASSERT(stats != NULL);
1422 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1424 for (i = 0; i < num_cpu; i++) {
1425 c = &(stats->ls_percpu[i]->lp_cntr[index]);
1426 c->lc_config = conf;
1429 c->lc_min = LC_MIN_INIT;
1432 c->lc_units = units;
1435 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1437 EXPORT_SYMBOL(lprocfs_counter_init);
1439 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1441 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1442 LASSERT(coffset < stats->ls_num); \
1443 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1446 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1448 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1449 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1450 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1451 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1452 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1453 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1454 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1455 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1456 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1457 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1458 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1459 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1460 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1461 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1462 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1463 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1467 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1468 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1469 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1470 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1471 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1472 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1473 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1474 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1475 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1476 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1477 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1478 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1479 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1480 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1481 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1482 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1483 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1484 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1485 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1486 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1487 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1488 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1489 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1490 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1491 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1492 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1493 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1494 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1495 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1496 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1497 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1498 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1499 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1500 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1501 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1502 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1503 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1504 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1505 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1506 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1507 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1508 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1509 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1510 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1511 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1512 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1513 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1514 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1515 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1516 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1519 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1521 struct lprocfs_stats *stats;
1522 unsigned int num_stats;
1525 LASSERT(obd->obd_stats == NULL);
1526 LASSERT(obd->obd_proc_entry != NULL);
1527 LASSERT(obd->obd_cntr_base == 0);
1529 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1530 num_private_stats - 1 /* o_owner */;
1531 stats = lprocfs_alloc_stats(num_stats, 0);
1535 lprocfs_init_ops_stats(num_private_stats, stats);
1537 for (i = num_private_stats; i < num_stats; i++) {
1538 /* If this LBUGs, it is likely that an obd
1539 * operation was added to struct obd_ops in
1540 * <obd.h>, and that the corresponding line item
1541 * LPROCFS_OBD_OP_INIT(.., .., opname)
1542 * is missing from the list above. */
1543 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1544 "Missing obd_stat initializer obd_op "
1545 "operation at offset %d.\n", i - num_private_stats);
1547 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1549 lprocfs_free_stats(&stats);
1551 obd->obd_stats = stats;
1552 obd->obd_cntr_base = num_private_stats;
1557 void lprocfs_free_obd_stats(struct obd_device *obd)
1560 lprocfs_free_stats(&obd->obd_stats);
1563 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1565 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1566 LASSERT(coffset < stats->ls_num); \
1567 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1570 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1572 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1573 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1574 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1575 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1576 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1577 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1578 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1579 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1580 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1581 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1582 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1583 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1584 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1585 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1586 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1587 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1588 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1589 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1590 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1591 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1592 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1593 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1594 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1595 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1596 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1597 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1598 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1599 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1600 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1601 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1602 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1603 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1606 int lprocfs_alloc_md_stats(struct obd_device *obd,
1607 unsigned num_private_stats)
1609 struct lprocfs_stats *stats;
1610 unsigned int num_stats;
1613 LASSERT(obd->md_stats == NULL);
1614 LASSERT(obd->obd_proc_entry != NULL);
1615 LASSERT(obd->md_cntr_base == 0);
1617 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1619 stats = lprocfs_alloc_stats(num_stats, 0);
1623 lprocfs_init_mps_stats(num_private_stats, stats);
1625 for (i = num_private_stats; i < num_stats; i++) {
1626 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1627 CERROR("Missing md_stat initializer md_op "
1628 "operation at offset %d. Aborting.\n",
1629 i - num_private_stats);
1633 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1635 lprocfs_free_stats(&stats);
1637 obd->md_stats = stats;
1638 obd->md_cntr_base = num_private_stats;
1643 void lprocfs_free_md_stats(struct obd_device *obd)
1645 struct lprocfs_stats *stats = obd->md_stats;
1647 if (stats != NULL) {
1648 obd->md_stats = NULL;
1649 obd->md_cntr_base = 0;
1650 lprocfs_free_stats(&stats);
1654 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1656 lprocfs_counter_init(ldlm_stats,
1657 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1658 0, "ldlm_enqueue", "reqs");
1659 lprocfs_counter_init(ldlm_stats,
1660 LDLM_CONVERT - LDLM_FIRST_OPC,
1661 0, "ldlm_convert", "reqs");
1662 lprocfs_counter_init(ldlm_stats,
1663 LDLM_CANCEL - LDLM_FIRST_OPC,
1664 0, "ldlm_cancel", "reqs");
1665 lprocfs_counter_init(ldlm_stats,
1666 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1667 0, "ldlm_bl_callback", "reqs");
1668 lprocfs_counter_init(ldlm_stats,
1669 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1670 0, "ldlm_cp_callback", "reqs");
1671 lprocfs_counter_init(ldlm_stats,
1672 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1673 0, "ldlm_gl_callback", "reqs");
1676 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1677 int *eof, void *data)
1679 struct obd_export *exp = data;
1680 LASSERT(exp != NULL);
1682 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1685 struct exp_uuid_cb_data {
1693 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1694 int count, int *eof, int *len)
1696 cb_data->page = page;
1697 cb_data->count = count;
1702 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1703 cfs_hlist_node_t *hnode, void *cb_data)
1706 struct obd_export *exp = cfs_hash_object(hs, hnode);
1707 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1709 if (exp->exp_nid_stats)
1710 *data->len += snprintf((data->page + *data->len),
1711 data->count, "%s\n",
1712 obd_uuid2str(&exp->exp_client_uuid));
1716 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1717 int *eof, void *data)
1719 struct nid_stat *stats = (struct nid_stat *)data;
1720 struct exp_uuid_cb_data cb_data;
1721 struct obd_device *obd = stats->nid_obd;
1726 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1727 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1728 lprocfs_exp_print_uuid, &cb_data);
1729 return (*cb_data.len);
1732 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1733 cfs_hlist_node_t *hnode, void *cb_data)
1736 struct exp_uuid_cb_data *data = cb_data;
1737 struct obd_export *exp = cfs_hash_object(hs, hnode);
1739 if (exp->exp_lock_hash != NULL) {
1741 *data->len += cfs_hash_debug_header(data->page,
1744 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1751 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1752 int *eof, void *data)
1754 struct nid_stat *stats = (struct nid_stat *)data;
1755 struct exp_uuid_cb_data cb_data;
1756 struct obd_device *obd = stats->nid_obd;
1761 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1763 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1764 lprocfs_exp_print_hash, &cb_data);
1765 return (*cb_data.len);
1768 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1769 int count, int *eof, void *data)
1772 return snprintf(page, count, "%s\n",
1773 "Write into this file to clear all nid stats and "
1774 "stale nid entries");
1776 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1778 int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1780 struct nid_stat *stat = obj;
1784 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1785 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1786 /* object has only hash references. */
1787 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1788 cfs_list_move(&stat->nid_list, data);
1789 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1792 /* we has reference to object - only clear data*/
1793 if (stat->nid_stats)
1794 lprocfs_clear_stats(stat->nid_stats);
1796 if (stat->nid_brw_stats) {
1797 for (i = 0; i < BRW_LAST; i++)
1798 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1803 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1804 unsigned long count, void *data)
1806 struct obd_device *obd = (struct obd_device *)data;
1807 struct nid_stat *client_stat;
1808 CFS_LIST_HEAD(free_list);
1810 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1811 lprocfs_nid_stats_clear_write_cb, &free_list);
1813 while (!cfs_list_empty(&free_list)) {
1814 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1816 cfs_list_del_init(&client_stat->nid_list);
1817 lprocfs_free_client_stats(client_stat);
1822 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1824 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1826 struct nid_stat *new_stat, *old_stat;
1827 struct obd_device *obd = NULL;
1828 cfs_proc_dir_entry_t *entry;
1829 char *buffer = NULL;
1835 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1836 !exp->exp_obd->obd_nid_stats_hash)
1839 /* not test against zero because eric say:
1840 * You may only test nid against another nid, or LNET_NID_ANY.
1841 * Anything else is nonsense.*/
1842 if (!nid || *nid == LNET_NID_ANY)
1847 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1849 OBD_ALLOC_PTR(new_stat);
1850 if (new_stat == NULL)
1853 new_stat->nid = *nid;
1854 new_stat->nid_obd = exp->exp_obd;
1855 /* we need set default refcount to 1 to balance obd_disconnect */
1856 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1858 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1859 nid, &new_stat->nid_hash);
1860 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1861 old_stat, libcfs_nid2str(*nid),
1862 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1864 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1865 * been and will never be called. */
1866 if (exp->exp_nid_stats) {
1867 nidstat_putref(exp->exp_nid_stats);
1868 exp->exp_nid_stats = NULL;
1871 /* Return -EALREADY here so that we know that the /proc
1872 * entry already has been created */
1873 if (old_stat != new_stat) {
1874 exp->exp_nid_stats = old_stat;
1875 GOTO(destroy_new, rc = -EALREADY);
1877 /* not found - create */
1878 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1880 GOTO(destroy_new, rc = -ENOMEM);
1882 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1883 new_stat->nid_proc = lprocfs_register(buffer,
1884 obd->obd_proc_exports_entry,
1886 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1888 if (new_stat->nid_proc == NULL) {
1889 CERROR("Error making export directory for nid %s\n",
1890 libcfs_nid2str(*nid));
1891 GOTO(destroy_new_ns, rc = -ENOMEM);
1894 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1895 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1896 if (IS_ERR(entry)) {
1897 CWARN("Error adding the NID stats file\n");
1898 rc = PTR_ERR(entry);
1899 GOTO(destroy_new_ns, rc);
1902 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1903 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1904 if (IS_ERR(entry)) {
1905 CWARN("Error adding the hash file\n");
1906 rc = PTR_ERR(entry);
1907 GOTO(destroy_new_ns, rc);
1910 exp->exp_nid_stats = new_stat;
1912 /* protect competitive add to list, not need locking on destroy */
1913 cfs_spin_lock(&obd->obd_nid_lock);
1914 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1915 cfs_spin_unlock(&obd->obd_nid_lock);
1920 if (new_stat->nid_proc != NULL)
1921 lprocfs_remove(&new_stat->nid_proc);
1922 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1925 nidstat_putref(new_stat);
1926 OBD_FREE_PTR(new_stat);
1930 int lprocfs_exp_cleanup(struct obd_export *exp)
1932 struct nid_stat *stat = exp->exp_nid_stats;
1934 if(!stat || !exp->exp_obd)
1937 nidstat_putref(exp->exp_nid_stats);
1938 exp->exp_nid_stats = NULL;
1943 int lprocfs_write_helper(const char *buffer, unsigned long count,
1946 return lprocfs_write_frac_helper(buffer, count, val, 1);
1949 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1952 char kernbuf[20], *end, *pbuf;
1954 if (count > (sizeof(kernbuf) - 1))
1957 if (cfs_copy_from_user(kernbuf, buffer, count))
1960 kernbuf[count] = '\0';
1967 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1971 if (end != NULL && *end == '.') {
1972 int temp_val, pow = 1;
1976 if (strlen(pbuf) > 5)
1977 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1979 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1982 for (i = 0; i < (end - pbuf); i++)
1985 *val += temp_val / pow;
1991 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
1994 long decimal_val, frac_val;
2000 decimal_val = val / mult;
2001 prtn = snprintf(buffer, count, "%ld", decimal_val);
2002 frac_val = val % mult;
2004 if (prtn < (count - 4) && frac_val > 0) {
2006 int i, temp_mult = 1, frac_bits = 0;
2008 temp_frac = frac_val * 10;
2009 buffer[prtn++] = '.';
2010 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2011 /* only reserved 2 bits fraction */
2012 buffer[prtn++] ='0';
2017 * Need to think these cases :
2018 * 1. #echo x.00 > /proc/xxx output result : x
2019 * 2. #echo x.0x > /proc/xxx output result : x.0x
2020 * 3. #echo x.x0 > /proc/xxx output result : x.x
2021 * 4. #echo x.xx > /proc/xxx output result : x.xx
2022 * Only reserved 2 bits fraction.
2024 for (i = 0; i < (5 - prtn); i++)
2027 frac_bits = min((int)count - prtn, 3 - frac_bits);
2028 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2029 frac_val * temp_mult / mult);
2032 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2034 if (buffer[prtn] == '.') {
2041 buffer[prtn++] ='\n';
2045 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2047 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2050 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2051 __u64 *val, int mult)
2053 char kernbuf[22], *end, *pbuf;
2054 __u64 whole, frac = 0, units;
2055 unsigned frac_d = 1;
2057 if (count > (sizeof(kernbuf) - 1))
2060 if (cfs_copy_from_user(kernbuf, buffer, count))
2063 kernbuf[count] = '\0';
2070 whole = simple_strtoull(pbuf, &end, 10);
2074 if (end != NULL && *end == '.') {
2078 /* need to limit frac_d to a __u32 */
2079 if (strlen(pbuf) > 10)
2082 frac = simple_strtoull(pbuf, &end, 10);
2083 /* count decimal places */
2084 for (i = 0; i < (end - pbuf); i++)
2101 /* Specified units override the multiplier */
2103 mult = mult < 0 ? -units : units;
2106 do_div(frac, frac_d);
2107 *val = whole * mult + frac;
2111 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2112 struct file_operations *seq_fops, void *data)
2114 struct proc_dir_entry *entry;
2117 LPROCFS_WRITE_ENTRY();
2118 entry = create_proc_entry(name, mode, parent);
2120 entry->proc_fops = seq_fops;
2123 LPROCFS_WRITE_EXIT();
2130 EXPORT_SYMBOL(lprocfs_seq_create);
2132 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2134 struct file_operations *seq_fops,
2137 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2138 mode, seq_fops, data));
2140 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2142 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2144 if (value >= OBD_HIST_MAX)
2145 value = OBD_HIST_MAX - 1;
2147 cfs_spin_lock(&oh->oh_lock);
2148 oh->oh_buckets[value]++;
2149 cfs_spin_unlock(&oh->oh_lock);
2151 EXPORT_SYMBOL(lprocfs_oh_tally);
2153 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2157 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2160 lprocfs_oh_tally(oh, val);
2162 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2164 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2166 unsigned long ret = 0;
2169 for (i = 0; i < OBD_HIST_MAX; i++)
2170 ret += oh->oh_buckets[i];
2173 EXPORT_SYMBOL(lprocfs_oh_sum);
2175 void lprocfs_oh_clear(struct obd_histogram *oh)
2177 cfs_spin_lock(&oh->oh_lock);
2178 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2179 cfs_spin_unlock(&oh->oh_lock);
2181 EXPORT_SYMBOL(lprocfs_oh_clear);
2183 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2184 int count, int *eof, void *data)
2186 struct obd_device *obd = data;
2192 c += cfs_hash_debug_header(page, count);
2193 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2194 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2195 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2196 #ifdef HAVE_QUOTA_SUPPORT
2197 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2198 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2199 page + c, count - c);
2204 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2206 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2207 int count, int *eof, void *data)
2209 struct obd_device *obd = data;
2212 LASSERT(obd != NULL);
2213 LASSERT(count >= 0);
2215 /* Set start of user data returned to
2216 page + off since the user may have
2217 requested to read much smaller than
2218 what we need to read */
2219 *start = page + off;
2221 /* We know we are allocated a page here.
2222 Also we know that this function will
2223 not need to write more than a page
2224 so we can truncate at CFS_PAGE_SIZE. */
2225 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2227 /* Initialize the page */
2228 memset(page, 0, size);
2230 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2232 if (obd->obd_max_recoverable_clients == 0) {
2233 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2239 /* sampled unlocked, but really... */
2240 if (obd->obd_recovering == 0) {
2241 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2243 if (lprocfs_obd_snprintf(&page, size, &len,
2244 "recovery_start: %lu\n",
2245 obd->obd_recovery_start) <= 0)
2247 if (lprocfs_obd_snprintf(&page, size, &len,
2248 "recovery_duration: %lu\n",
2249 obd->obd_recovery_end -
2250 obd->obd_recovery_start) <= 0)
2252 /* Number of clients that have completed recovery */
2253 if (lprocfs_obd_snprintf(&page, size, &len,
2254 "completed_clients: %d/%d\n",
2255 obd->obd_max_recoverable_clients -
2256 obd->obd_stale_clients,
2257 obd->obd_max_recoverable_clients) <= 0)
2259 if (lprocfs_obd_snprintf(&page, size, &len,
2260 "replayed_requests: %d\n",
2261 obd->obd_replayed_requests) <= 0)
2263 if (lprocfs_obd_snprintf(&page, size, &len,
2264 "last_transno: "LPD64"\n",
2265 obd->obd_next_recovery_transno - 1)<=0)
2267 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2268 obd->obd_version_recov ? "ON" : "OFF")<=0)
2273 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2275 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2276 obd->obd_recovery_start) <= 0)
2278 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2279 cfs_time_current_sec() >= obd->obd_recovery_end ? 0 :
2280 obd->obd_recovery_end - cfs_time_current_sec()) <= 0)
2282 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2283 obd->obd_connected_clients,
2284 obd->obd_max_recoverable_clients) <= 0)
2286 /* Number of clients that have completed recovery */
2287 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2288 cfs_atomic_read(&obd->obd_req_replay_clients))
2291 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2292 cfs_atomic_read(&obd->obd_lock_replay_clients))
2295 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2296 obd->obd_connected_clients -
2297 cfs_atomic_read(&obd->obd_lock_replay_clients))
2300 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2301 obd->obd_stale_clients) <= 0)
2303 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2304 obd->obd_replayed_requests) <= 0)
2306 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2307 obd->obd_requests_queued_for_recovery) <= 0)
2310 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2311 obd->obd_next_recovery_transno) <= 0)
2317 return min(count, len - (int)off);
2319 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2321 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2322 int count, int *eof, void *data)
2324 struct obd_device *obd = (struct obd_device *)data;
2325 LASSERT(obd != NULL);
2327 return snprintf(page, count, "%d\n",
2328 obd->obd_recovery_timeout);
2330 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2332 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2333 unsigned long count, void *data)
2335 struct obd_device *obd = (struct obd_device *)data;
2337 LASSERT(obd != NULL);
2339 rc = lprocfs_write_helper(buffer, count, &val);
2343 obd->obd_recovery_timeout = val;
2346 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2348 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2349 int count, int *eof, void *data)
2351 struct obd_device *obd = data;
2352 LASSERT(obd != NULL);
2354 return snprintf(page, count, "%lu\n", obd->obd_recovery_time_hard);
2356 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2358 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2359 unsigned long count, void *data)
2361 struct obd_device *obd = data;
2363 LASSERT(obd != NULL);
2365 rc = lprocfs_write_helper(buffer, count, &val);
2369 obd->obd_recovery_time_hard = val;
2372 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2374 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2375 int count, int *eof, void *data)
2377 struct obd_device *obd = (struct obd_device *)data;
2379 LASSERT(obd != NULL);
2380 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2382 return snprintf(page, count, "%s\n",
2383 obd->u.obt.obt_vfsmnt->mnt_devname);
2385 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2387 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2388 int count, int *eof, void *data)
2390 struct obd_device *dev = data;
2391 struct client_obd *cli = &dev->u.cli;
2394 client_obd_list_lock(&cli->cl_loi_list_lock);
2395 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2396 client_obd_list_unlock(&cli->cl_loi_list_lock);
2399 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2401 int lprocfs_obd_wr_max_pages_per_rpc(struct file *file, const char *buffer,
2402 unsigned long count, void *data)
2404 struct obd_device *dev = data;
2405 struct client_obd *cli = &dev->u.cli;
2406 struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
2409 rc = lprocfs_write_helper(buffer, count, &val);
2413 LPROCFS_CLIMP_CHECK(dev);
2414 if (val < 1 || val > ocd->ocd_brw_size >> CFS_PAGE_SHIFT) {
2415 LPROCFS_CLIMP_EXIT(dev);
2418 client_obd_list_lock(&cli->cl_loi_list_lock);
2419 cli->cl_max_pages_per_rpc = val;
2420 client_obd_list_unlock(&cli->cl_loi_list_lock);
2422 LPROCFS_CLIMP_EXIT(dev);
2425 EXPORT_SYMBOL(lprocfs_obd_wr_max_pages_per_rpc);
2427 EXPORT_SYMBOL(lprocfs_register);
2428 EXPORT_SYMBOL(lprocfs_srch);
2429 EXPORT_SYMBOL(lprocfs_remove);
2430 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2431 EXPORT_SYMBOL(lprocfs_add_vars);
2432 EXPORT_SYMBOL(lprocfs_obd_setup);
2433 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2434 EXPORT_SYMBOL(lprocfs_add_simple);
2435 EXPORT_SYMBOL(lprocfs_add_symlink);
2436 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2437 EXPORT_SYMBOL(lprocfs_alloc_stats);
2438 EXPORT_SYMBOL(lprocfs_free_stats);
2439 EXPORT_SYMBOL(lprocfs_clear_stats);
2440 EXPORT_SYMBOL(lprocfs_register_stats);
2441 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2442 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2443 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2444 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2445 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2446 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2447 EXPORT_SYMBOL(lprocfs_free_md_stats);
2448 EXPORT_SYMBOL(lprocfs_exp_setup);
2449 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2451 EXPORT_SYMBOL(lprocfs_rd_u64);
2452 EXPORT_SYMBOL(lprocfs_rd_atomic);
2453 EXPORT_SYMBOL(lprocfs_wr_atomic);
2454 EXPORT_SYMBOL(lprocfs_rd_uint);
2455 EXPORT_SYMBOL(lprocfs_wr_uint);
2456 EXPORT_SYMBOL(lprocfs_rd_uuid);
2457 EXPORT_SYMBOL(lprocfs_rd_name);
2458 EXPORT_SYMBOL(lprocfs_rd_fstype);
2459 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2460 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2461 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2462 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2463 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2464 EXPORT_SYMBOL(lprocfs_rd_import);
2465 EXPORT_SYMBOL(lprocfs_rd_state);
2466 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2467 EXPORT_SYMBOL(lprocfs_rd_blksize);
2468 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2469 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2470 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2471 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2472 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2474 EXPORT_SYMBOL(lprocfs_write_helper);
2475 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2476 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2477 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2478 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2479 EXPORT_SYMBOL(lprocfs_stats_collect);