4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, Whamcloud, Inc.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/obdclass/lprocfs_status.c
38 * Author: Hariharan Thantry <thantry@users.sourceforge.net>
42 # define EXPORT_SYMTAB
44 #define DEBUG_SUBSYSTEM S_CLASS
47 # include <liblustre.h>
50 #include <obd_class.h>
51 #include <lprocfs_status.h>
52 #include <lustre_fsfilt.h>
53 #include <lustre_log.h>
54 #include <lustre/lustre_idl.h>
58 static int lprocfs_no_percpu_stats = 0;
59 CFS_MODULE_PARM(lprocfs_no_percpu_stats, "i", int, 0644,
60 "Do not alloc percpu data for lprocfs stats");
62 #define MAX_STRING_SIZE 128
64 /* for bug 10866, global variable */
65 CFS_DECLARE_RWSEM(_lprocfs_lock);
66 EXPORT_SYMBOL(_lprocfs_lock);
68 int lprocfs_seq_release(struct inode *inode, struct file *file)
71 return seq_release(inode, file);
73 EXPORT_SYMBOL(lprocfs_seq_release);
75 static struct proc_dir_entry *__lprocfs_srch(struct proc_dir_entry *head,
78 struct proc_dir_entry *temp;
84 while (temp != NULL) {
85 if (strcmp(temp->name, name) == 0) {
94 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
97 struct proc_dir_entry *temp;
100 temp = __lprocfs_srch(head, name);
105 /* lprocfs API calls */
107 /* Function that emulates snprintf but also has the side effect of advancing
108 the page pointer for the next write into the buffer, incrementing the total
109 length written to the buffer, and decrementing the size left in the
111 static int lprocfs_obd_snprintf(char **page, int end, int *len,
112 const char *format, ...)
120 va_start(list, format);
121 n = vsnprintf(*page, end - *len, format, list);
124 *page += n; *len += n;
128 cfs_proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
130 read_proc_t *read_proc,
131 write_proc_t *write_proc,
133 struct file_operations *fops)
135 cfs_proc_dir_entry_t *proc;
138 if (root == NULL || name == NULL)
139 return ERR_PTR(-EINVAL);
146 LPROCFS_WRITE_ENTRY();
147 proc = create_proc_entry(name, mode, root);
149 CERROR("LprocFS: No memory to create /proc entry %s", name);
150 LPROCFS_WRITE_EXIT();
151 return ERR_PTR(-ENOMEM);
153 proc->read_proc = read_proc;
154 proc->write_proc = write_proc;
157 proc->proc_fops = fops;
158 LPROCFS_WRITE_EXIT();
162 struct proc_dir_entry *lprocfs_add_symlink(const char *name,
163 struct proc_dir_entry *parent, const char *format, ...)
165 struct proc_dir_entry *entry;
169 if (parent == NULL || format == NULL)
172 OBD_ALLOC_WAIT(dest, MAX_STRING_SIZE + 1);
176 va_start(ap, format);
177 vsnprintf(dest, MAX_STRING_SIZE, format, ap);
180 entry = proc_symlink(name, parent, dest);
182 CERROR("LprocFS: Could not create symbolic link from %s to %s",
185 OBD_FREE(dest, MAX_STRING_SIZE + 1);
189 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
190 size_t size, loff_t *ppos)
192 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
193 char *page, *start = NULL;
194 int rc = 0, eof = 1, count;
196 if (*ppos >= CFS_PAGE_SIZE)
199 page = (char *)__get_free_page(GFP_KERNEL);
203 if (LPROCFS_ENTRY_AND_CHECK(dp)) {
208 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
210 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
216 /* for lustre proc read, the read count must be less than PAGE_SIZE */
225 start = page + *ppos;
226 } else if (start < page) {
230 count = (rc < size) ? rc : size;
231 if (cfs_copy_to_user(buf, start, count)) {
238 free_page((unsigned long)page);
242 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
243 size_t size, loff_t *ppos)
245 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
248 if (LPROCFS_ENTRY_AND_CHECK(dp))
251 rc = dp->write_proc(f, buf, size, dp->data);
256 static struct file_operations lprocfs_generic_fops = {
257 .owner = THIS_MODULE,
258 .read = lprocfs_fops_read,
259 .write = lprocfs_fops_write,
262 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
264 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
265 struct obd_device *obd = dp->data;
267 cfs_atomic_inc(&obd->obd_evict_inprogress);
272 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
274 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
275 struct obd_device *obd = dp->data;
277 cfs_atomic_dec(&obd->obd_evict_inprogress);
278 cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
283 struct file_operations lprocfs_evict_client_fops = {
284 .owner = THIS_MODULE,
285 .read = lprocfs_fops_read,
286 .write = lprocfs_fops_write,
287 .open = lprocfs_evict_client_open,
288 .release = lprocfs_evict_client_release,
290 EXPORT_SYMBOL(lprocfs_evict_client_fops);
295 * \param root [in] The parent proc entry on which new entry will be added.
296 * \param list [in] Array of proc entries to be added.
297 * \param data [in] The argument to be passed when entries read/write routines
298 * are called through /proc file.
300 * \retval 0 on success
303 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
308 if (root == NULL || list == NULL)
311 LPROCFS_WRITE_ENTRY();
312 while (list->name != NULL) {
313 struct proc_dir_entry *cur_root, *proc;
314 char *pathcopy, *cur, *next, pathbuf[64];
315 int pathsize = strlen(list->name) + 1;
320 /* need copy of path for strsep */
321 if (strlen(list->name) > sizeof(pathbuf) - 1) {
322 OBD_ALLOC(pathcopy, pathsize);
323 if (pathcopy == NULL)
324 GOTO(out, rc = -ENOMEM);
330 strcpy(pathcopy, list->name);
332 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
333 if (*cur =='\0') /* skip double/trailing "/" */
336 proc = __lprocfs_srch(cur_root, cur);
337 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
338 cur_root->name, cur, next,
339 (proc ? "exists" : "new"));
341 cur_root = (proc ? proc :
342 proc_mkdir(cur, cur_root));
343 } else if (proc == NULL) {
345 if (list->proc_mode != 0000) {
346 mode = list->proc_mode;
350 if (list->write_fptr)
353 proc = create_proc_entry(cur, mode, cur_root);
357 if (pathcopy != pathbuf)
358 OBD_FREE(pathcopy, pathsize);
360 if (cur_root == NULL || proc == NULL) {
361 CERROR("LprocFS: No memory to create /proc entry %s",
363 GOTO(out, rc = -ENOMEM);
367 proc->proc_fops = list->fops;
369 proc->proc_fops = &lprocfs_generic_fops;
370 proc->read_proc = list->read_fptr;
371 proc->write_proc = list->write_fptr;
372 proc->data = (list->data ? list->data : data);
376 LPROCFS_WRITE_EXIT();
380 void lprocfs_remove(struct proc_dir_entry **rooth)
382 struct proc_dir_entry *root = *rooth;
383 struct proc_dir_entry *temp = root;
384 struct proc_dir_entry *rm_entry;
385 struct proc_dir_entry *parent;
391 parent = root->parent;
392 LASSERT(parent != NULL);
393 LPROCFS_WRITE_ENTRY(); /* search vs remove race */
396 while (temp->subdir != NULL)
402 /* Memory corruption once caused this to fail, and
403 without this LASSERT we would loop here forever. */
404 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
405 "0x%p %s/%s len %d\n", rm_entry, temp->name,
406 rm_entry->name, (int)strlen(rm_entry->name));
408 #ifdef HAVE_PROCFS_USERS
409 /* if procfs uses user count to synchronize deletion of
410 * proc entry, there is no protection for rm_entry->data,
411 * then lprocfs_fops_read and lprocfs_fops_write maybe
412 * call proc_dir_entry->read_proc (or write_proc) with
413 * proc_dir_entry->data == NULL, then cause kernel Oops.
414 * see bug19706 for detailed information */
416 /* procfs won't free rm_entry->data if it isn't a LINK,
417 * and Lustre won't use rm_entry->data if it is a LINK */
418 if (S_ISLNK(rm_entry->mode))
419 rm_entry->data = NULL;
421 /* Now, the rm_entry->deleted flags is protected
422 * by _lprocfs_lock. */
423 rm_entry->data = NULL;
425 remove_proc_entry(rm_entry->name, temp);
429 LPROCFS_WRITE_EXIT();
432 void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
434 LASSERT(parent != NULL);
435 remove_proc_entry(name, parent);
438 struct proc_dir_entry *lprocfs_register(const char *name,
439 struct proc_dir_entry *parent,
440 struct lprocfs_vars *list, void *data)
442 struct proc_dir_entry *newchild;
444 newchild = lprocfs_srch(parent, name);
445 if (newchild != NULL) {
446 CERROR(" Lproc: Attempting to register %s more than once \n",
448 return ERR_PTR(-EALREADY);
451 newchild = proc_mkdir(name, parent);
452 if (newchild != NULL && list != NULL) {
453 int rc = lprocfs_add_vars(newchild, list, data);
455 lprocfs_remove(&newchild);
462 /* Generic callbacks */
463 int lprocfs_rd_uint(char *page, char **start, off_t off,
464 int count, int *eof, void *data)
466 unsigned int *temp = data;
467 return snprintf(page, count, "%u\n", *temp);
470 int lprocfs_wr_uint(struct file *file, const char *buffer,
471 unsigned long count, void *data)
474 char dummy[MAX_STRING_SIZE + 1], *end;
477 dummy[MAX_STRING_SIZE] = '\0';
478 if (cfs_copy_from_user(dummy, buffer, MAX_STRING_SIZE))
481 tmp = simple_strtoul(dummy, &end, 0);
485 *p = (unsigned int)tmp;
489 int lprocfs_rd_u64(char *page, char **start, off_t off,
490 int count, int *eof, void *data)
492 LASSERT(data != NULL);
494 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
497 int lprocfs_rd_atomic(char *page, char **start, off_t off,
498 int count, int *eof, void *data)
500 cfs_atomic_t *atom = data;
501 LASSERT(atom != NULL);
503 return snprintf(page, count, "%d\n", cfs_atomic_read(atom));
506 int lprocfs_wr_atomic(struct file *file, const char *buffer,
507 unsigned long count, void *data)
509 cfs_atomic_t *atm = data;
513 rc = lprocfs_write_helper(buffer, count, &val);
520 cfs_atomic_set(atm, val);
524 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
525 int *eof, void *data)
527 struct obd_device *obd = data;
529 LASSERT(obd != NULL);
531 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
534 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
535 int *eof, void *data)
537 struct obd_device *dev = data;
539 LASSERT(dev != NULL);
540 LASSERT(dev->obd_name != NULL);
542 return snprintf(page, count, "%s\n", dev->obd_name);
545 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
548 struct obd_device *obd = data;
550 LASSERT(obd != NULL);
551 LASSERT(obd->obd_fsops != NULL);
552 LASSERT(obd->obd_fsops->fs_type != NULL);
553 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
556 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
557 int *eof, void *data)
559 struct obd_device *obd = data;
560 struct obd_statfs osfs;
561 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
562 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
566 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
571 int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
572 int *eof, void *data)
574 struct obd_device *obd = data;
575 struct obd_statfs osfs;
576 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
577 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
580 __u32 blk_size = osfs.os_bsize >> 10;
581 __u64 result = osfs.os_blocks;
583 while (blk_size >>= 1)
587 rc = snprintf(page, count, LPU64"\n", result);
592 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
593 int *eof, void *data)
595 struct obd_device *obd = data;
596 struct obd_statfs osfs;
597 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
598 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
601 __u32 blk_size = osfs.os_bsize >> 10;
602 __u64 result = osfs.os_bfree;
604 while (blk_size >>= 1)
608 rc = snprintf(page, count, LPU64"\n", result);
613 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
614 int *eof, void *data)
616 struct obd_device *obd = data;
617 struct obd_statfs osfs;
618 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
619 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
622 __u32 blk_size = osfs.os_bsize >> 10;
623 __u64 result = osfs.os_bavail;
625 while (blk_size >>= 1)
629 rc = snprintf(page, count, LPU64"\n", result);
634 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
635 int *eof, void *data)
637 struct obd_device *obd = data;
638 struct obd_statfs osfs;
639 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
640 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
644 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
650 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
651 int *eof, void *data)
653 struct obd_device *obd = data;
654 struct obd_statfs osfs;
655 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
656 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
660 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
665 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
666 int *eof, void *data)
668 struct obd_device *obd = data;
669 struct obd_import *imp;
670 char *imp_state_name = NULL;
673 LASSERT(obd != NULL);
674 LPROCFS_CLIMP_CHECK(obd);
675 imp = obd->u.cli.cl_import;
676 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
678 rc = snprintf(page, count, "%s\t%s%s\n",
679 obd2cli_tgt(obd), imp_state_name,
680 imp->imp_deactive ? "\tDEACTIVATED" : "");
682 LPROCFS_CLIMP_EXIT(obd);
686 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
687 int *eof, void *data)
689 struct obd_device *obd = data;
690 struct ptlrpc_connection *conn;
693 LASSERT(obd != NULL);
695 LPROCFS_CLIMP_CHECK(obd);
696 conn = obd->u.cli.cl_import->imp_connection;
698 if (conn && obd->u.cli.cl_import) {
699 rc = snprintf(page, count, "%s\n",
700 conn->c_remote_uuid.uuid);
702 rc = snprintf(page, count, "%s\n", "<none>");
705 LPROCFS_CLIMP_EXIT(obd);
709 /** add up per-cpu counters */
710 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
711 struct lprocfs_counter *cnt)
713 unsigned int num_cpu;
714 struct lprocfs_counter t;
715 struct lprocfs_counter *percpu_cntr;
718 memset(cnt, 0, sizeof(*cnt));
721 /* set count to 1 to avoid divide-by-zero errs in callers */
726 cnt->lc_min = LC_MIN_INIT;
728 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
730 for (i = 0; i < num_cpu; i++) {
731 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
734 centry = cfs_atomic_read(&percpu_cntr-> \
736 t.lc_count = percpu_cntr->lc_count;
737 t.lc_sum = percpu_cntr->lc_sum;
738 t.lc_min = percpu_cntr->lc_min;
739 t.lc_max = percpu_cntr->lc_max;
740 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
741 } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
743 centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
745 cnt->lc_count += t.lc_count;
746 cnt->lc_sum += t.lc_sum;
747 if (t.lc_min < cnt->lc_min)
748 cnt->lc_min = t.lc_min;
749 if (t.lc_max > cnt->lc_max)
750 cnt->lc_max = t.lc_max;
751 cnt->lc_sumsquare += t.lc_sumsquare;
754 cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
755 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
759 * Append a space separated list of current set flags to str.
761 #define flag2str(flag) \
762 if (imp->imp_##flag && max - len > 0) \
763 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
764 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
768 if (imp->imp_obd->obd_no_recov)
769 len += snprintf(str, max - len, "no_recov");
773 flag2str(replayable);
779 static const char *obd_connect_names[] = {
793 "join_file(obsolete)",
797 "remote_client_by_force",
806 "mds_mds_connection",
809 "alt_checksum_algorithm",
828 int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
833 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
835 ret += snprintf(page + ret, count - ret, "%s%s",
836 ret ? sep : "", obd_connect_names[i]);
838 if (flags & ~(mask - 1))
839 ret += snprintf(page + ret, count - ret,
840 "%sunknown flags "LPX64,
841 ret ? sep : "", flags & ~(mask - 1));
844 EXPORT_SYMBOL(obd_connect_flags2str);
846 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
847 int *eof, void *data)
849 struct lprocfs_counter ret;
850 struct obd_device *obd = (struct obd_device *)data;
851 struct obd_import *imp;
852 struct obd_import_conn *conn;
855 LASSERT(obd != NULL);
856 LPROCFS_CLIMP_CHECK(obd);
857 imp = obd->u.cli.cl_import;
860 i = snprintf(page, count,
869 ptlrpc_import_state_name(imp->imp_state),
870 imp->imp_connect_data.ocd_instance);
871 i += obd_connect_flags2str(page + i, count - i,
872 imp->imp_connect_data.ocd_connect_flags,
874 i += snprintf(page + i, count - i,
877 i += obd_import_flags2str(imp, page + i, count - i);
879 i += snprintf(page + i, count - i,
882 " failover_nids: [");
883 cfs_spin_lock(&imp->imp_lock);
885 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
886 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
887 libcfs_nid2str(conn->oic_conn->c_peer.nid));
890 cfs_spin_unlock(&imp->imp_lock);
891 i += snprintf(page + i, count - i,
893 " current_connection: %s\n"
894 " connection_attempts: %u\n"
896 " in-progress_invalidations: %u\n",
897 libcfs_nid2str(imp->imp_connection->c_peer.nid),
900 cfs_atomic_read(&imp->imp_inval_count));
902 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
903 if (ret.lc_count != 0) {
904 /* first argument to do_div MUST be __u64 */
905 __u64 sum = ret.lc_sum;
906 do_div(sum, ret.lc_count);
910 i += snprintf(page + i, count - i,
913 " unregistering: %u\n"
915 " avg_waittime: "LPU64" %s\n",
916 cfs_atomic_read(&imp->imp_inflight),
917 cfs_atomic_read(&imp->imp_unregistering),
918 cfs_atomic_read(&imp->imp_timeouts),
919 ret.lc_sum, ret.lc_units);
922 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
923 if (imp->imp_at.iat_portal[j] == 0)
925 k = max_t(unsigned int, k,
926 at_get(&imp->imp_at.iat_service_estimate[j]));
928 i += snprintf(page + i, count - i,
929 " service_estimates:\n"
930 " services: %u sec\n"
931 " network: %u sec\n",
933 at_get(&imp->imp_at.iat_net_latency));
935 i += snprintf(page + i, count - i,
937 " last_replay: "LPU64"\n"
938 " peer_committed: "LPU64"\n"
939 " last_checked: "LPU64"\n",
940 imp->imp_last_replay_transno,
941 imp->imp_peer_committed_transno,
942 imp->imp_last_transno_checked);
945 for (rw = 0; rw <= 1; rw++) {
946 lprocfs_stats_collect(obd->obd_svc_stats,
947 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
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_data_averages:\n"
956 " bytes_per_rpc: "LPU64"\n",
957 rw ? "write" : "read",
961 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
962 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
963 if (ret.lc_sum > 0 && ret.lc_count != 0) {
964 /* first argument to do_div MUST be __u64 */
965 __u64 sum = ret.lc_sum;
966 do_div(sum, ret.lc_count);
968 i += snprintf(page + i, count - i,
969 " %s_per_rpc: "LPU64"\n",
970 ret.lc_units, ret.lc_sum);
973 i += snprintf(page + i, count - i,
974 " MB_per_sec: %u.%.02u\n",
975 k / j, (100 * k / j) % 100);
979 LPROCFS_CLIMP_EXIT(obd);
983 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
984 int *eof, void *data)
986 struct obd_device *obd = (struct obd_device *)data;
987 struct obd_import *imp;
990 LASSERT(obd != NULL);
991 LPROCFS_CLIMP_CHECK(obd);
992 imp = obd->u.cli.cl_import;
995 i = snprintf(page, count, "current_state: %s\n",
996 ptlrpc_import_state_name(imp->imp_state));
997 i += snprintf(page + i, count - i,
999 k = imp->imp_state_hist_idx;
1000 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
1001 struct import_state_hist *ish =
1002 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
1003 if (ish->ish_state == 0)
1005 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
1007 ptlrpc_import_state_name(ish->ish_state));
1010 LPROCFS_CLIMP_EXIT(obd);
1014 int lprocfs_at_hist_helper(char *page, int count, int rc,
1015 struct adaptive_timeout *at)
1018 for (i = 0; i < AT_BINS; i++)
1019 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1020 rc += snprintf(page + rc, count - rc, "\n");
1024 /* See also ptlrpc_lprocfs_rd_timeouts */
1025 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1026 int *eof, void *data)
1028 struct obd_device *obd = (struct obd_device *)data;
1029 struct obd_import *imp;
1030 unsigned int cur, worst;
1035 LASSERT(obd != NULL);
1036 LPROCFS_CLIMP_CHECK(obd);
1037 imp = obd->u.cli.cl_import;
1040 now = cfs_time_current_sec();
1042 /* Some network health info for kicks */
1043 s2dhms(&ts, now - imp->imp_last_reply_time);
1044 rc += snprintf(page + rc, count - rc,
1045 "%-10s : %ld, "DHMS_FMT" ago\n",
1046 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1048 cur = at_get(&imp->imp_at.iat_net_latency);
1049 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1050 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1051 s2dhms(&ts, now - worstt);
1052 rc += snprintf(page + rc, count - rc,
1053 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1054 "network", cur, worst, worstt, DHMS_VARS(&ts));
1055 rc = lprocfs_at_hist_helper(page, count, rc,
1056 &imp->imp_at.iat_net_latency);
1058 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1059 if (imp->imp_at.iat_portal[i] == 0)
1061 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1062 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1063 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1064 s2dhms(&ts, now - worstt);
1065 rc += snprintf(page + rc, count - rc,
1066 "portal %-2d : cur %3u worst %3u (at %ld, "
1067 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1068 cur, worst, worstt, DHMS_VARS(&ts));
1069 rc = lprocfs_at_hist_helper(page, count, rc,
1070 &imp->imp_at.iat_service_estimate[i]);
1073 LPROCFS_CLIMP_EXIT(obd);
1077 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1078 int count, int *eof, void *data)
1080 struct obd_device *obd = data;
1084 LPROCFS_CLIMP_CHECK(obd);
1085 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1086 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1087 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1088 ret += snprintf(page + ret, count - ret, "\n");
1089 LPROCFS_CLIMP_EXIT(obd);
1092 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1094 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1095 int *eof, void *data)
1097 struct obd_device *obd = data;
1099 LASSERT(obd != NULL);
1101 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1104 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1105 int *eof, void *data)
1107 struct obd_type *class = (struct obd_type*) data;
1109 LASSERT(class != NULL);
1111 return snprintf(page, count, "%d\n", class->typ_refcnt);
1114 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1118 LASSERT(obd != NULL);
1119 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1120 LASSERT(obd->obd_type->typ_procroot != NULL);
1122 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1123 obd->obd_type->typ_procroot,
1125 if (IS_ERR(obd->obd_proc_entry)) {
1126 rc = PTR_ERR(obd->obd_proc_entry);
1127 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1128 obd->obd_proc_entry = NULL;
1133 int lprocfs_obd_cleanup(struct obd_device *obd)
1137 if (obd->obd_proc_exports_entry) {
1138 /* Should be no exports left */
1139 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1140 lprocfs_remove(&obd->obd_proc_exports_entry);
1141 obd->obd_proc_exports_entry = NULL;
1143 if (obd->obd_proc_entry) {
1144 lprocfs_remove(&obd->obd_proc_entry);
1145 obd->obd_proc_entry = NULL;
1150 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1152 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1153 client_stat->nid_proc, client_stat->nid_stats,
1154 client_stat->nid_brw_stats);
1156 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1157 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1158 atomic_read(&client_stat->nid_exp_ref_count));
1160 if (client_stat->nid_proc)
1161 lprocfs_remove(&client_stat->nid_proc);
1163 if (client_stat->nid_stats)
1164 lprocfs_free_stats(&client_stat->nid_stats);
1166 if (client_stat->nid_brw_stats)
1167 OBD_FREE_PTR(client_stat->nid_brw_stats);
1169 if (client_stat->nid_ldlm_stats)
1170 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1172 OBD_FREE_PTR(client_stat);
1177 void lprocfs_free_per_client_stats(struct obd_device *obd)
1179 cfs_hash_t *hash = obd->obd_nid_stats_hash;
1180 struct nid_stat *stat;
1183 /* we need extra list - because hash_exit called to early */
1184 /* not need locking because all clients is died */
1185 while (!cfs_list_empty(&obd->obd_nid_stats)) {
1186 stat = cfs_list_entry(obd->obd_nid_stats.next,
1187 struct nid_stat, nid_list);
1188 cfs_list_del_init(&stat->nid_list);
1189 cfs_hash_del(hash, &stat->nid, &stat->nid_hash);
1190 lprocfs_free_client_stats(stat);
1195 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1196 enum lprocfs_stats_flags flags)
1198 struct lprocfs_stats *stats;
1199 unsigned int percpusize;
1201 unsigned int num_cpu;
1206 if (lprocfs_no_percpu_stats != 0)
1207 flags |= LPROCFS_STATS_FLAG_NOPERCPU;
1209 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1212 num_cpu = cfs_num_possible_cpus();
1214 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1218 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1219 stats->ls_flags = flags;
1220 cfs_spin_lock_init(&stats->ls_lock);
1221 /* Use this lock only if there are no percpu areas */
1223 stats->ls_flags = 0;
1226 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1228 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1230 for (i = 0; i < num_cpu; i++) {
1231 OBD_ALLOC(stats->ls_percpu[i], percpusize);
1232 if (stats->ls_percpu[i] == NULL) {
1233 for (j = 0; j < i; j++) {
1234 OBD_FREE(stats->ls_percpu[j], percpusize);
1235 stats->ls_percpu[j] = NULL;
1240 if (stats->ls_percpu[0] == NULL) {
1241 OBD_FREE(stats, offsetof(typeof(*stats),
1242 ls_percpu[num_cpu]));
1246 stats->ls_num = num;
1250 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1252 struct lprocfs_stats *stats = *statsh;
1253 unsigned int num_cpu;
1254 unsigned int percpusize;
1257 if (stats == NULL || stats->ls_num == 0)
1261 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1264 num_cpu = cfs_num_possible_cpus();
1266 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1268 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1269 for (i = 0; i < num_cpu; i++)
1270 OBD_FREE(stats->ls_percpu[i], percpusize);
1271 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1274 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1276 struct lprocfs_counter *percpu_cntr;
1278 unsigned int num_cpu;
1280 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1282 for (i = 0; i < num_cpu; i++) {
1283 for (j = 0; j < stats->ls_num; j++) {
1284 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1285 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1286 percpu_cntr->lc_count = 0;
1287 percpu_cntr->lc_sum = 0;
1288 percpu_cntr->lc_min = LC_MIN_INIT;
1289 percpu_cntr->lc_max = 0;
1290 percpu_cntr->lc_sumsquare = 0;
1291 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1295 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1298 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1299 size_t len, loff_t *off)
1301 struct seq_file *seq = file->private_data;
1302 struct lprocfs_stats *stats = seq->private;
1304 lprocfs_clear_stats(stats);
1309 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1311 struct lprocfs_stats *stats = p->private;
1312 /* return 1st cpu location */
1313 return (*pos >= stats->ls_num) ? NULL :
1314 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1317 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1321 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1323 struct lprocfs_stats *stats = p->private;
1325 return (*pos >= stats->ls_num) ? NULL :
1326 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1329 /* seq file export of one lprocfs counter */
1330 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1332 struct lprocfs_stats *stats = p->private;
1333 struct lprocfs_counter *cntr = v;
1334 struct lprocfs_counter ret;
1337 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1339 cfs_gettimeofday(&now);
1340 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1341 "snapshot_time", now.tv_sec, now.tv_usec);
1345 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1347 lprocfs_stats_collect(stats, idx, &ret);
1349 if (ret.lc_count == 0)
1352 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1353 ret.lc_count, cntr->lc_units);
1358 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1359 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1360 ret.lc_min, ret.lc_max, ret.lc_sum);
1363 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1364 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1368 rc = seq_printf(p, "\n");
1370 return (rc < 0) ? rc : 0;
1373 struct seq_operations lprocfs_stats_seq_sops = {
1374 start: lprocfs_stats_seq_start,
1375 stop: lprocfs_stats_seq_stop,
1376 next: lprocfs_stats_seq_next,
1377 show: lprocfs_stats_seq_show,
1380 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1382 struct proc_dir_entry *dp = PDE(inode);
1383 struct seq_file *seq;
1386 if (LPROCFS_ENTRY_AND_CHECK(dp))
1389 rc = seq_open(file, &lprocfs_stats_seq_sops);
1394 seq = file->private_data;
1395 seq->private = dp->data;
1399 struct file_operations lprocfs_stats_seq_fops = {
1400 .owner = THIS_MODULE,
1401 .open = lprocfs_stats_seq_open,
1403 .write = lprocfs_stats_seq_write,
1404 .llseek = seq_lseek,
1405 .release = lprocfs_seq_release,
1408 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1409 struct lprocfs_stats *stats)
1411 struct proc_dir_entry *entry;
1412 LASSERT(root != NULL);
1414 LPROCFS_WRITE_ENTRY();
1415 entry = create_proc_entry(name, 0644, root);
1417 entry->proc_fops = &lprocfs_stats_seq_fops;
1418 entry->data = stats;
1421 LPROCFS_WRITE_EXIT();
1429 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1430 unsigned conf, const char *name, const char *units)
1432 struct lprocfs_counter *c;
1434 unsigned int num_cpu;
1436 LASSERT(stats != NULL);
1438 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1440 for (i = 0; i < num_cpu; i++) {
1441 c = &(stats->ls_percpu[i]->lp_cntr[index]);
1442 c->lc_config = conf;
1445 c->lc_min = LC_MIN_INIT;
1448 c->lc_units = units;
1451 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1453 EXPORT_SYMBOL(lprocfs_counter_init);
1455 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1457 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1458 LASSERT(coffset < stats->ls_num); \
1459 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1462 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1467 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1468 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1469 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1470 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1471 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1472 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1473 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1474 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1475 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1476 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1477 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1478 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1479 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1480 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1481 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1482 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1483 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1484 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1485 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1486 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1487 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1488 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1489 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1490 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1491 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1492 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1493 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1494 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1495 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1496 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1497 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1498 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1499 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1500 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1501 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1502 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1503 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1504 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1505 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1506 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1507 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1508 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1509 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1510 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1511 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1512 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1513 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1514 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1515 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1516 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1517 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1518 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1519 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1520 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1521 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1522 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1523 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1524 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1525 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1526 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1527 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1528 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1529 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1530 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1531 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1532 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1535 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1537 struct lprocfs_stats *stats;
1538 unsigned int num_stats;
1541 LASSERT(obd->obd_stats == NULL);
1542 LASSERT(obd->obd_proc_entry != NULL);
1543 LASSERT(obd->obd_cntr_base == 0);
1545 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1546 num_private_stats - 1 /* o_owner */;
1547 stats = lprocfs_alloc_stats(num_stats, 0);
1551 lprocfs_init_ops_stats(num_private_stats, stats);
1553 for (i = num_private_stats; i < num_stats; i++) {
1554 /* If this LBUGs, it is likely that an obd
1555 * operation was added to struct obd_ops in
1556 * <obd.h>, and that the corresponding line item
1557 * LPROCFS_OBD_OP_INIT(.., .., opname)
1558 * is missing from the list above. */
1559 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1560 "Missing obd_stat initializer obd_op "
1561 "operation at offset %d.\n", i - num_private_stats);
1563 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1565 lprocfs_free_stats(&stats);
1567 obd->obd_stats = stats;
1568 obd->obd_cntr_base = num_private_stats;
1573 void lprocfs_free_obd_stats(struct obd_device *obd)
1576 lprocfs_free_stats(&obd->obd_stats);
1579 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1581 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1582 LASSERT(coffset < stats->ls_num); \
1583 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1586 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1588 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1589 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1590 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1591 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1592 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1593 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1594 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1595 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1596 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1597 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1598 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1599 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1600 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1601 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1602 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1603 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1604 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1605 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1606 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1607 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1608 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1609 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1610 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1611 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1612 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1613 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1614 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1615 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1616 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1617 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1618 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1619 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1622 int lprocfs_alloc_md_stats(struct obd_device *obd,
1623 unsigned num_private_stats)
1625 struct lprocfs_stats *stats;
1626 unsigned int num_stats;
1629 LASSERT(obd->md_stats == NULL);
1630 LASSERT(obd->obd_proc_entry != NULL);
1631 LASSERT(obd->md_cntr_base == 0);
1633 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1635 stats = lprocfs_alloc_stats(num_stats, 0);
1639 lprocfs_init_mps_stats(num_private_stats, stats);
1641 for (i = num_private_stats; i < num_stats; i++) {
1642 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1643 CERROR("Missing md_stat initializer md_op "
1644 "operation at offset %d. Aborting.\n",
1645 i - num_private_stats);
1649 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1651 lprocfs_free_stats(&stats);
1653 obd->md_stats = stats;
1654 obd->md_cntr_base = num_private_stats;
1659 void lprocfs_free_md_stats(struct obd_device *obd)
1661 struct lprocfs_stats *stats = obd->md_stats;
1663 if (stats != NULL) {
1664 obd->md_stats = NULL;
1665 obd->md_cntr_base = 0;
1666 lprocfs_free_stats(&stats);
1670 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1672 lprocfs_counter_init(ldlm_stats,
1673 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1674 0, "ldlm_enqueue", "reqs");
1675 lprocfs_counter_init(ldlm_stats,
1676 LDLM_CONVERT - LDLM_FIRST_OPC,
1677 0, "ldlm_convert", "reqs");
1678 lprocfs_counter_init(ldlm_stats,
1679 LDLM_CANCEL - LDLM_FIRST_OPC,
1680 0, "ldlm_cancel", "reqs");
1681 lprocfs_counter_init(ldlm_stats,
1682 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1683 0, "ldlm_bl_callback", "reqs");
1684 lprocfs_counter_init(ldlm_stats,
1685 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1686 0, "ldlm_cp_callback", "reqs");
1687 lprocfs_counter_init(ldlm_stats,
1688 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1689 0, "ldlm_gl_callback", "reqs");
1692 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1693 int *eof, void *data)
1695 struct obd_export *exp = data;
1696 LASSERT(exp != NULL);
1698 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1701 struct exp_uuid_cb_data {
1709 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1710 int count, int *eof, int *len)
1712 cb_data->page = page;
1713 cb_data->count = count;
1718 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1719 cfs_hlist_node_t *hnode, void *cb_data)
1722 struct obd_export *exp = cfs_hash_object(hs, hnode);
1723 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1725 if (exp->exp_nid_stats)
1726 *data->len += snprintf((data->page + *data->len),
1727 data->count, "%s\n",
1728 obd_uuid2str(&exp->exp_client_uuid));
1732 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1733 int *eof, void *data)
1735 struct nid_stat *stats = (struct nid_stat *)data;
1736 struct exp_uuid_cb_data cb_data;
1737 struct obd_device *obd = stats->nid_obd;
1742 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1743 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1744 lprocfs_exp_print_uuid, &cb_data);
1745 return (*cb_data.len);
1748 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1749 cfs_hlist_node_t *hnode, void *cb_data)
1752 struct exp_uuid_cb_data *data = cb_data;
1753 struct obd_export *exp = cfs_hash_object(hs, hnode);
1755 if (exp->exp_lock_hash != NULL) {
1757 *data->len += cfs_hash_debug_header(data->page,
1760 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1767 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1768 int *eof, void *data)
1770 struct nid_stat *stats = (struct nid_stat *)data;
1771 struct exp_uuid_cb_data cb_data;
1772 struct obd_device *obd = stats->nid_obd;
1777 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1779 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1780 lprocfs_exp_print_hash, &cb_data);
1781 return (*cb_data.len);
1784 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1785 int count, int *eof, void *data)
1788 return snprintf(page, count, "%s\n",
1789 "Write into this file to clear all nid stats and "
1790 "stale nid entries");
1792 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1794 static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1796 struct nid_stat *stat = obj;
1800 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1801 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1802 /* object has only hash references. */
1803 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1804 cfs_list_move(&stat->nid_list, data);
1805 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1808 /* we has reference to object - only clear data*/
1809 if (stat->nid_stats)
1810 lprocfs_clear_stats(stat->nid_stats);
1812 if (stat->nid_brw_stats) {
1813 for (i = 0; i < BRW_LAST; i++)
1814 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1819 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1820 unsigned long count, void *data)
1822 struct obd_device *obd = (struct obd_device *)data;
1823 struct nid_stat *client_stat;
1824 CFS_LIST_HEAD(free_list);
1826 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1827 lprocfs_nid_stats_clear_write_cb, &free_list);
1829 while (!cfs_list_empty(&free_list)) {
1830 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1832 cfs_list_del_init(&client_stat->nid_list);
1833 lprocfs_free_client_stats(client_stat);
1838 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1840 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1842 struct nid_stat *new_stat, *old_stat;
1843 struct obd_device *obd = NULL;
1844 cfs_proc_dir_entry_t *entry;
1845 char *buffer = NULL;
1851 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1852 !exp->exp_obd->obd_nid_stats_hash)
1855 /* not test against zero because eric say:
1856 * You may only test nid against another nid, or LNET_NID_ANY.
1857 * Anything else is nonsense.*/
1858 if (!nid || *nid == LNET_NID_ANY)
1863 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1865 OBD_ALLOC_PTR(new_stat);
1866 if (new_stat == NULL)
1869 new_stat->nid = *nid;
1870 new_stat->nid_obd = exp->exp_obd;
1871 /* we need set default refcount to 1 to balance obd_disconnect */
1872 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1874 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1875 nid, &new_stat->nid_hash);
1876 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1877 old_stat, libcfs_nid2str(*nid),
1878 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1880 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1881 * been and will never be called. */
1882 if (exp->exp_nid_stats) {
1883 nidstat_putref(exp->exp_nid_stats);
1884 exp->exp_nid_stats = NULL;
1887 /* Return -EALREADY here so that we know that the /proc
1888 * entry already has been created */
1889 if (old_stat != new_stat) {
1890 exp->exp_nid_stats = old_stat;
1891 GOTO(destroy_new, rc = -EALREADY);
1893 /* not found - create */
1894 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1896 GOTO(destroy_new, rc = -ENOMEM);
1898 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1899 new_stat->nid_proc = lprocfs_register(buffer,
1900 obd->obd_proc_exports_entry,
1902 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1904 if (new_stat->nid_proc == NULL) {
1905 CERROR("Error making export directory for nid %s\n",
1906 libcfs_nid2str(*nid));
1907 GOTO(destroy_new_ns, rc = -ENOMEM);
1910 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1911 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1912 if (IS_ERR(entry)) {
1913 CWARN("Error adding the NID stats file\n");
1914 rc = PTR_ERR(entry);
1915 GOTO(destroy_new_ns, rc);
1918 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1919 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1920 if (IS_ERR(entry)) {
1921 CWARN("Error adding the hash file\n");
1922 rc = PTR_ERR(entry);
1923 GOTO(destroy_new_ns, rc);
1926 exp->exp_nid_stats = new_stat;
1928 /* protect competitive add to list, not need locking on destroy */
1929 cfs_spin_lock(&obd->obd_nid_lock);
1930 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1931 cfs_spin_unlock(&obd->obd_nid_lock);
1936 if (new_stat->nid_proc != NULL)
1937 lprocfs_remove(&new_stat->nid_proc);
1938 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1941 nidstat_putref(new_stat);
1942 OBD_FREE_PTR(new_stat);
1946 int lprocfs_exp_cleanup(struct obd_export *exp)
1948 struct nid_stat *stat = exp->exp_nid_stats;
1950 if(!stat || !exp->exp_obd)
1953 nidstat_putref(exp->exp_nid_stats);
1954 exp->exp_nid_stats = NULL;
1959 int lprocfs_write_helper(const char *buffer, unsigned long count,
1962 return lprocfs_write_frac_helper(buffer, count, val, 1);
1965 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1968 char kernbuf[20], *end, *pbuf;
1970 if (count > (sizeof(kernbuf) - 1))
1973 if (cfs_copy_from_user(kernbuf, buffer, count))
1976 kernbuf[count] = '\0';
1983 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1987 if (end != NULL && *end == '.') {
1988 int temp_val, pow = 1;
1992 if (strlen(pbuf) > 5)
1993 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1995 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1998 for (i = 0; i < (end - pbuf); i++)
2001 *val += temp_val / pow;
2007 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
2010 long decimal_val, frac_val;
2016 decimal_val = val / mult;
2017 prtn = snprintf(buffer, count, "%ld", decimal_val);
2018 frac_val = val % mult;
2020 if (prtn < (count - 4) && frac_val > 0) {
2022 int i, temp_mult = 1, frac_bits = 0;
2024 temp_frac = frac_val * 10;
2025 buffer[prtn++] = '.';
2026 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2027 /* only reserved 2 bits fraction */
2028 buffer[prtn++] ='0';
2033 * Need to think these cases :
2034 * 1. #echo x.00 > /proc/xxx output result : x
2035 * 2. #echo x.0x > /proc/xxx output result : x.0x
2036 * 3. #echo x.x0 > /proc/xxx output result : x.x
2037 * 4. #echo x.xx > /proc/xxx output result : x.xx
2038 * Only reserved 2 bits fraction.
2040 for (i = 0; i < (5 - prtn); i++)
2043 frac_bits = min((int)count - prtn, 3 - frac_bits);
2044 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2045 frac_val * temp_mult / mult);
2048 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2050 if (buffer[prtn] == '.') {
2057 buffer[prtn++] ='\n';
2061 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2063 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2066 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2067 __u64 *val, int mult)
2069 char kernbuf[22], *end, *pbuf;
2070 __u64 whole, frac = 0, units;
2071 unsigned frac_d = 1;
2073 if (count > (sizeof(kernbuf) - 1))
2076 if (cfs_copy_from_user(kernbuf, buffer, count))
2079 kernbuf[count] = '\0';
2086 whole = simple_strtoull(pbuf, &end, 10);
2090 if (end != NULL && *end == '.') {
2094 /* need to limit frac_d to a __u32 */
2095 if (strlen(pbuf) > 10)
2098 frac = simple_strtoull(pbuf, &end, 10);
2099 /* count decimal places */
2100 for (i = 0; i < (end - pbuf); i++)
2117 /* Specified units override the multiplier */
2119 mult = mult < 0 ? -units : units;
2122 do_div(frac, frac_d);
2123 *val = whole * mult + frac;
2127 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2128 struct file_operations *seq_fops, void *data)
2130 struct proc_dir_entry *entry;
2133 LPROCFS_WRITE_ENTRY();
2134 entry = create_proc_entry(name, mode, parent);
2136 entry->proc_fops = seq_fops;
2139 LPROCFS_WRITE_EXIT();
2146 EXPORT_SYMBOL(lprocfs_seq_create);
2148 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2150 struct file_operations *seq_fops,
2153 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2154 mode, seq_fops, data));
2156 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2158 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2160 if (value >= OBD_HIST_MAX)
2161 value = OBD_HIST_MAX - 1;
2163 cfs_spin_lock(&oh->oh_lock);
2164 oh->oh_buckets[value]++;
2165 cfs_spin_unlock(&oh->oh_lock);
2167 EXPORT_SYMBOL(lprocfs_oh_tally);
2169 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2173 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2176 lprocfs_oh_tally(oh, val);
2178 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2180 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2182 unsigned long ret = 0;
2185 for (i = 0; i < OBD_HIST_MAX; i++)
2186 ret += oh->oh_buckets[i];
2189 EXPORT_SYMBOL(lprocfs_oh_sum);
2191 void lprocfs_oh_clear(struct obd_histogram *oh)
2193 cfs_spin_lock(&oh->oh_lock);
2194 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2195 cfs_spin_unlock(&oh->oh_lock);
2197 EXPORT_SYMBOL(lprocfs_oh_clear);
2199 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2200 int count, int *eof, void *data)
2202 struct obd_device *obd = data;
2208 c += cfs_hash_debug_header(page, count);
2209 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2210 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2211 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2212 #ifdef HAVE_QUOTA_SUPPORT
2213 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2214 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2215 page + c, count - c);
2220 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2222 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2223 int count, int *eof, void *data)
2225 struct obd_device *obd = data;
2228 LASSERT(obd != NULL);
2229 LASSERT(count >= 0);
2231 /* Set start of user data returned to
2232 page + off since the user may have
2233 requested to read much smaller than
2234 what we need to read */
2235 *start = page + off;
2237 /* We know we are allocated a page here.
2238 Also we know that this function will
2239 not need to write more than a page
2240 so we can truncate at CFS_PAGE_SIZE. */
2241 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2243 /* Initialize the page */
2244 memset(page, 0, size);
2246 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2248 if (obd->obd_max_recoverable_clients == 0) {
2249 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2255 /* sampled unlocked, but really... */
2256 if (obd->obd_recovering == 0) {
2257 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2259 if (lprocfs_obd_snprintf(&page, size, &len,
2260 "recovery_start: %lu\n",
2261 obd->obd_recovery_start) <= 0)
2263 if (lprocfs_obd_snprintf(&page, size, &len,
2264 "recovery_duration: %lu\n",
2265 obd->obd_recovery_end -
2266 obd->obd_recovery_start) <= 0)
2268 /* Number of clients that have completed recovery */
2269 if (lprocfs_obd_snprintf(&page, size, &len,
2270 "completed_clients: %d/%d\n",
2271 obd->obd_max_recoverable_clients -
2272 obd->obd_stale_clients,
2273 obd->obd_max_recoverable_clients) <= 0)
2275 if (lprocfs_obd_snprintf(&page, size, &len,
2276 "replayed_requests: %d\n",
2277 obd->obd_replayed_requests) <= 0)
2279 if (lprocfs_obd_snprintf(&page, size, &len,
2280 "last_transno: "LPD64"\n",
2281 obd->obd_next_recovery_transno - 1)<=0)
2283 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2284 obd->obd_version_recov ? "ON" : "OFF")<=0)
2286 if (lprocfs_obd_snprintf(&page, size, &len, "IR: %s\n",
2287 obd->obd_no_ir ? "OFF" : "ON") <= 0)
2292 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2294 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2295 obd->obd_recovery_start) <= 0)
2297 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2298 cfs_time_current_sec() >=
2299 obd->obd_recovery_start +
2300 obd->obd_recovery_timeout ? 0 :
2301 obd->obd_recovery_start +
2302 obd->obd_recovery_timeout -
2303 cfs_time_current_sec()) <= 0)
2305 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2306 cfs_atomic_read(&obd->obd_connected_clients),
2307 obd->obd_max_recoverable_clients) <= 0)
2309 /* Number of clients that have completed recovery */
2310 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2311 cfs_atomic_read(&obd->obd_req_replay_clients))
2314 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2315 cfs_atomic_read(&obd->obd_lock_replay_clients))
2318 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2319 cfs_atomic_read(&obd->obd_connected_clients) -
2320 cfs_atomic_read(&obd->obd_lock_replay_clients))
2323 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2324 obd->obd_stale_clients) <= 0)
2326 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2327 obd->obd_replayed_requests) <= 0)
2329 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2330 obd->obd_requests_queued_for_recovery) <= 0)
2333 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2334 obd->obd_next_recovery_transno) <= 0)
2340 return min(count, len - (int)off);
2342 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2344 int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off,
2345 int count, int *eof, void *data)
2347 struct obd_device *obd = (struct obd_device *)data;
2348 LASSERT(obd != NULL);
2350 return snprintf(page, count, "%d\n",
2351 obd->obd_recovery_ir_factor);
2353 EXPORT_SYMBOL(lprocfs_obd_rd_ir_factor);
2355 int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer,
2356 unsigned long count, void *data)
2358 struct obd_device *obd = (struct obd_device *)data;
2360 LASSERT(obd != NULL);
2362 rc = lprocfs_write_helper(buffer, count, &val);
2366 if (val < OBD_IR_FACTOR_MIN || val > OBD_IR_FACTOR_MAX)
2369 obd->obd_recovery_ir_factor = val;
2372 EXPORT_SYMBOL(lprocfs_obd_wr_ir_factor);
2374 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2375 int count, int *eof, void *data)
2377 struct obd_device *obd = (struct obd_device *)data;
2378 LASSERT(obd != NULL);
2380 return snprintf(page, count, "%d\n",
2381 obd->obd_recovery_timeout);
2383 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2385 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2386 unsigned long count, void *data)
2388 struct obd_device *obd = (struct obd_device *)data;
2390 LASSERT(obd != NULL);
2392 rc = lprocfs_write_helper(buffer, count, &val);
2396 obd->obd_recovery_timeout = val;
2399 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2401 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2402 int count, int *eof, void *data)
2404 struct obd_device *obd = data;
2405 LASSERT(obd != NULL);
2407 return snprintf(page, count, "%u\n", obd->obd_recovery_time_hard);
2409 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2411 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2412 unsigned long count, void *data)
2414 struct obd_device *obd = data;
2416 LASSERT(obd != NULL);
2418 rc = lprocfs_write_helper(buffer, count, &val);
2422 obd->obd_recovery_time_hard = val;
2425 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2427 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2428 int count, int *eof, void *data)
2430 struct obd_device *obd = (struct obd_device *)data;
2432 LASSERT(obd != NULL);
2433 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2435 return snprintf(page, count, "%s\n",
2436 obd->u.obt.obt_vfsmnt->mnt_devname);
2438 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2440 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2441 int count, int *eof, void *data)
2443 struct obd_device *dev = data;
2444 struct client_obd *cli = &dev->u.cli;
2447 client_obd_list_lock(&cli->cl_loi_list_lock);
2448 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2449 client_obd_list_unlock(&cli->cl_loi_list_lock);
2452 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2454 int lprocfs_obd_wr_max_pages_per_rpc(struct file *file, const char *buffer,
2455 unsigned long count, void *data)
2457 struct obd_device *dev = data;
2458 struct client_obd *cli = &dev->u.cli;
2459 struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
2462 rc = lprocfs_write_helper(buffer, count, &val);
2466 LPROCFS_CLIMP_CHECK(dev);
2467 if (val < 1 || val > ocd->ocd_brw_size >> CFS_PAGE_SHIFT) {
2468 LPROCFS_CLIMP_EXIT(dev);
2471 client_obd_list_lock(&cli->cl_loi_list_lock);
2472 cli->cl_max_pages_per_rpc = val;
2473 client_obd_list_unlock(&cli->cl_loi_list_lock);
2475 LPROCFS_CLIMP_EXIT(dev);
2478 EXPORT_SYMBOL(lprocfs_obd_wr_max_pages_per_rpc);
2480 int lprocfs_target_rd_instance(char *page, char **start, off_t off,
2481 int count, int *eof, void *data)
2483 struct obd_device *obd = (struct obd_device *)data;
2484 struct obd_device_target *target = &obd->u.obt;
2486 LASSERT(obd != NULL);
2487 LASSERT(target->obt_magic == OBT_MAGIC);
2489 return snprintf(page, count, "%u\n", obd->u.obt.obt_instance);
2491 EXPORT_SYMBOL(lprocfs_target_rd_instance);
2493 EXPORT_SYMBOL(lprocfs_register);
2494 EXPORT_SYMBOL(lprocfs_srch);
2495 EXPORT_SYMBOL(lprocfs_remove);
2496 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2497 EXPORT_SYMBOL(lprocfs_add_vars);
2498 EXPORT_SYMBOL(lprocfs_obd_setup);
2499 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2500 EXPORT_SYMBOL(lprocfs_add_simple);
2501 EXPORT_SYMBOL(lprocfs_add_symlink);
2502 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2503 EXPORT_SYMBOL(lprocfs_alloc_stats);
2504 EXPORT_SYMBOL(lprocfs_free_stats);
2505 EXPORT_SYMBOL(lprocfs_clear_stats);
2506 EXPORT_SYMBOL(lprocfs_register_stats);
2507 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2508 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2509 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2510 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2511 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2512 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2513 EXPORT_SYMBOL(lprocfs_free_md_stats);
2514 EXPORT_SYMBOL(lprocfs_exp_setup);
2515 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2517 EXPORT_SYMBOL(lprocfs_rd_u64);
2518 EXPORT_SYMBOL(lprocfs_rd_atomic);
2519 EXPORT_SYMBOL(lprocfs_wr_atomic);
2520 EXPORT_SYMBOL(lprocfs_rd_uint);
2521 EXPORT_SYMBOL(lprocfs_wr_uint);
2522 EXPORT_SYMBOL(lprocfs_rd_uuid);
2523 EXPORT_SYMBOL(lprocfs_rd_name);
2524 EXPORT_SYMBOL(lprocfs_rd_fstype);
2525 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2526 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2527 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2528 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2529 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2530 EXPORT_SYMBOL(lprocfs_rd_import);
2531 EXPORT_SYMBOL(lprocfs_rd_state);
2532 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2533 EXPORT_SYMBOL(lprocfs_rd_blksize);
2534 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2535 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2536 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2537 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2538 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2540 EXPORT_SYMBOL(lprocfs_write_helper);
2541 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2542 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2543 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2544 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2545 EXPORT_SYMBOL(lprocfs_stats_collect);