1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
30 * Use is subject to license terms.
33 * Copyright (c) 2011 Whamcloud, Inc.
36 * This file is part of Lustre, http://www.lustre.org/
37 * Lustre is a trademark of Sun Microsystems, Inc.
39 * lustre/obdclass/lprocfs_status.c
41 * Author: Hariharan Thantry <thantry@users.sourceforge.net>
45 # define EXPORT_SYMTAB
47 #define DEBUG_SUBSYSTEM S_CLASS
50 # include <liblustre.h>
53 #include <obd_class.h>
54 #include <lprocfs_status.h>
55 #include <lustre_fsfilt.h>
56 #include <lustre_log.h>
57 #include <lustre/lustre_idl.h>
61 #define MAX_STRING_SIZE 128
63 /* for bug 10866, global variable */
64 CFS_DECLARE_RWSEM(_lprocfs_lock);
65 EXPORT_SYMBOL(_lprocfs_lock);
67 int lprocfs_seq_release(struct inode *inode, struct file *file)
70 return seq_release(inode, file);
72 EXPORT_SYMBOL(lprocfs_seq_release);
74 static struct proc_dir_entry *__lprocfs_srch(struct proc_dir_entry *head,
77 struct proc_dir_entry *temp;
83 while (temp != NULL) {
84 if (strcmp(temp->name, name) == 0) {
93 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
96 struct proc_dir_entry *temp;
99 temp = __lprocfs_srch(head, name);
104 /* lprocfs API calls */
106 /* Function that emulates snprintf but also has the side effect of advancing
107 the page pointer for the next write into the buffer, incrementing the total
108 length written to the buffer, and decrementing the size left in the
110 static int lprocfs_obd_snprintf(char **page, int end, int *len,
111 const char *format, ...)
119 va_start(list, format);
120 n = vsnprintf(*page, end - *len, format, list);
123 *page += n; *len += n;
127 cfs_proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
129 read_proc_t *read_proc,
130 write_proc_t *write_proc,
132 struct file_operations *fops)
134 cfs_proc_dir_entry_t *proc;
137 if (root == NULL || name == NULL)
138 return ERR_PTR(-EINVAL);
145 LPROCFS_WRITE_ENTRY();
146 proc = create_proc_entry(name, mode, root);
148 CERROR("LprocFS: No memory to create /proc entry %s", name);
149 LPROCFS_WRITE_EXIT();
150 return ERR_PTR(-ENOMEM);
152 proc->read_proc = read_proc;
153 proc->write_proc = write_proc;
156 proc->proc_fops = fops;
157 LPROCFS_WRITE_EXIT();
161 struct proc_dir_entry *lprocfs_add_symlink(const char *name,
162 struct proc_dir_entry *parent, const char *format, ...)
164 struct proc_dir_entry *entry;
168 if (parent == NULL || format == NULL)
171 OBD_ALLOC_WAIT(dest, MAX_STRING_SIZE + 1);
175 va_start(ap, format);
176 vsnprintf(dest, MAX_STRING_SIZE, format, ap);
179 entry = proc_symlink(name, parent, dest);
181 CERROR("LprocFS: Could not create symbolic link from %s to %s",
184 OBD_FREE(dest, MAX_STRING_SIZE + 1);
188 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
189 size_t size, loff_t *ppos)
191 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
192 char *page, *start = NULL;
193 int rc = 0, eof = 1, count;
195 if (*ppos >= CFS_PAGE_SIZE)
198 page = (char *)__get_free_page(GFP_KERNEL);
202 if (LPROCFS_ENTRY_AND_CHECK(dp)) {
207 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
209 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
215 /* for lustre proc read, the read count must be less than PAGE_SIZE */
224 start = page + *ppos;
225 } else if (start < page) {
229 count = (rc < size) ? rc : size;
230 if (cfs_copy_to_user(buf, start, count)) {
237 free_page((unsigned long)page);
241 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
242 size_t size, loff_t *ppos)
244 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
247 if (LPROCFS_ENTRY_AND_CHECK(dp))
250 rc = dp->write_proc(f, buf, size, dp->data);
255 static struct file_operations lprocfs_generic_fops = {
256 .owner = THIS_MODULE,
257 .read = lprocfs_fops_read,
258 .write = lprocfs_fops_write,
261 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
263 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
264 struct obd_device *obd = dp->data;
266 cfs_atomic_inc(&obd->obd_evict_inprogress);
271 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
273 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
274 struct obd_device *obd = dp->data;
276 cfs_atomic_dec(&obd->obd_evict_inprogress);
277 cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
282 struct file_operations lprocfs_evict_client_fops = {
283 .owner = THIS_MODULE,
284 .read = lprocfs_fops_read,
285 .write = lprocfs_fops_write,
286 .open = lprocfs_evict_client_open,
287 .release = lprocfs_evict_client_release,
289 EXPORT_SYMBOL(lprocfs_evict_client_fops);
294 * \param root [in] The parent proc entry on which new entry will be added.
295 * \param list [in] Array of proc entries to be added.
296 * \param data [in] The argument to be passed when entries read/write routines
297 * are called through /proc file.
299 * \retval 0 on success
302 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
307 if (root == NULL || list == NULL)
310 LPROCFS_WRITE_ENTRY();
311 while (list->name != NULL) {
312 struct proc_dir_entry *cur_root, *proc;
313 char *pathcopy, *cur, *next, pathbuf[64];
314 int pathsize = strlen(list->name) + 1;
319 /* need copy of path for strsep */
320 if (strlen(list->name) > sizeof(pathbuf) - 1) {
321 OBD_ALLOC(pathcopy, pathsize);
322 if (pathcopy == NULL)
323 GOTO(out, rc = -ENOMEM);
329 strcpy(pathcopy, list->name);
331 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
332 if (*cur =='\0') /* skip double/trailing "/" */
335 proc = __lprocfs_srch(cur_root, cur);
336 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
337 cur_root->name, cur, next,
338 (proc ? "exists" : "new"));
340 cur_root = (proc ? proc :
341 proc_mkdir(cur, cur_root));
342 } else if (proc == NULL) {
344 if (list->proc_mode != 0000) {
345 mode = list->proc_mode;
349 if (list->write_fptr)
352 proc = create_proc_entry(cur, mode, cur_root);
356 if (pathcopy != pathbuf)
357 OBD_FREE(pathcopy, pathsize);
359 if (cur_root == NULL || proc == NULL) {
360 CERROR("LprocFS: No memory to create /proc entry %s",
362 GOTO(out, rc = -ENOMEM);
366 proc->proc_fops = list->fops;
368 proc->proc_fops = &lprocfs_generic_fops;
369 proc->read_proc = list->read_fptr;
370 proc->write_proc = list->write_fptr;
371 proc->data = (list->data ? list->data : data);
375 LPROCFS_WRITE_EXIT();
379 void lprocfs_remove(struct proc_dir_entry **rooth)
381 struct proc_dir_entry *root = *rooth;
382 struct proc_dir_entry *temp = root;
383 struct proc_dir_entry *rm_entry;
384 struct proc_dir_entry *parent;
390 parent = root->parent;
391 LASSERT(parent != NULL);
392 LPROCFS_WRITE_ENTRY(); /* search vs remove race */
395 while (temp->subdir != NULL)
401 /* Memory corruption once caused this to fail, and
402 without this LASSERT we would loop here forever. */
403 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
404 "0x%p %s/%s len %d\n", rm_entry, temp->name,
405 rm_entry->name, (int)strlen(rm_entry->name));
407 #ifdef HAVE_PROCFS_USERS
408 /* if procfs uses user count to synchronize deletion of
409 * proc entry, there is no protection for rm_entry->data,
410 * then lprocfs_fops_read and lprocfs_fops_write maybe
411 * call proc_dir_entry->read_proc (or write_proc) with
412 * proc_dir_entry->data == NULL, then cause kernel Oops.
413 * see bug19706 for detailed information */
415 /* procfs won't free rm_entry->data if it isn't a LINK,
416 * and Lustre won't use rm_entry->data if it is a LINK */
417 if (S_ISLNK(rm_entry->mode))
418 rm_entry->data = NULL;
420 /* Now, the rm_entry->deleted flags is protected
421 * by _lprocfs_lock. */
422 rm_entry->data = NULL;
424 remove_proc_entry(rm_entry->name, temp);
428 LPROCFS_WRITE_EXIT();
431 void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
433 LASSERT(parent != NULL);
434 remove_proc_entry(name, parent);
437 struct proc_dir_entry *lprocfs_register(const char *name,
438 struct proc_dir_entry *parent,
439 struct lprocfs_vars *list, void *data)
441 struct proc_dir_entry *newchild;
443 newchild = lprocfs_srch(parent, name);
444 if (newchild != NULL) {
445 CERROR(" Lproc: Attempting to register %s more than once \n",
447 return ERR_PTR(-EALREADY);
450 newchild = proc_mkdir(name, parent);
451 if (newchild != NULL && list != NULL) {
452 int rc = lprocfs_add_vars(newchild, list, data);
454 lprocfs_remove(&newchild);
461 /* Generic callbacks */
462 int lprocfs_rd_uint(char *page, char **start, off_t off,
463 int count, int *eof, void *data)
465 unsigned int *temp = data;
466 return snprintf(page, count, "%u\n", *temp);
469 int lprocfs_wr_uint(struct file *file, const char *buffer,
470 unsigned long count, void *data)
473 char dummy[MAX_STRING_SIZE + 1], *end;
476 dummy[MAX_STRING_SIZE] = '\0';
477 if (cfs_copy_from_user(dummy, buffer, MAX_STRING_SIZE))
480 tmp = simple_strtoul(dummy, &end, 0);
484 *p = (unsigned int)tmp;
488 int lprocfs_rd_u64(char *page, char **start, off_t off,
489 int count, int *eof, void *data)
491 LASSERT(data != NULL);
493 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
496 int lprocfs_rd_atomic(char *page, char **start, off_t off,
497 int count, int *eof, void *data)
499 cfs_atomic_t *atom = data;
500 LASSERT(atom != NULL);
502 return snprintf(page, count, "%d\n", cfs_atomic_read(atom));
505 int lprocfs_wr_atomic(struct file *file, const char *buffer,
506 unsigned long count, void *data)
508 cfs_atomic_t *atm = data;
512 rc = lprocfs_write_helper(buffer, count, &val);
519 cfs_atomic_set(atm, val);
523 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
524 int *eof, void *data)
526 struct obd_device *obd = data;
528 LASSERT(obd != NULL);
530 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
533 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
534 int *eof, void *data)
536 struct obd_device *dev = data;
538 LASSERT(dev != NULL);
539 LASSERT(dev->obd_name != NULL);
541 return snprintf(page, count, "%s\n", dev->obd_name);
544 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
547 struct obd_device *obd = data;
549 LASSERT(obd != NULL);
550 LASSERT(obd->obd_fsops != NULL);
551 LASSERT(obd->obd_fsops->fs_type != NULL);
552 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
555 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
556 int *eof, void *data)
558 struct obd_statfs osfs;
559 int rc = obd_statfs(data, &osfs,
560 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
564 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
569 int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
570 int *eof, void *data)
572 struct obd_statfs osfs;
573 int rc = obd_statfs(data, &osfs,
574 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
577 __u32 blk_size = osfs.os_bsize >> 10;
578 __u64 result = osfs.os_blocks;
580 while (blk_size >>= 1)
584 rc = snprintf(page, count, LPU64"\n", result);
589 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
590 int *eof, void *data)
592 struct obd_statfs osfs;
593 int rc = obd_statfs(data, &osfs,
594 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
597 __u32 blk_size = osfs.os_bsize >> 10;
598 __u64 result = osfs.os_bfree;
600 while (blk_size >>= 1)
604 rc = snprintf(page, count, LPU64"\n", result);
609 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
610 int *eof, void *data)
612 struct obd_statfs osfs;
613 int rc = obd_statfs(data, &osfs,
614 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
617 __u32 blk_size = osfs.os_bsize >> 10;
618 __u64 result = osfs.os_bavail;
620 while (blk_size >>= 1)
624 rc = snprintf(page, count, LPU64"\n", result);
629 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
630 int *eof, void *data)
632 struct obd_statfs osfs;
633 int rc = obd_statfs(data, &osfs,
634 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
638 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
644 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
645 int *eof, void *data)
647 struct obd_statfs osfs;
648 int rc = obd_statfs(data, &osfs,
649 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
653 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
658 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
659 int *eof, void *data)
661 struct obd_device *obd = data;
662 struct obd_import *imp;
663 char *imp_state_name = NULL;
666 LASSERT(obd != NULL);
667 LPROCFS_CLIMP_CHECK(obd);
668 imp = obd->u.cli.cl_import;
669 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
671 rc = snprintf(page, count, "%s\t%s%s\n",
672 obd2cli_tgt(obd), imp_state_name,
673 imp->imp_deactive ? "\tDEACTIVATED" : "");
675 LPROCFS_CLIMP_EXIT(obd);
679 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
680 int *eof, void *data)
682 struct obd_device *obd = data;
683 struct ptlrpc_connection *conn;
686 LASSERT(obd != NULL);
688 LPROCFS_CLIMP_CHECK(obd);
689 conn = obd->u.cli.cl_import->imp_connection;
691 if (conn && obd->u.cli.cl_import) {
692 rc = snprintf(page, count, "%s\n",
693 conn->c_remote_uuid.uuid);
695 rc = snprintf(page, count, "%s\n", "<none>");
698 LPROCFS_CLIMP_EXIT(obd);
702 /** add up per-cpu counters */
703 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
704 struct lprocfs_counter *cnt)
706 unsigned int num_cpu;
707 struct lprocfs_counter t;
708 struct lprocfs_counter *percpu_cntr;
711 memset(cnt, 0, sizeof(*cnt));
714 /* set count to 1 to avoid divide-by-zero errs in callers */
719 cnt->lc_min = LC_MIN_INIT;
721 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
723 for (i = 0; i < num_cpu; i++) {
724 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
727 centry = cfs_atomic_read(&percpu_cntr-> \
729 t.lc_count = percpu_cntr->lc_count;
730 t.lc_sum = percpu_cntr->lc_sum;
731 t.lc_min = percpu_cntr->lc_min;
732 t.lc_max = percpu_cntr->lc_max;
733 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
734 } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
736 centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
738 cnt->lc_count += t.lc_count;
739 cnt->lc_sum += t.lc_sum;
740 if (t.lc_min < cnt->lc_min)
741 cnt->lc_min = t.lc_min;
742 if (t.lc_max > cnt->lc_max)
743 cnt->lc_max = t.lc_max;
744 cnt->lc_sumsquare += t.lc_sumsquare;
747 cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
748 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
752 * Append a space separated list of current set flags to str.
754 #define flag2str(flag) \
755 if (imp->imp_##flag && max - len > 0) \
756 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
757 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
761 if (imp->imp_obd->obd_no_recov)
762 len += snprintf(str, max - len, "no_recov");
766 flag2str(replayable);
772 static const char *obd_connect_names[] = {
786 "join_file(obsolete)",
790 "remote_client_by_force",
799 "mds_mds_connection",
802 "alt_checksum_algorithm",
817 int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
822 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
824 ret += snprintf(page + ret, count - ret, "%s%s",
825 ret ? sep : "", obd_connect_names[i]);
827 if (flags & ~(mask - 1))
828 ret += snprintf(page + ret, count - ret,
829 "%sunknown flags "LPX64,
830 ret ? sep : "", flags & ~(mask - 1));
833 EXPORT_SYMBOL(obd_connect_flags2str);
835 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
836 int *eof, void *data)
838 struct lprocfs_counter ret;
839 struct obd_device *obd = (struct obd_device *)data;
840 struct obd_import *imp;
841 struct obd_import_conn *conn;
844 LASSERT(obd != NULL);
845 LPROCFS_CLIMP_CHECK(obd);
846 imp = obd->u.cli.cl_import;
849 i = snprintf(page, count,
858 ptlrpc_import_state_name(imp->imp_state),
859 imp->imp_connect_data.ocd_instance);
860 i += obd_connect_flags2str(page + i, count - i,
861 imp->imp_connect_data.ocd_connect_flags,
863 i += snprintf(page + i, count - i,
866 i += obd_import_flags2str(imp, page + i, count - i);
868 i += snprintf(page + i, count - i,
871 " failover_nids: [");
872 cfs_spin_lock(&imp->imp_lock);
874 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
875 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
876 libcfs_nid2str(conn->oic_conn->c_peer.nid));
879 cfs_spin_unlock(&imp->imp_lock);
880 i += snprintf(page + i, count - i,
882 " current_connection: %s\n"
883 " connection_attempts: %u\n"
885 " in-progress_invalidations: %u\n",
886 libcfs_nid2str(imp->imp_connection->c_peer.nid),
889 cfs_atomic_read(&imp->imp_inval_count));
891 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
892 if (ret.lc_count != 0) {
893 /* first argument to do_div MUST be __u64 */
894 __u64 sum = ret.lc_sum;
895 do_div(sum, ret.lc_count);
899 i += snprintf(page + i, count - i,
902 " unregistering: %u\n"
904 " avg_waittime: "LPU64" %s\n",
905 cfs_atomic_read(&imp->imp_inflight),
906 cfs_atomic_read(&imp->imp_unregistering),
907 cfs_atomic_read(&imp->imp_timeouts),
908 ret.lc_sum, ret.lc_units);
911 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
912 if (imp->imp_at.iat_portal[j] == 0)
914 k = max_t(unsigned int, k,
915 at_get(&imp->imp_at.iat_service_estimate[j]));
917 i += snprintf(page + i, count - i,
918 " service_estimates:\n"
919 " services: %u sec\n"
920 " network: %u sec\n",
922 at_get(&imp->imp_at.iat_net_latency));
924 i += snprintf(page + i, count - i,
926 " last_replay: "LPU64"\n"
927 " peer_committed: "LPU64"\n"
928 " last_checked: "LPU64"\n",
929 imp->imp_last_replay_transno,
930 imp->imp_peer_committed_transno,
931 imp->imp_last_transno_checked);
934 for (rw = 0; rw <= 1; rw++) {
935 lprocfs_stats_collect(obd->obd_svc_stats,
936 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
938 if (ret.lc_sum > 0 && ret.lc_count > 0) {
939 /* first argument to do_div MUST be __u64 */
940 __u64 sum = ret.lc_sum;
941 do_div(sum, ret.lc_count);
943 i += snprintf(page + i, count - i,
944 " %s_data_averages:\n"
945 " bytes_per_rpc: "LPU64"\n",
946 rw ? "write" : "read",
950 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
951 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
952 if (ret.lc_sum > 0 && ret.lc_count != 0) {
953 /* first argument to do_div MUST be __u64 */
954 __u64 sum = ret.lc_sum;
955 do_div(sum, ret.lc_count);
957 i += snprintf(page + i, count - i,
958 " %s_per_rpc: "LPU64"\n",
959 ret.lc_units, ret.lc_sum);
962 i += snprintf(page + i, count - i,
963 " MB_per_sec: %u.%.02u\n",
964 k / j, (100 * k / j) % 100);
968 LPROCFS_CLIMP_EXIT(obd);
972 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
973 int *eof, void *data)
975 struct obd_device *obd = (struct obd_device *)data;
976 struct obd_import *imp;
979 LASSERT(obd != NULL);
980 LPROCFS_CLIMP_CHECK(obd);
981 imp = obd->u.cli.cl_import;
984 i = snprintf(page, count, "current_state: %s\n",
985 ptlrpc_import_state_name(imp->imp_state));
986 i += snprintf(page + i, count - i,
988 k = imp->imp_state_hist_idx;
989 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
990 struct import_state_hist *ish =
991 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
992 if (ish->ish_state == 0)
994 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
996 ptlrpc_import_state_name(ish->ish_state));
999 LPROCFS_CLIMP_EXIT(obd);
1003 int lprocfs_at_hist_helper(char *page, int count, int rc,
1004 struct adaptive_timeout *at)
1007 for (i = 0; i < AT_BINS; i++)
1008 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1009 rc += snprintf(page + rc, count - rc, "\n");
1013 /* See also ptlrpc_lprocfs_rd_timeouts */
1014 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1015 int *eof, void *data)
1017 struct obd_device *obd = (struct obd_device *)data;
1018 struct obd_import *imp;
1019 unsigned int cur, worst;
1024 LASSERT(obd != NULL);
1025 LPROCFS_CLIMP_CHECK(obd);
1026 imp = obd->u.cli.cl_import;
1029 now = cfs_time_current_sec();
1031 /* Some network health info for kicks */
1032 s2dhms(&ts, now - imp->imp_last_reply_time);
1033 rc += snprintf(page + rc, count - rc,
1034 "%-10s : %ld, "DHMS_FMT" ago\n",
1035 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1037 cur = at_get(&imp->imp_at.iat_net_latency);
1038 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1039 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1040 s2dhms(&ts, now - worstt);
1041 rc += snprintf(page + rc, count - rc,
1042 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1043 "network", cur, worst, worstt, DHMS_VARS(&ts));
1044 rc = lprocfs_at_hist_helper(page, count, rc,
1045 &imp->imp_at.iat_net_latency);
1047 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1048 if (imp->imp_at.iat_portal[i] == 0)
1050 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1051 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1052 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1053 s2dhms(&ts, now - worstt);
1054 rc += snprintf(page + rc, count - rc,
1055 "portal %-2d : cur %3u worst %3u (at %ld, "
1056 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1057 cur, worst, worstt, DHMS_VARS(&ts));
1058 rc = lprocfs_at_hist_helper(page, count, rc,
1059 &imp->imp_at.iat_service_estimate[i]);
1062 LPROCFS_CLIMP_EXIT(obd);
1066 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1067 int count, int *eof, void *data)
1069 struct obd_device *obd = data;
1073 LPROCFS_CLIMP_CHECK(obd);
1074 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1075 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1076 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1077 ret += snprintf(page + ret, count - ret, "\n");
1078 LPROCFS_CLIMP_EXIT(obd);
1081 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1083 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1084 int *eof, void *data)
1086 struct obd_device *obd = data;
1088 LASSERT(obd != NULL);
1090 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1093 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1094 int *eof, void *data)
1096 struct obd_type *class = (struct obd_type*) data;
1098 LASSERT(class != NULL);
1100 return snprintf(page, count, "%d\n", class->typ_refcnt);
1103 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1107 LASSERT(obd != NULL);
1108 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1109 LASSERT(obd->obd_type->typ_procroot != NULL);
1111 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1112 obd->obd_type->typ_procroot,
1114 if (IS_ERR(obd->obd_proc_entry)) {
1115 rc = PTR_ERR(obd->obd_proc_entry);
1116 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1117 obd->obd_proc_entry = NULL;
1122 int lprocfs_obd_cleanup(struct obd_device *obd)
1126 if (obd->obd_proc_exports_entry) {
1127 /* Should be no exports left */
1128 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1129 lprocfs_remove(&obd->obd_proc_exports_entry);
1130 obd->obd_proc_exports_entry = NULL;
1132 if (obd->obd_proc_entry) {
1133 lprocfs_remove(&obd->obd_proc_entry);
1134 obd->obd_proc_entry = NULL;
1139 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1141 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1142 client_stat->nid_proc, client_stat->nid_stats,
1143 client_stat->nid_brw_stats);
1145 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1146 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1147 atomic_read(&client_stat->nid_exp_ref_count));
1149 cfs_hlist_del_init(&client_stat->nid_hash);
1151 if (client_stat->nid_proc)
1152 lprocfs_remove(&client_stat->nid_proc);
1154 if (client_stat->nid_stats)
1155 lprocfs_free_stats(&client_stat->nid_stats);
1157 if (client_stat->nid_brw_stats)
1158 OBD_FREE_PTR(client_stat->nid_brw_stats);
1160 if (client_stat->nid_ldlm_stats)
1161 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1163 OBD_FREE_PTR(client_stat);
1168 void lprocfs_free_per_client_stats(struct obd_device *obd)
1170 struct nid_stat *stat;
1173 /* we need extra list - because hash_exit called to early */
1174 /* not need locking because all clients is died */
1175 while(!cfs_list_empty(&obd->obd_nid_stats)) {
1176 stat = cfs_list_entry(obd->obd_nid_stats.next,
1177 struct nid_stat, nid_list);
1178 cfs_list_del_init(&stat->nid_list);
1179 lprocfs_free_client_stats(stat);
1185 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1186 enum lprocfs_stats_flags flags)
1188 struct lprocfs_stats *stats;
1189 unsigned int percpusize;
1191 unsigned int num_cpu;
1196 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1199 num_cpu = cfs_num_possible_cpus();
1201 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1205 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1206 stats->ls_flags = flags;
1207 cfs_spin_lock_init(&stats->ls_lock);
1208 /* Use this lock only if there are no percpu areas */
1210 stats->ls_flags = 0;
1213 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1215 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1217 for (i = 0; i < num_cpu; i++) {
1218 OBD_ALLOC(stats->ls_percpu[i], percpusize);
1219 if (stats->ls_percpu[i] == NULL) {
1220 for (j = 0; j < i; j++) {
1221 OBD_FREE(stats->ls_percpu[j], percpusize);
1222 stats->ls_percpu[j] = NULL;
1227 if (stats->ls_percpu[0] == NULL) {
1228 OBD_FREE(stats, offsetof(typeof(*stats),
1229 ls_percpu[num_cpu]));
1233 stats->ls_num = num;
1237 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1239 struct lprocfs_stats *stats = *statsh;
1240 unsigned int num_cpu;
1241 unsigned int percpusize;
1244 if (stats == NULL || stats->ls_num == 0)
1248 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1251 num_cpu = cfs_num_possible_cpus();
1253 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1255 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1256 for (i = 0; i < num_cpu; i++)
1257 OBD_FREE(stats->ls_percpu[i], percpusize);
1258 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1261 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1263 struct lprocfs_counter *percpu_cntr;
1265 unsigned int num_cpu;
1267 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1269 for (i = 0; i < num_cpu; i++) {
1270 for (j = 0; j < stats->ls_num; j++) {
1271 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1272 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1273 percpu_cntr->lc_count = 0;
1274 percpu_cntr->lc_sum = 0;
1275 percpu_cntr->lc_min = LC_MIN_INIT;
1276 percpu_cntr->lc_max = 0;
1277 percpu_cntr->lc_sumsquare = 0;
1278 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1282 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1285 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1286 size_t len, loff_t *off)
1288 struct seq_file *seq = file->private_data;
1289 struct lprocfs_stats *stats = seq->private;
1291 lprocfs_clear_stats(stats);
1296 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1298 struct lprocfs_stats *stats = p->private;
1299 /* return 1st cpu location */
1300 return (*pos >= stats->ls_num) ? NULL :
1301 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1304 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1308 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1310 struct lprocfs_stats *stats = p->private;
1312 return (*pos >= stats->ls_num) ? NULL :
1313 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1316 /* seq file export of one lprocfs counter */
1317 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1319 struct lprocfs_stats *stats = p->private;
1320 struct lprocfs_counter *cntr = v;
1321 struct lprocfs_counter ret;
1324 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1326 cfs_gettimeofday(&now);
1327 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1328 "snapshot_time", now.tv_sec, now.tv_usec);
1332 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1334 lprocfs_stats_collect(stats, idx, &ret);
1336 if (ret.lc_count == 0)
1339 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1340 ret.lc_count, cntr->lc_units);
1345 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1346 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1347 ret.lc_min, ret.lc_max, ret.lc_sum);
1350 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1351 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1355 rc = seq_printf(p, "\n");
1357 return (rc < 0) ? rc : 0;
1360 struct seq_operations lprocfs_stats_seq_sops = {
1361 start: lprocfs_stats_seq_start,
1362 stop: lprocfs_stats_seq_stop,
1363 next: lprocfs_stats_seq_next,
1364 show: lprocfs_stats_seq_show,
1367 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1369 struct proc_dir_entry *dp = PDE(inode);
1370 struct seq_file *seq;
1373 if (LPROCFS_ENTRY_AND_CHECK(dp))
1376 rc = seq_open(file, &lprocfs_stats_seq_sops);
1381 seq = file->private_data;
1382 seq->private = dp->data;
1386 struct file_operations lprocfs_stats_seq_fops = {
1387 .owner = THIS_MODULE,
1388 .open = lprocfs_stats_seq_open,
1390 .write = lprocfs_stats_seq_write,
1391 .llseek = seq_lseek,
1392 .release = lprocfs_seq_release,
1395 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1396 struct lprocfs_stats *stats)
1398 struct proc_dir_entry *entry;
1399 LASSERT(root != NULL);
1401 LPROCFS_WRITE_ENTRY();
1402 entry = create_proc_entry(name, 0644, root);
1404 entry->proc_fops = &lprocfs_stats_seq_fops;
1405 entry->data = stats;
1408 LPROCFS_WRITE_EXIT();
1416 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1417 unsigned conf, const char *name, const char *units)
1419 struct lprocfs_counter *c;
1421 unsigned int num_cpu;
1423 LASSERT(stats != NULL);
1425 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1427 for (i = 0; i < num_cpu; i++) {
1428 c = &(stats->ls_percpu[i]->lp_cntr[index]);
1429 c->lc_config = conf;
1432 c->lc_min = LC_MIN_INIT;
1435 c->lc_units = units;
1438 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1440 EXPORT_SYMBOL(lprocfs_counter_init);
1442 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1444 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1445 LASSERT(coffset < stats->ls_num); \
1446 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1449 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1451 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1452 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1453 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1454 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1455 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1456 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1457 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1458 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1459 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1460 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1461 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1462 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1463 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1467 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1468 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1469 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1470 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1471 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1472 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1473 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1474 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1475 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1476 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1477 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1478 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1479 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1480 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1481 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1482 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1483 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1484 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1485 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1486 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1487 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1488 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1489 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1490 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1491 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1492 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1493 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1494 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1495 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1496 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1497 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1498 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1499 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1500 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1501 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1502 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1503 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1504 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1505 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1506 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1507 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1508 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1509 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1510 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1511 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1512 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1513 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1514 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1515 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1516 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1517 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1518 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1519 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1522 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1524 struct lprocfs_stats *stats;
1525 unsigned int num_stats;
1528 LASSERT(obd->obd_stats == NULL);
1529 LASSERT(obd->obd_proc_entry != NULL);
1530 LASSERT(obd->obd_cntr_base == 0);
1532 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1533 num_private_stats - 1 /* o_owner */;
1534 stats = lprocfs_alloc_stats(num_stats, 0);
1538 lprocfs_init_ops_stats(num_private_stats, stats);
1540 for (i = num_private_stats; i < num_stats; i++) {
1541 /* If this LBUGs, it is likely that an obd
1542 * operation was added to struct obd_ops in
1543 * <obd.h>, and that the corresponding line item
1544 * LPROCFS_OBD_OP_INIT(.., .., opname)
1545 * is missing from the list above. */
1546 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1547 "Missing obd_stat initializer obd_op "
1548 "operation at offset %d.\n", i - num_private_stats);
1550 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1552 lprocfs_free_stats(&stats);
1554 obd->obd_stats = stats;
1555 obd->obd_cntr_base = num_private_stats;
1560 void lprocfs_free_obd_stats(struct obd_device *obd)
1563 lprocfs_free_stats(&obd->obd_stats);
1566 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1568 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1569 LASSERT(coffset < stats->ls_num); \
1570 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1573 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1575 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1576 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1577 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1578 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1579 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1580 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1581 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1582 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1583 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1584 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1585 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1586 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1587 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1588 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1589 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1590 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1591 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1592 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1593 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1594 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1595 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1596 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1597 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1598 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1599 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1600 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1601 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1602 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1603 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1604 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1605 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1606 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1609 int lprocfs_alloc_md_stats(struct obd_device *obd,
1610 unsigned num_private_stats)
1612 struct lprocfs_stats *stats;
1613 unsigned int num_stats;
1616 LASSERT(obd->md_stats == NULL);
1617 LASSERT(obd->obd_proc_entry != NULL);
1618 LASSERT(obd->md_cntr_base == 0);
1620 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1622 stats = lprocfs_alloc_stats(num_stats, 0);
1626 lprocfs_init_mps_stats(num_private_stats, stats);
1628 for (i = num_private_stats; i < num_stats; i++) {
1629 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1630 CERROR("Missing md_stat initializer md_op "
1631 "operation at offset %d. Aborting.\n",
1632 i - num_private_stats);
1636 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1638 lprocfs_free_stats(&stats);
1640 obd->md_stats = stats;
1641 obd->md_cntr_base = num_private_stats;
1646 void lprocfs_free_md_stats(struct obd_device *obd)
1648 struct lprocfs_stats *stats = obd->md_stats;
1650 if (stats != NULL) {
1651 obd->md_stats = NULL;
1652 obd->md_cntr_base = 0;
1653 lprocfs_free_stats(&stats);
1657 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1659 lprocfs_counter_init(ldlm_stats,
1660 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1661 0, "ldlm_enqueue", "reqs");
1662 lprocfs_counter_init(ldlm_stats,
1663 LDLM_CONVERT - LDLM_FIRST_OPC,
1664 0, "ldlm_convert", "reqs");
1665 lprocfs_counter_init(ldlm_stats,
1666 LDLM_CANCEL - LDLM_FIRST_OPC,
1667 0, "ldlm_cancel", "reqs");
1668 lprocfs_counter_init(ldlm_stats,
1669 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1670 0, "ldlm_bl_callback", "reqs");
1671 lprocfs_counter_init(ldlm_stats,
1672 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1673 0, "ldlm_cp_callback", "reqs");
1674 lprocfs_counter_init(ldlm_stats,
1675 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1676 0, "ldlm_gl_callback", "reqs");
1679 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1680 int *eof, void *data)
1682 struct obd_export *exp = data;
1683 LASSERT(exp != NULL);
1685 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1688 struct exp_uuid_cb_data {
1696 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1697 int count, int *eof, int *len)
1699 cb_data->page = page;
1700 cb_data->count = count;
1705 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1706 cfs_hlist_node_t *hnode, void *cb_data)
1709 struct obd_export *exp = cfs_hash_object(hs, hnode);
1710 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1712 if (exp->exp_nid_stats)
1713 *data->len += snprintf((data->page + *data->len),
1714 data->count, "%s\n",
1715 obd_uuid2str(&exp->exp_client_uuid));
1719 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1720 int *eof, void *data)
1722 struct nid_stat *stats = (struct nid_stat *)data;
1723 struct exp_uuid_cb_data cb_data;
1724 struct obd_device *obd = stats->nid_obd;
1729 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1730 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1731 lprocfs_exp_print_uuid, &cb_data);
1732 return (*cb_data.len);
1735 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1736 cfs_hlist_node_t *hnode, void *cb_data)
1739 struct exp_uuid_cb_data *data = cb_data;
1740 struct obd_export *exp = cfs_hash_object(hs, hnode);
1742 if (exp->exp_lock_hash != NULL) {
1744 *data->len += cfs_hash_debug_header(data->page,
1747 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1754 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1755 int *eof, void *data)
1757 struct nid_stat *stats = (struct nid_stat *)data;
1758 struct exp_uuid_cb_data cb_data;
1759 struct obd_device *obd = stats->nid_obd;
1764 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1766 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1767 lprocfs_exp_print_hash, &cb_data);
1768 return (*cb_data.len);
1771 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1772 int count, int *eof, void *data)
1775 return snprintf(page, count, "%s\n",
1776 "Write into this file to clear all nid stats and "
1777 "stale nid entries");
1779 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1781 int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1783 struct nid_stat *stat = obj;
1787 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1788 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1789 /* object has only hash references. */
1790 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1791 cfs_list_move(&stat->nid_list, data);
1792 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1795 /* we has reference to object - only clear data*/
1796 if (stat->nid_stats)
1797 lprocfs_clear_stats(stat->nid_stats);
1799 if (stat->nid_brw_stats) {
1800 for (i = 0; i < BRW_LAST; i++)
1801 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1806 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1807 unsigned long count, void *data)
1809 struct obd_device *obd = (struct obd_device *)data;
1810 struct nid_stat *client_stat;
1811 CFS_LIST_HEAD(free_list);
1813 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1814 lprocfs_nid_stats_clear_write_cb, &free_list);
1816 while (!cfs_list_empty(&free_list)) {
1817 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1819 cfs_list_del_init(&client_stat->nid_list);
1820 lprocfs_free_client_stats(client_stat);
1825 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1827 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1829 struct nid_stat *new_stat, *old_stat;
1830 struct obd_device *obd = NULL;
1831 cfs_proc_dir_entry_t *entry;
1832 char *buffer = NULL;
1838 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1839 !exp->exp_obd->obd_nid_stats_hash)
1842 /* not test against zero because eric say:
1843 * You may only test nid against another nid, or LNET_NID_ANY.
1844 * Anything else is nonsense.*/
1845 if (!nid || *nid == LNET_NID_ANY)
1850 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1852 OBD_ALLOC_PTR(new_stat);
1853 if (new_stat == NULL)
1856 new_stat->nid = *nid;
1857 new_stat->nid_obd = exp->exp_obd;
1858 /* we need set default refcount to 1 to balance obd_disconnect */
1859 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1861 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1862 nid, &new_stat->nid_hash);
1863 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1864 old_stat, libcfs_nid2str(*nid),
1865 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1867 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1868 * been and will never be called. */
1869 if (exp->exp_nid_stats) {
1870 nidstat_putref(exp->exp_nid_stats);
1871 exp->exp_nid_stats = NULL;
1874 /* Return -EALREADY here so that we know that the /proc
1875 * entry already has been created */
1876 if (old_stat != new_stat) {
1877 exp->exp_nid_stats = old_stat;
1878 GOTO(destroy_new, rc = -EALREADY);
1880 /* not found - create */
1881 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1883 GOTO(destroy_new, rc = -ENOMEM);
1885 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1886 new_stat->nid_proc = lprocfs_register(buffer,
1887 obd->obd_proc_exports_entry,
1889 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1891 if (new_stat->nid_proc == NULL) {
1892 CERROR("Error making export directory for nid %s\n",
1893 libcfs_nid2str(*nid));
1894 GOTO(destroy_new_ns, rc = -ENOMEM);
1897 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1898 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1899 if (IS_ERR(entry)) {
1900 CWARN("Error adding the NID stats file\n");
1901 rc = PTR_ERR(entry);
1902 GOTO(destroy_new_ns, rc);
1905 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1906 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1907 if (IS_ERR(entry)) {
1908 CWARN("Error adding the hash file\n");
1909 rc = PTR_ERR(entry);
1910 GOTO(destroy_new_ns, rc);
1913 exp->exp_nid_stats = new_stat;
1915 /* protect competitive add to list, not need locking on destroy */
1916 cfs_spin_lock(&obd->obd_nid_lock);
1917 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1918 cfs_spin_unlock(&obd->obd_nid_lock);
1923 if (new_stat->nid_proc != NULL)
1924 lprocfs_remove(&new_stat->nid_proc);
1925 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1928 nidstat_putref(new_stat);
1929 OBD_FREE_PTR(new_stat);
1933 int lprocfs_exp_cleanup(struct obd_export *exp)
1935 struct nid_stat *stat = exp->exp_nid_stats;
1937 if(!stat || !exp->exp_obd)
1940 nidstat_putref(exp->exp_nid_stats);
1941 exp->exp_nid_stats = NULL;
1946 int lprocfs_write_helper(const char *buffer, unsigned long count,
1949 return lprocfs_write_frac_helper(buffer, count, val, 1);
1952 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1955 char kernbuf[20], *end, *pbuf;
1957 if (count > (sizeof(kernbuf) - 1))
1960 if (cfs_copy_from_user(kernbuf, buffer, count))
1963 kernbuf[count] = '\0';
1970 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1974 if (end != NULL && *end == '.') {
1975 int temp_val, pow = 1;
1979 if (strlen(pbuf) > 5)
1980 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1982 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1985 for (i = 0; i < (end - pbuf); i++)
1988 *val += temp_val / pow;
1994 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
1997 long decimal_val, frac_val;
2003 decimal_val = val / mult;
2004 prtn = snprintf(buffer, count, "%ld", decimal_val);
2005 frac_val = val % mult;
2007 if (prtn < (count - 4) && frac_val > 0) {
2009 int i, temp_mult = 1, frac_bits = 0;
2011 temp_frac = frac_val * 10;
2012 buffer[prtn++] = '.';
2013 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2014 /* only reserved 2 bits fraction */
2015 buffer[prtn++] ='0';
2020 * Need to think these cases :
2021 * 1. #echo x.00 > /proc/xxx output result : x
2022 * 2. #echo x.0x > /proc/xxx output result : x.0x
2023 * 3. #echo x.x0 > /proc/xxx output result : x.x
2024 * 4. #echo x.xx > /proc/xxx output result : x.xx
2025 * Only reserved 2 bits fraction.
2027 for (i = 0; i < (5 - prtn); i++)
2030 frac_bits = min((int)count - prtn, 3 - frac_bits);
2031 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2032 frac_val * temp_mult / mult);
2035 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2037 if (buffer[prtn] == '.') {
2044 buffer[prtn++] ='\n';
2048 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2050 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2053 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2054 __u64 *val, int mult)
2056 char kernbuf[22], *end, *pbuf;
2057 __u64 whole, frac = 0, units;
2058 unsigned frac_d = 1;
2060 if (count > (sizeof(kernbuf) - 1))
2063 if (cfs_copy_from_user(kernbuf, buffer, count))
2066 kernbuf[count] = '\0';
2073 whole = simple_strtoull(pbuf, &end, 10);
2077 if (end != NULL && *end == '.') {
2081 /* need to limit frac_d to a __u32 */
2082 if (strlen(pbuf) > 10)
2085 frac = simple_strtoull(pbuf, &end, 10);
2086 /* count decimal places */
2087 for (i = 0; i < (end - pbuf); i++)
2104 /* Specified units override the multiplier */
2106 mult = mult < 0 ? -units : units;
2109 do_div(frac, frac_d);
2110 *val = whole * mult + frac;
2114 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2115 struct file_operations *seq_fops, void *data)
2117 struct proc_dir_entry *entry;
2120 LPROCFS_WRITE_ENTRY();
2121 entry = create_proc_entry(name, mode, parent);
2123 entry->proc_fops = seq_fops;
2126 LPROCFS_WRITE_EXIT();
2133 EXPORT_SYMBOL(lprocfs_seq_create);
2135 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2137 struct file_operations *seq_fops,
2140 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2141 mode, seq_fops, data));
2143 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2145 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2147 if (value >= OBD_HIST_MAX)
2148 value = OBD_HIST_MAX - 1;
2150 cfs_spin_lock(&oh->oh_lock);
2151 oh->oh_buckets[value]++;
2152 cfs_spin_unlock(&oh->oh_lock);
2154 EXPORT_SYMBOL(lprocfs_oh_tally);
2156 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2160 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2163 lprocfs_oh_tally(oh, val);
2165 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2167 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2169 unsigned long ret = 0;
2172 for (i = 0; i < OBD_HIST_MAX; i++)
2173 ret += oh->oh_buckets[i];
2176 EXPORT_SYMBOL(lprocfs_oh_sum);
2178 void lprocfs_oh_clear(struct obd_histogram *oh)
2180 cfs_spin_lock(&oh->oh_lock);
2181 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2182 cfs_spin_unlock(&oh->oh_lock);
2184 EXPORT_SYMBOL(lprocfs_oh_clear);
2186 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2187 int count, int *eof, void *data)
2189 struct obd_device *obd = data;
2195 c += cfs_hash_debug_header(page, count);
2196 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2197 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2198 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2199 #ifdef HAVE_QUOTA_SUPPORT
2200 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2201 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2202 page + c, count - c);
2207 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2209 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2210 int count, int *eof, void *data)
2212 struct obd_device *obd = data;
2215 LASSERT(obd != NULL);
2216 LASSERT(count >= 0);
2218 /* Set start of user data returned to
2219 page + off since the user may have
2220 requested to read much smaller than
2221 what we need to read */
2222 *start = page + off;
2224 /* We know we are allocated a page here.
2225 Also we know that this function will
2226 not need to write more than a page
2227 so we can truncate at CFS_PAGE_SIZE. */
2228 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2230 /* Initialize the page */
2231 memset(page, 0, size);
2233 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2235 if (obd->obd_max_recoverable_clients == 0) {
2236 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2242 /* sampled unlocked, but really... */
2243 if (obd->obd_recovering == 0) {
2244 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2246 if (lprocfs_obd_snprintf(&page, size, &len,
2247 "recovery_start: %lu\n",
2248 obd->obd_recovery_start) <= 0)
2250 if (lprocfs_obd_snprintf(&page, size, &len,
2251 "recovery_duration: %lu\n",
2252 obd->obd_recovery_end -
2253 obd->obd_recovery_start) <= 0)
2255 /* Number of clients that have completed recovery */
2256 if (lprocfs_obd_snprintf(&page, size, &len,
2257 "completed_clients: %d/%d\n",
2258 obd->obd_max_recoverable_clients -
2259 obd->obd_stale_clients,
2260 obd->obd_max_recoverable_clients) <= 0)
2262 if (lprocfs_obd_snprintf(&page, size, &len,
2263 "replayed_requests: %d\n",
2264 obd->obd_replayed_requests) <= 0)
2266 if (lprocfs_obd_snprintf(&page, size, &len,
2267 "last_transno: "LPD64"\n",
2268 obd->obd_next_recovery_transno - 1)<=0)
2270 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2271 obd->obd_version_recov ? "ON" : "OFF")<=0)
2273 if (lprocfs_obd_snprintf(&page, size, &len, "IR: %s\n",
2274 obd->obd_no_ir ? "OFF" : "ON") <= 0)
2279 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2281 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2282 obd->obd_recovery_start) <= 0)
2284 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2285 cfs_time_current_sec() >= obd->obd_recovery_end ? 0 :
2286 obd->obd_recovery_end - cfs_time_current_sec()) <= 0)
2288 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2289 obd->obd_connected_clients,
2290 obd->obd_max_recoverable_clients) <= 0)
2292 /* Number of clients that have completed recovery */
2293 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2294 cfs_atomic_read(&obd->obd_req_replay_clients))
2297 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2298 cfs_atomic_read(&obd->obd_lock_replay_clients))
2301 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2302 obd->obd_connected_clients -
2303 cfs_atomic_read(&obd->obd_lock_replay_clients))
2306 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2307 obd->obd_stale_clients) <= 0)
2309 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2310 obd->obd_replayed_requests) <= 0)
2312 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2313 obd->obd_requests_queued_for_recovery) <= 0)
2316 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2317 obd->obd_next_recovery_transno) <= 0)
2323 return min(count, len - (int)off);
2325 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2327 int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off,
2328 int count, int *eof, void *data)
2330 struct obd_device *obd = (struct obd_device *)data;
2331 LASSERT(obd != NULL);
2333 return snprintf(page, count, "%d\n",
2334 obd->obd_recovery_ir_factor);
2336 EXPORT_SYMBOL(lprocfs_obd_rd_ir_factor);
2338 int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer,
2339 unsigned long count, void *data)
2341 struct obd_device *obd = (struct obd_device *)data;
2343 LASSERT(obd != NULL);
2345 rc = lprocfs_write_helper(buffer, count, &val);
2349 if (val < OBD_IR_FACTOR_MIN || val > OBD_IR_FACTOR_MAX)
2352 obd->obd_recovery_ir_factor = val;
2355 EXPORT_SYMBOL(lprocfs_obd_wr_ir_factor);
2357 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2358 int count, int *eof, void *data)
2360 struct obd_device *obd = (struct obd_device *)data;
2361 LASSERT(obd != NULL);
2363 return snprintf(page, count, "%d\n",
2364 obd->obd_recovery_timeout);
2366 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2368 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2369 unsigned long count, void *data)
2371 struct obd_device *obd = (struct obd_device *)data;
2373 LASSERT(obd != NULL);
2375 rc = lprocfs_write_helper(buffer, count, &val);
2379 obd->obd_recovery_timeout = val;
2382 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2384 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2385 int count, int *eof, void *data)
2387 struct obd_device *obd = data;
2388 LASSERT(obd != NULL);
2390 return snprintf(page, count, "%u\n", obd->obd_recovery_time_hard);
2392 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2394 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2395 unsigned long count, void *data)
2397 struct obd_device *obd = data;
2399 LASSERT(obd != NULL);
2401 rc = lprocfs_write_helper(buffer, count, &val);
2405 obd->obd_recovery_time_hard = val;
2408 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2410 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2411 int count, int *eof, void *data)
2413 struct obd_device *obd = (struct obd_device *)data;
2415 LASSERT(obd != NULL);
2416 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2418 return snprintf(page, count, "%s\n",
2419 obd->u.obt.obt_vfsmnt->mnt_devname);
2421 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2423 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2424 int count, int *eof, void *data)
2426 struct obd_device *dev = data;
2427 struct client_obd *cli = &dev->u.cli;
2430 client_obd_list_lock(&cli->cl_loi_list_lock);
2431 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2432 client_obd_list_unlock(&cli->cl_loi_list_lock);
2435 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2437 int lprocfs_obd_wr_max_pages_per_rpc(struct file *file, const char *buffer,
2438 unsigned long count, void *data)
2440 struct obd_device *dev = data;
2441 struct client_obd *cli = &dev->u.cli;
2442 struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
2445 rc = lprocfs_write_helper(buffer, count, &val);
2449 LPROCFS_CLIMP_CHECK(dev);
2450 if (val < 1 || val > ocd->ocd_brw_size >> CFS_PAGE_SHIFT) {
2451 LPROCFS_CLIMP_EXIT(dev);
2454 client_obd_list_lock(&cli->cl_loi_list_lock);
2455 cli->cl_max_pages_per_rpc = val;
2456 client_obd_list_unlock(&cli->cl_loi_list_lock);
2458 LPROCFS_CLIMP_EXIT(dev);
2461 EXPORT_SYMBOL(lprocfs_obd_wr_max_pages_per_rpc);
2463 int lprocfs_target_rd_instance(char *page, char **start, off_t off,
2464 int count, int *eof, void *data)
2466 struct obd_device *obd = (struct obd_device *)data;
2467 struct obd_device_target *target = &obd->u.obt;
2469 LASSERT(obd != NULL);
2470 LASSERT(target->obt_magic == OBT_MAGIC);
2472 return snprintf(page, count, "%u\n", obd->u.obt.obt_instance);
2474 EXPORT_SYMBOL(lprocfs_target_rd_instance);
2476 EXPORT_SYMBOL(lprocfs_register);
2477 EXPORT_SYMBOL(lprocfs_srch);
2478 EXPORT_SYMBOL(lprocfs_remove);
2479 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2480 EXPORT_SYMBOL(lprocfs_add_vars);
2481 EXPORT_SYMBOL(lprocfs_obd_setup);
2482 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2483 EXPORT_SYMBOL(lprocfs_add_simple);
2484 EXPORT_SYMBOL(lprocfs_add_symlink);
2485 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2486 EXPORT_SYMBOL(lprocfs_alloc_stats);
2487 EXPORT_SYMBOL(lprocfs_free_stats);
2488 EXPORT_SYMBOL(lprocfs_clear_stats);
2489 EXPORT_SYMBOL(lprocfs_register_stats);
2490 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2491 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2492 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2493 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2494 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2495 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2496 EXPORT_SYMBOL(lprocfs_free_md_stats);
2497 EXPORT_SYMBOL(lprocfs_exp_setup);
2498 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2500 EXPORT_SYMBOL(lprocfs_rd_u64);
2501 EXPORT_SYMBOL(lprocfs_rd_atomic);
2502 EXPORT_SYMBOL(lprocfs_wr_atomic);
2503 EXPORT_SYMBOL(lprocfs_rd_uint);
2504 EXPORT_SYMBOL(lprocfs_wr_uint);
2505 EXPORT_SYMBOL(lprocfs_rd_uuid);
2506 EXPORT_SYMBOL(lprocfs_rd_name);
2507 EXPORT_SYMBOL(lprocfs_rd_fstype);
2508 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2509 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2510 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2511 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2512 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2513 EXPORT_SYMBOL(lprocfs_rd_import);
2514 EXPORT_SYMBOL(lprocfs_rd_state);
2515 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2516 EXPORT_SYMBOL(lprocfs_rd_blksize);
2517 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2518 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2519 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2520 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2521 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2523 EXPORT_SYMBOL(lprocfs_write_helper);
2524 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2525 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2526 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2527 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2528 EXPORT_SYMBOL(lprocfs_stats_collect);