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, 2013, Intel Corporation.
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>
41 #define DEBUG_SUBSYSTEM S_CLASS
44 # include <liblustre.h>
47 #include <obd_class.h>
48 #include <lprocfs_status.h>
49 #include <lustre/lustre_idl.h>
53 static int lprocfs_no_percpu_stats = 0;
54 CFS_MODULE_PARM(lprocfs_no_percpu_stats, "i", int, 0644,
55 "Do not alloc percpu data for lprocfs stats");
57 #define MAX_STRING_SIZE 128
59 /* for bug 10866, global variable */
60 DECLARE_RWSEM(_lprocfs_lock);
61 EXPORT_SYMBOL(_lprocfs_lock);
63 int lprocfs_single_release(struct inode *inode, struct file *file)
66 return single_release(inode, file);
68 EXPORT_SYMBOL(lprocfs_single_release);
70 int lprocfs_seq_release(struct inode *inode, struct file *file)
73 return seq_release(inode, file);
75 EXPORT_SYMBOL(lprocfs_seq_release);
77 static struct proc_dir_entry *__lprocfs_srch(struct proc_dir_entry *head,
80 struct proc_dir_entry *temp;
86 while (temp != NULL) {
87 if (strcmp(temp->name, name) == 0) {
96 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
99 struct proc_dir_entry *temp;
101 LPROCFS_SRCH_ENTRY();
102 temp = __lprocfs_srch(head, name);
106 EXPORT_SYMBOL(lprocfs_srch);
108 /* lprocfs API calls */
110 /* Function that emulates snprintf but also has the side effect of advancing
111 the page pointer for the next write into the buffer, incrementing the total
112 length written to the buffer, and decrementing the size left in the
114 static int lprocfs_obd_snprintf(char **page, int end, int *len,
115 const char *format, ...)
123 va_start(list, format);
124 n = vsnprintf(*page, end - *len, format, list);
127 *page += n; *len += n;
131 cfs_proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
133 read_proc_t *read_proc,
134 write_proc_t *write_proc,
136 struct file_operations *fops)
138 cfs_proc_dir_entry_t *proc;
141 if (root == NULL || name == NULL)
142 return ERR_PTR(-EINVAL);
149 LPROCFS_WRITE_ENTRY();
150 proc = create_proc_entry(name, mode, root);
152 CERROR("LprocFS: No memory to create /proc entry %s", name);
153 LPROCFS_WRITE_EXIT();
154 return ERR_PTR(-ENOMEM);
156 proc->read_proc = read_proc;
157 proc->write_proc = write_proc;
160 proc->proc_fops = fops;
161 LPROCFS_WRITE_EXIT();
164 EXPORT_SYMBOL(lprocfs_add_simple);
166 struct proc_dir_entry *lprocfs_add_symlink(const char *name,
167 struct proc_dir_entry *parent, const char *format, ...)
169 struct proc_dir_entry *entry;
173 if (parent == NULL || format == NULL)
176 OBD_ALLOC_WAIT(dest, MAX_STRING_SIZE + 1);
180 va_start(ap, format);
181 vsnprintf(dest, MAX_STRING_SIZE, format, ap);
184 entry = proc_symlink(name, parent, dest);
186 CERROR("LprocFS: Could not create symbolic link from %s to %s",
189 OBD_FREE(dest, MAX_STRING_SIZE + 1);
192 EXPORT_SYMBOL(lprocfs_add_symlink);
194 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
195 size_t size, loff_t *ppos)
197 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
198 char *page, *start = NULL;
199 int rc = 0, eof = 1, count;
201 if (*ppos >= PAGE_CACHE_SIZE)
204 page = (char *)__get_free_page(GFP_KERNEL);
208 if (LPROCFS_ENTRY_AND_CHECK(dp)) {
213 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
215 rc = dp->read_proc(page, &start, *ppos, PAGE_CACHE_SIZE,
221 /* for lustre proc read, the read count must be less than PAGE_SIZE */
230 start = page + *ppos;
231 } else if (start < page) {
235 count = (rc < size) ? rc : size;
236 if (copy_to_user(buf, start, count)) {
243 free_page((unsigned long)page);
247 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
248 size_t size, loff_t *ppos)
250 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
253 if (LPROCFS_ENTRY_AND_CHECK(dp))
256 rc = dp->write_proc(f, buf, size, dp->data);
261 static struct file_operations lprocfs_generic_fops = {
262 .owner = THIS_MODULE,
263 .read = lprocfs_fops_read,
264 .write = lprocfs_fops_write,
267 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
269 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
270 struct obd_device *obd = dp->data;
272 cfs_atomic_inc(&obd->obd_evict_inprogress);
277 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
279 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
280 struct obd_device *obd = dp->data;
282 cfs_atomic_dec(&obd->obd_evict_inprogress);
283 cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
288 struct file_operations lprocfs_evict_client_fops = {
289 .owner = THIS_MODULE,
290 .read = lprocfs_fops_read,
291 .write = lprocfs_fops_write,
292 .open = lprocfs_evict_client_open,
293 .release = lprocfs_evict_client_release,
295 EXPORT_SYMBOL(lprocfs_evict_client_fops);
300 * \param root [in] The parent proc entry on which new entry will be added.
301 * \param list [in] Array of proc entries to be added.
302 * \param data [in] The argument to be passed when entries read/write routines
303 * are called through /proc file.
305 * \retval 0 on success
308 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
313 if (root == NULL || list == NULL)
316 LPROCFS_WRITE_ENTRY();
317 while (list->name != NULL) {
318 struct proc_dir_entry *cur_root, *proc;
319 char *pathcopy, *cur, *next, pathbuf[64];
320 int pathsize = strlen(list->name) + 1;
325 /* need copy of path for strsep */
326 if (strlen(list->name) > sizeof(pathbuf) - 1) {
327 OBD_ALLOC(pathcopy, pathsize);
328 if (pathcopy == NULL)
329 GOTO(out, rc = -ENOMEM);
335 strcpy(pathcopy, list->name);
337 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
338 if (*cur =='\0') /* skip double/trailing "/" */
341 proc = __lprocfs_srch(cur_root, cur);
342 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
343 cur_root->name, cur, next,
344 (proc ? "exists" : "new"));
346 cur_root = (proc ? proc :
347 proc_mkdir(cur, cur_root));
348 } else if (proc == NULL) {
350 if (list->proc_mode != 0000) {
351 mode = list->proc_mode;
355 if (list->write_fptr)
358 proc = create_proc_entry(cur, mode, cur_root);
362 if (pathcopy != pathbuf)
363 OBD_FREE(pathcopy, pathsize);
365 if (cur_root == NULL || proc == NULL) {
366 CERROR("LprocFS: No memory to create /proc entry %s",
368 GOTO(out, rc = -ENOMEM);
372 proc->proc_fops = list->fops;
374 proc->proc_fops = &lprocfs_generic_fops;
375 proc->read_proc = list->read_fptr;
376 proc->write_proc = list->write_fptr;
377 proc->data = (list->data ? list->data : data);
381 LPROCFS_WRITE_EXIT();
384 EXPORT_SYMBOL(lprocfs_add_vars);
386 void lprocfs_remove_nolock(struct proc_dir_entry **rooth)
388 struct proc_dir_entry *root = *rooth;
389 struct proc_dir_entry *temp = root;
390 struct proc_dir_entry *rm_entry;
391 struct proc_dir_entry *parent;
397 parent = root->parent;
398 LASSERT(parent != NULL);
401 while (temp->subdir != NULL)
407 /* Memory corruption once caused this to fail, and
408 without this LASSERT we would loop here forever. */
409 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
410 "0x%p %s/%s len %d\n", rm_entry, temp->name,
411 rm_entry->name, (int)strlen(rm_entry->name));
413 remove_proc_entry(rm_entry->name, temp);
419 void lprocfs_remove(struct proc_dir_entry **rooth)
421 LPROCFS_WRITE_ENTRY(); /* search vs remove race */
422 lprocfs_remove_nolock(rooth);
423 LPROCFS_WRITE_EXIT();
425 EXPORT_SYMBOL(lprocfs_remove);
427 void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
429 LASSERT(parent != NULL);
430 remove_proc_entry(name, parent);
432 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
434 void lprocfs_try_remove_proc_entry(const char *name,
435 struct proc_dir_entry *parent)
437 struct proc_dir_entry *t = NULL;
438 struct proc_dir_entry **p;
441 LASSERT(parent != NULL);
444 LPROCFS_WRITE_ENTRY();
446 /* lookup target name */
447 for (p = &parent->subdir; *p; p = &(*p)->next) {
448 if ((*p)->namelen != len)
450 if (memcmp(name, (*p)->name, len))
457 /* verify it's empty: do not count "num_refs" */
458 for (p = &t->subdir; *p; p = &(*p)->next) {
459 if ((*p)->namelen != strlen("num_refs")) {
463 if (memcmp("num_refs", (*p)->name,
464 strlen("num_refs"))) {
472 lprocfs_remove_nolock(&t);
474 LPROCFS_WRITE_EXIT();
478 EXPORT_SYMBOL(lprocfs_try_remove_proc_entry);
480 struct proc_dir_entry *lprocfs_register(const char *name,
481 struct proc_dir_entry *parent,
482 struct lprocfs_vars *list, void *data)
484 struct proc_dir_entry *newchild;
486 newchild = lprocfs_srch(parent, name);
487 if (newchild != NULL) {
488 CERROR(" Lproc: Attempting to register %s more than once \n",
490 return ERR_PTR(-EALREADY);
493 newchild = proc_mkdir(name, parent);
494 if (newchild != NULL && list != NULL) {
495 int rc = lprocfs_add_vars(newchild, list, data);
497 lprocfs_remove(&newchild);
503 EXPORT_SYMBOL(lprocfs_register);
505 /* Generic callbacks */
506 int lprocfs_rd_uint(char *page, char **start, off_t off,
507 int count, int *eof, void *data)
509 unsigned int *temp = data;
510 return snprintf(page, count, "%u\n", *temp);
512 EXPORT_SYMBOL(lprocfs_rd_uint);
514 int lprocfs_wr_uint(struct file *file, const char *buffer,
515 unsigned long count, void *data)
518 char dummy[MAX_STRING_SIZE + 1], *end;
521 dummy[MAX_STRING_SIZE] = '\0';
522 if (copy_from_user(dummy, buffer, MAX_STRING_SIZE))
525 tmp = simple_strtoul(dummy, &end, 0);
529 *p = (unsigned int)tmp;
532 EXPORT_SYMBOL(lprocfs_wr_uint);
534 int lprocfs_rd_u64(char *page, char **start, off_t off,
535 int count, int *eof, void *data)
537 LASSERT(data != NULL);
539 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
541 EXPORT_SYMBOL(lprocfs_rd_u64);
543 int lprocfs_rd_atomic(char *page, char **start, off_t off,
544 int count, int *eof, void *data)
546 cfs_atomic_t *atom = data;
547 LASSERT(atom != NULL);
549 return snprintf(page, count, "%d\n", cfs_atomic_read(atom));
551 EXPORT_SYMBOL(lprocfs_rd_atomic);
553 int lprocfs_wr_atomic(struct file *file, const char *buffer,
554 unsigned long count, void *data)
556 cfs_atomic_t *atm = data;
560 rc = lprocfs_write_helper(buffer, count, &val);
567 cfs_atomic_set(atm, val);
570 EXPORT_SYMBOL(lprocfs_wr_atomic);
572 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
573 int *eof, void *data)
575 struct obd_device *obd = data;
577 LASSERT(obd != NULL);
579 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
581 EXPORT_SYMBOL(lprocfs_rd_uuid);
583 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
584 int *eof, void *data)
586 struct obd_device *dev = data;
588 LASSERT(dev != NULL);
590 return snprintf(page, count, "%s\n", dev->obd_name);
592 EXPORT_SYMBOL(lprocfs_rd_name);
594 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
595 int *eof, void *data)
597 struct obd_device *obd = data;
598 struct obd_statfs osfs;
599 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
600 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
604 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
608 EXPORT_SYMBOL(lprocfs_rd_blksize);
610 int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
611 int *eof, void *data)
613 struct obd_device *obd = data;
614 struct obd_statfs osfs;
615 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
616 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
619 __u32 blk_size = osfs.os_bsize >> 10;
620 __u64 result = osfs.os_blocks;
622 while (blk_size >>= 1)
626 rc = snprintf(page, count, LPU64"\n", result);
630 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
632 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
633 int *eof, void *data)
635 struct obd_device *obd = data;
636 struct obd_statfs osfs;
637 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
638 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
641 __u32 blk_size = osfs.os_bsize >> 10;
642 __u64 result = osfs.os_bfree;
644 while (blk_size >>= 1)
648 rc = snprintf(page, count, LPU64"\n", result);
652 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
654 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
655 int *eof, void *data)
657 struct obd_device *obd = data;
658 struct obd_statfs osfs;
659 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
660 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
663 __u32 blk_size = osfs.os_bsize >> 10;
664 __u64 result = osfs.os_bavail;
666 while (blk_size >>= 1)
670 rc = snprintf(page, count, LPU64"\n", result);
674 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
676 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
677 int *eof, void *data)
679 struct obd_device *obd = data;
680 struct obd_statfs osfs;
681 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
682 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
686 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
691 EXPORT_SYMBOL(lprocfs_rd_filestotal);
693 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
694 int *eof, void *data)
696 struct obd_device *obd = data;
697 struct obd_statfs osfs;
698 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
699 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
703 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
707 EXPORT_SYMBOL(lprocfs_rd_filesfree);
709 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
710 int *eof, void *data)
712 struct obd_device *obd = data;
713 struct obd_import *imp;
714 char *imp_state_name = NULL;
717 LASSERT(obd != NULL);
718 LPROCFS_CLIMP_CHECK(obd);
719 imp = obd->u.cli.cl_import;
720 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
722 rc = snprintf(page, count, "%s\t%s%s\n",
723 obd2cli_tgt(obd), imp_state_name,
724 imp->imp_deactive ? "\tDEACTIVATED" : "");
726 LPROCFS_CLIMP_EXIT(obd);
729 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
731 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
732 int *eof, void *data)
734 struct obd_device *obd = data;
735 struct ptlrpc_connection *conn;
738 LASSERT(obd != NULL);
740 LPROCFS_CLIMP_CHECK(obd);
741 conn = obd->u.cli.cl_import->imp_connection;
743 if (conn && obd->u.cli.cl_import) {
744 rc = snprintf(page, count, "%s\n",
745 conn->c_remote_uuid.uuid);
747 rc = snprintf(page, count, "%s\n", "<none>");
750 LPROCFS_CLIMP_EXIT(obd);
753 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
755 /** add up per-cpu counters */
756 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
757 struct lprocfs_counter *cnt)
759 unsigned int num_entry;
760 struct lprocfs_counter *percpu_cntr;
761 struct lprocfs_counter_header *cntr_header;
763 unsigned long flags = 0;
765 memset(cnt, 0, sizeof(*cnt));
768 /* set count to 1 to avoid divide-by-zero errs in callers */
773 cnt->lc_min = LC_MIN_INIT;
775 num_entry = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
777 for (i = 0; i < num_entry; i++) {
778 if (stats->ls_percpu[i] == NULL)
780 cntr_header = &stats->ls_cnt_header[idx];
781 percpu_cntr = lprocfs_stats_counter_get(stats, i, idx);
783 cnt->lc_count += percpu_cntr->lc_count;
784 cnt->lc_sum += percpu_cntr->lc_sum;
785 if (percpu_cntr->lc_min < cnt->lc_min)
786 cnt->lc_min = percpu_cntr->lc_min;
787 if (percpu_cntr->lc_max > cnt->lc_max)
788 cnt->lc_max = percpu_cntr->lc_max;
789 cnt->lc_sumsquare += percpu_cntr->lc_sumsquare;
792 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
794 EXPORT_SYMBOL(lprocfs_stats_collect);
797 * Append a space separated list of current set flags to str.
799 #define flag2str(flag) \
800 if (imp->imp_##flag && max - len > 0) \
801 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
802 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
806 if (imp->imp_obd->obd_no_recov)
807 len += snprintf(str, max - len, "no_recov");
811 flag2str(replayable);
817 static const char *obd_connect_names[] = {
831 "join_file(obsolete)",
835 "remote_client_by_force",
844 "mds_mds_connection",
847 "alt_checksum_algorithm",
873 int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
878 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
880 ret += snprintf(page + ret, count - ret, "%s%s",
881 ret ? sep : "", obd_connect_names[i]);
883 if (flags & ~(mask - 1))
884 ret += snprintf(page + ret, count - ret,
885 "%sunknown flags "LPX64,
886 ret ? sep : "", flags & ~(mask - 1));
889 EXPORT_SYMBOL(obd_connect_flags2str);
891 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
892 int *eof, void *data)
894 struct lprocfs_counter ret;
895 struct lprocfs_counter_header *header;
896 struct obd_device *obd = (struct obd_device *)data;
897 struct obd_import *imp;
898 struct obd_import_conn *conn;
904 LASSERT(obd != NULL);
905 LPROCFS_CLIMP_CHECK(obd);
906 imp = obd->u.cli.cl_import;
909 i = snprintf(page, count,
918 ptlrpc_import_state_name(imp->imp_state),
919 imp->imp_connect_data.ocd_instance);
920 i += obd_connect_flags2str(page + i, count - i,
921 imp->imp_connect_data.ocd_connect_flags,
923 i += snprintf(page + i, count - i,
926 i += obd_import_flags2str(imp, page + i, count - i);
928 i += snprintf(page + i, count - i,
931 " failover_nids: [");
932 spin_lock(&imp->imp_lock);
934 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
935 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
936 libcfs_nid2str(conn->oic_conn->c_peer.nid));
939 i += snprintf(page + i, count - i,
941 " current_connection: %s\n"
942 " connection_attempts: %u\n"
944 " in-progress_invalidations: %u\n",
945 imp->imp_connection == NULL ? "<none>" :
946 libcfs_nid2str(imp->imp_connection->c_peer.nid),
949 cfs_atomic_read(&imp->imp_inval_count));
950 spin_unlock(&imp->imp_lock);
952 if (obd->obd_svc_stats == NULL)
955 header = &obd->obd_svc_stats->ls_cnt_header[PTLRPC_REQWAIT_CNTR];
956 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
957 if (ret.lc_count != 0) {
958 /* first argument to do_div MUST be __u64 */
959 __u64 sum = ret.lc_sum;
960 do_div(sum, ret.lc_count);
964 i += snprintf(page + i, count - i,
967 " unregistering: %u\n"
969 " avg_waittime: "LPU64" %s\n",
970 cfs_atomic_read(&imp->imp_inflight),
971 cfs_atomic_read(&imp->imp_unregistering),
972 cfs_atomic_read(&imp->imp_timeouts),
973 ret.lc_sum, header->lc_units);
976 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
977 if (imp->imp_at.iat_portal[j] == 0)
979 k = max_t(unsigned int, k,
980 at_get(&imp->imp_at.iat_service_estimate[j]));
982 i += snprintf(page + i, count - i,
983 " service_estimates:\n"
984 " services: %u sec\n"
985 " network: %u sec\n",
987 at_get(&imp->imp_at.iat_net_latency));
989 i += snprintf(page + i, count - i,
991 " last_replay: "LPU64"\n"
992 " peer_committed: "LPU64"\n"
993 " last_checked: "LPU64"\n",
994 imp->imp_last_replay_transno,
995 imp->imp_peer_committed_transno,
996 imp->imp_last_transno_checked);
999 for (rw = 0; rw <= 1; rw++) {
1000 lprocfs_stats_collect(obd->obd_svc_stats,
1001 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
1003 if (ret.lc_sum > 0 && ret.lc_count > 0) {
1004 /* first argument to do_div MUST be __u64 */
1005 __u64 sum = ret.lc_sum;
1006 do_div(sum, ret.lc_count);
1008 i += snprintf(page + i, count - i,
1009 " %s_data_averages:\n"
1010 " bytes_per_rpc: "LPU64"\n",
1011 rw ? "write" : "read",
1014 k = (int)ret.lc_sum;
1015 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
1016 header = &obd->obd_svc_stats->ls_cnt_header[j];
1017 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
1018 if (ret.lc_sum > 0 && ret.lc_count != 0) {
1019 /* first argument to do_div MUST be __u64 */
1020 __u64 sum = ret.lc_sum;
1021 do_div(sum, ret.lc_count);
1023 i += snprintf(page + i, count - i,
1024 " %s_per_rpc: "LPU64"\n",
1025 header->lc_units, ret.lc_sum);
1026 j = (int)ret.lc_sum;
1028 i += snprintf(page + i, count - i,
1029 " MB_per_sec: %u.%.02u\n",
1030 k / j, (100 * k / j) % 100);
1035 LPROCFS_CLIMP_EXIT(obd);
1038 EXPORT_SYMBOL(lprocfs_rd_import);
1040 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
1041 int *eof, void *data)
1043 struct obd_device *obd = (struct obd_device *)data;
1044 struct obd_import *imp;
1047 LASSERT(obd != NULL);
1048 LPROCFS_CLIMP_CHECK(obd);
1049 imp = obd->u.cli.cl_import;
1052 i = snprintf(page, count, "current_state: %s\n",
1053 ptlrpc_import_state_name(imp->imp_state));
1054 i += snprintf(page + i, count - i,
1055 "state_history:\n");
1056 k = imp->imp_state_hist_idx;
1057 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
1058 struct import_state_hist *ish =
1059 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
1060 if (ish->ish_state == 0)
1062 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
1064 ptlrpc_import_state_name(ish->ish_state));
1067 LPROCFS_CLIMP_EXIT(obd);
1070 EXPORT_SYMBOL(lprocfs_rd_state);
1072 int lprocfs_at_hist_helper(char *page, int count, int rc,
1073 struct adaptive_timeout *at)
1076 for (i = 0; i < AT_BINS; i++)
1077 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1078 rc += snprintf(page + rc, count - rc, "\n");
1081 EXPORT_SYMBOL(lprocfs_at_hist_helper);
1083 /* See also ptlrpc_lprocfs_rd_timeouts */
1084 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1085 int *eof, void *data)
1087 struct obd_device *obd = (struct obd_device *)data;
1088 struct obd_import *imp;
1089 unsigned int cur, worst;
1094 LASSERT(obd != NULL);
1095 LPROCFS_CLIMP_CHECK(obd);
1096 imp = obd->u.cli.cl_import;
1099 now = cfs_time_current_sec();
1101 /* Some network health info for kicks */
1102 s2dhms(&ts, now - imp->imp_last_reply_time);
1103 rc += snprintf(page + rc, count - rc,
1104 "%-10s : %ld, "DHMS_FMT" ago\n",
1105 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1107 cur = at_get(&imp->imp_at.iat_net_latency);
1108 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1109 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1110 s2dhms(&ts, now - worstt);
1111 rc += snprintf(page + rc, count - rc,
1112 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1113 "network", cur, worst, worstt, DHMS_VARS(&ts));
1114 rc = lprocfs_at_hist_helper(page, count, rc,
1115 &imp->imp_at.iat_net_latency);
1117 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1118 if (imp->imp_at.iat_portal[i] == 0)
1120 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1121 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1122 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1123 s2dhms(&ts, now - worstt);
1124 rc += snprintf(page + rc, count - rc,
1125 "portal %-2d : cur %3u worst %3u (at %ld, "
1126 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1127 cur, worst, worstt, DHMS_VARS(&ts));
1128 rc = lprocfs_at_hist_helper(page, count, rc,
1129 &imp->imp_at.iat_service_estimate[i]);
1132 LPROCFS_CLIMP_EXIT(obd);
1135 EXPORT_SYMBOL(lprocfs_rd_timeouts);
1137 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1138 int count, int *eof, void *data)
1140 struct obd_device *obd = data;
1144 LPROCFS_CLIMP_CHECK(obd);
1145 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1146 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1147 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1148 ret += snprintf(page + ret, count - ret, "\n");
1149 LPROCFS_CLIMP_EXIT(obd);
1152 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1154 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1155 int *eof, void *data)
1157 struct obd_device *obd = data;
1159 LASSERT(obd != NULL);
1161 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1163 EXPORT_SYMBOL(lprocfs_rd_num_exports);
1165 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1166 int *eof, void *data)
1168 struct obd_type *class = (struct obd_type*) data;
1170 LASSERT(class != NULL);
1172 return snprintf(page, count, "%d\n", class->typ_refcnt);
1174 EXPORT_SYMBOL(lprocfs_rd_numrefs);
1176 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1180 LASSERT(obd != NULL);
1181 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1182 LASSERT(obd->obd_type->typ_procroot != NULL);
1184 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1185 obd->obd_type->typ_procroot,
1187 if (IS_ERR(obd->obd_proc_entry)) {
1188 rc = PTR_ERR(obd->obd_proc_entry);
1189 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1190 obd->obd_proc_entry = NULL;
1194 EXPORT_SYMBOL(lprocfs_obd_setup);
1196 int lprocfs_obd_cleanup(struct obd_device *obd)
1200 if (obd->obd_proc_exports_entry) {
1201 /* Should be no exports left */
1202 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1203 lprocfs_remove(&obd->obd_proc_exports_entry);
1204 obd->obd_proc_exports_entry = NULL;
1206 if (obd->obd_proc_entry) {
1207 lprocfs_remove(&obd->obd_proc_entry);
1208 obd->obd_proc_entry = NULL;
1212 EXPORT_SYMBOL(lprocfs_obd_cleanup);
1214 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1216 CDEBUG(D_CONFIG, "stat %p - data %p/%p\n", client_stat,
1217 client_stat->nid_proc, client_stat->nid_stats);
1219 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1220 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1221 atomic_read(&client_stat->nid_exp_ref_count));
1223 if (client_stat->nid_proc)
1224 lprocfs_remove(&client_stat->nid_proc);
1226 if (client_stat->nid_stats)
1227 lprocfs_free_stats(&client_stat->nid_stats);
1229 if (client_stat->nid_ldlm_stats)
1230 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1232 OBD_FREE_PTR(client_stat);
1237 void lprocfs_free_per_client_stats(struct obd_device *obd)
1239 cfs_hash_t *hash = obd->obd_nid_stats_hash;
1240 struct nid_stat *stat;
1243 /* we need extra list - because hash_exit called to early */
1244 /* not need locking because all clients is died */
1245 while (!cfs_list_empty(&obd->obd_nid_stats)) {
1246 stat = cfs_list_entry(obd->obd_nid_stats.next,
1247 struct nid_stat, nid_list);
1248 cfs_list_del_init(&stat->nid_list);
1249 cfs_hash_del(hash, &stat->nid, &stat->nid_hash);
1250 lprocfs_free_client_stats(stat);
1254 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
1256 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1257 enum lprocfs_stats_flags flags)
1259 struct lprocfs_stats *stats;
1260 unsigned int num_entry;
1261 unsigned int percpusize = 0;
1267 if (lprocfs_no_percpu_stats != 0)
1268 flags |= LPROCFS_STATS_FLAG_NOPERCPU;
1270 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1273 num_entry = cfs_num_possible_cpus();
1275 /* alloc percpu pointers for all possible cpu slots */
1276 LIBCFS_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_entry]));
1280 stats->ls_num = num;
1281 stats->ls_flags = flags;
1282 spin_lock_init(&stats->ls_lock);
1284 /* alloc num of counter headers */
1285 LIBCFS_ALLOC(stats->ls_cnt_header,
1286 stats->ls_num * sizeof(struct lprocfs_counter_header));
1287 if (stats->ls_cnt_header == NULL)
1290 if ((flags & LPROCFS_STATS_FLAG_NOPERCPU) != 0) {
1291 /* contains only one set counters */
1292 percpusize = lprocfs_stats_counter_size(stats);
1293 LIBCFS_ALLOC_ATOMIC(stats->ls_percpu[0], percpusize);
1294 if (stats->ls_percpu[0] == NULL)
1296 stats->ls_biggest_alloc_num = 1;
1297 } else if ((flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0) {
1298 /* alloc all percpu data, currently only obd_memory use this */
1299 for (i = 0; i < num_entry; ++i)
1300 if (lprocfs_stats_alloc_one(stats, i) < 0)
1307 lprocfs_free_stats(&stats);
1310 EXPORT_SYMBOL(lprocfs_alloc_stats);
1312 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1314 struct lprocfs_stats *stats = *statsh;
1315 unsigned int num_entry;
1316 unsigned int percpusize;
1319 if (stats == NULL || stats->ls_num == 0)
1323 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1326 num_entry = cfs_num_possible_cpus();
1328 percpusize = lprocfs_stats_counter_size(stats);
1329 for (i = 0; i < num_entry; i++)
1330 if (stats->ls_percpu[i] != NULL)
1331 LIBCFS_FREE(stats->ls_percpu[i], percpusize);
1332 if (stats->ls_cnt_header != NULL)
1333 LIBCFS_FREE(stats->ls_cnt_header, stats->ls_num *
1334 sizeof(struct lprocfs_counter_header));
1335 LIBCFS_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_entry]));
1337 EXPORT_SYMBOL(lprocfs_free_stats);
1339 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1341 struct lprocfs_counter *percpu_cntr;
1342 struct lprocfs_counter_header *header;
1345 unsigned int num_entry;
1346 unsigned long flags = 0;
1348 num_entry = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
1350 for (i = 0; i < num_entry; i++) {
1351 if (stats->ls_percpu[i] == NULL)
1353 for (j = 0; j < stats->ls_num; j++) {
1354 header = &stats->ls_cnt_header[j];
1355 percpu_cntr = lprocfs_stats_counter_get(stats, i, j);
1356 percpu_cntr->lc_count = 0;
1357 percpu_cntr->lc_min = LC_MIN_INIT;
1358 percpu_cntr->lc_max = 0;
1359 percpu_cntr->lc_sumsquare = 0;
1360 percpu_cntr->lc_sum = 0;
1361 if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
1362 percpu_cntr->lc_sum_irq = 0;
1366 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
1368 EXPORT_SYMBOL(lprocfs_clear_stats);
1370 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1371 size_t len, loff_t *off)
1373 struct seq_file *seq = file->private_data;
1374 struct lprocfs_stats *stats = seq->private;
1376 lprocfs_clear_stats(stats);
1381 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1383 struct lprocfs_stats *stats = p->private;
1385 return (*pos < stats->ls_num) ? pos : NULL;
1388 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1392 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1396 return lprocfs_stats_seq_start(p, pos);
1399 /* seq file export of one lprocfs counter */
1400 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1402 struct lprocfs_stats *stats = p->private;
1403 struct lprocfs_counter_header *hdr;
1404 struct lprocfs_counter ctr;
1405 int idx = *(loff_t *)v;
1411 cfs_gettimeofday(&now);
1412 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1413 "snapshot_time", now.tv_sec, now.tv_usec);
1418 hdr = &stats->ls_cnt_header[idx];
1419 lprocfs_stats_collect(stats, idx, &ctr);
1421 if (ctr.lc_count == 0)
1424 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", hdr->lc_name,
1425 ctr.lc_count, hdr->lc_units);
1429 if ((hdr->lc_config & LPROCFS_CNTR_AVGMINMAX) && ctr.lc_count > 0) {
1430 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1431 ctr.lc_min, ctr.lc_max, ctr.lc_sum);
1434 if (hdr->lc_config & LPROCFS_CNTR_STDDEV)
1435 rc = seq_printf(p, " "LPD64, ctr.lc_sumsquare);
1439 rc = seq_printf(p, "\n");
1441 return (rc < 0) ? rc : 0;
1444 struct seq_operations lprocfs_stats_seq_sops = {
1445 .start = lprocfs_stats_seq_start,
1446 .stop = lprocfs_stats_seq_stop,
1447 .next = lprocfs_stats_seq_next,
1448 .show = lprocfs_stats_seq_show,
1451 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1453 struct proc_dir_entry *dp = PDE(inode);
1454 struct seq_file *seq;
1457 if (LPROCFS_ENTRY_AND_CHECK(dp))
1460 rc = seq_open(file, &lprocfs_stats_seq_sops);
1465 seq = file->private_data;
1466 seq->private = dp->data;
1470 struct file_operations lprocfs_stats_seq_fops = {
1471 .owner = THIS_MODULE,
1472 .open = lprocfs_stats_seq_open,
1474 .write = lprocfs_stats_seq_write,
1475 .llseek = seq_lseek,
1476 .release = lprocfs_seq_release,
1479 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1480 struct lprocfs_stats *stats)
1482 struct proc_dir_entry *entry;
1483 LASSERT(root != NULL);
1485 LPROCFS_WRITE_ENTRY();
1486 entry = create_proc_entry(name, 0644, root);
1488 entry->proc_fops = &lprocfs_stats_seq_fops;
1489 entry->data = stats;
1492 LPROCFS_WRITE_EXIT();
1499 EXPORT_SYMBOL(lprocfs_register_stats);
1501 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1502 unsigned conf, const char *name, const char *units)
1504 struct lprocfs_counter_header *header;
1505 struct lprocfs_counter *percpu_cntr;
1506 unsigned long flags = 0;
1508 unsigned int num_cpu;
1510 LASSERT(stats != NULL);
1512 header = &stats->ls_cnt_header[index];
1513 LASSERTF(header != NULL, "Failed to allocate stats header:[%d]%s/%s\n",
1514 index, name, units);
1516 header->lc_config = conf;
1517 header->lc_name = name;
1518 header->lc_units = units;
1520 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
1521 for (i = 0; i < num_cpu; ++i) {
1522 if (stats->ls_percpu[i] == NULL)
1524 percpu_cntr = lprocfs_stats_counter_get(stats, i, index);
1525 percpu_cntr->lc_count = 0;
1526 percpu_cntr->lc_min = LC_MIN_INIT;
1527 percpu_cntr->lc_max = 0;
1528 percpu_cntr->lc_sumsquare = 0;
1529 percpu_cntr->lc_sum = 0;
1530 if ((stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0)
1531 percpu_cntr->lc_sum_irq = 0;
1533 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
1535 EXPORT_SYMBOL(lprocfs_counter_init);
1537 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1539 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1540 LASSERT(coffset < stats->ls_num); \
1541 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1544 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1546 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1547 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1548 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1549 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1550 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1551 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1552 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1553 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1554 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1555 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1556 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1557 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1558 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1559 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1560 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1561 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1562 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1563 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1564 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1565 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1566 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1567 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1568 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1569 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1570 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1571 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1572 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1573 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1574 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1575 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1576 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1577 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1578 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1579 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1580 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1581 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1582 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1583 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1584 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1585 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1586 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1587 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1588 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1589 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1590 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1591 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1592 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1593 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1594 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1595 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1596 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1597 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1598 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1599 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1600 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1601 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1602 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1603 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1604 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1605 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1606 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1607 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1608 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1609 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1610 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1611 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1612 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1614 EXPORT_SYMBOL(lprocfs_init_ops_stats);
1616 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1618 struct lprocfs_stats *stats;
1619 unsigned int num_stats;
1622 LASSERT(obd->obd_stats == NULL);
1623 LASSERT(obd->obd_proc_entry != NULL);
1624 LASSERT(obd->obd_cntr_base == 0);
1626 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1627 num_private_stats - 1 /* o_owner */;
1628 stats = lprocfs_alloc_stats(num_stats, 0);
1632 lprocfs_init_ops_stats(num_private_stats, stats);
1634 for (i = num_private_stats; i < num_stats; i++) {
1635 /* If this LBUGs, it is likely that an obd
1636 * operation was added to struct obd_ops in
1637 * <obd.h>, and that the corresponding line item
1638 * LPROCFS_OBD_OP_INIT(.., .., opname)
1639 * is missing from the list above. */
1640 LASSERTF(stats->ls_cnt_header[i].lc_name != NULL,
1641 "Missing obd_stat initializer obd_op "
1642 "operation at offset %d.\n", i - num_private_stats);
1644 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1646 lprocfs_free_stats(&stats);
1648 obd->obd_stats = stats;
1649 obd->obd_cntr_base = num_private_stats;
1653 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
1655 void lprocfs_free_obd_stats(struct obd_device *obd)
1658 lprocfs_free_stats(&obd->obd_stats);
1660 EXPORT_SYMBOL(lprocfs_free_obd_stats);
1662 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1664 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1665 LASSERT(coffset < stats->ls_num); \
1666 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1669 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1671 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1672 LPROCFS_MD_OP_INIT(num_private_stats, stats, null_inode);
1673 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1674 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1675 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1676 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1677 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1678 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1679 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1680 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1681 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1682 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1683 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1684 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1685 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1686 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1687 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1688 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1689 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1690 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1691 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1692 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1693 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1694 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1695 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1696 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1697 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1698 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1699 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1700 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1701 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1702 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1704 EXPORT_SYMBOL(lprocfs_init_mps_stats);
1706 int lprocfs_alloc_md_stats(struct obd_device *obd,
1707 unsigned num_private_stats)
1709 struct lprocfs_stats *stats;
1710 unsigned int num_stats;
1713 LASSERT(obd->md_stats == NULL);
1714 LASSERT(obd->obd_proc_entry != NULL);
1715 LASSERT(obd->md_cntr_base == 0);
1717 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1719 stats = lprocfs_alloc_stats(num_stats, 0);
1723 lprocfs_init_mps_stats(num_private_stats, stats);
1725 for (i = num_private_stats; i < num_stats; i++) {
1726 if (stats->ls_cnt_header[i].lc_name == NULL) {
1727 CERROR("Missing md_stat initializer md_op "
1728 "operation at offset %d. Aborting.\n",
1729 i - num_private_stats);
1733 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1735 lprocfs_free_stats(&stats);
1737 obd->md_stats = stats;
1738 obd->md_cntr_base = num_private_stats;
1742 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
1744 void lprocfs_free_md_stats(struct obd_device *obd)
1746 struct lprocfs_stats *stats = obd->md_stats;
1748 if (stats != NULL) {
1749 obd->md_stats = NULL;
1750 obd->md_cntr_base = 0;
1751 lprocfs_free_stats(&stats);
1754 EXPORT_SYMBOL(lprocfs_free_md_stats);
1756 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1758 lprocfs_counter_init(ldlm_stats,
1759 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1760 0, "ldlm_enqueue", "reqs");
1761 lprocfs_counter_init(ldlm_stats,
1762 LDLM_CONVERT - LDLM_FIRST_OPC,
1763 0, "ldlm_convert", "reqs");
1764 lprocfs_counter_init(ldlm_stats,
1765 LDLM_CANCEL - LDLM_FIRST_OPC,
1766 0, "ldlm_cancel", "reqs");
1767 lprocfs_counter_init(ldlm_stats,
1768 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1769 0, "ldlm_bl_callback", "reqs");
1770 lprocfs_counter_init(ldlm_stats,
1771 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1772 0, "ldlm_cp_callback", "reqs");
1773 lprocfs_counter_init(ldlm_stats,
1774 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1775 0, "ldlm_gl_callback", "reqs");
1777 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
1779 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1780 int *eof, void *data)
1782 struct obd_export *exp = data;
1783 LASSERT(exp != NULL);
1785 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1788 struct exp_uuid_cb_data {
1796 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1797 int count, int *eof, int *len)
1799 cb_data->page = page;
1800 cb_data->count = count;
1805 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1806 cfs_hlist_node_t *hnode, void *cb_data)
1809 struct obd_export *exp = cfs_hash_object(hs, hnode);
1810 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1812 if (exp->exp_nid_stats)
1813 *data->len += snprintf((data->page + *data->len),
1814 data->count, "%s\n",
1815 obd_uuid2str(&exp->exp_client_uuid));
1819 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1820 int *eof, void *data)
1822 struct nid_stat *stats = (struct nid_stat *)data;
1823 struct exp_uuid_cb_data cb_data;
1824 struct obd_device *obd = stats->nid_obd;
1829 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1830 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1831 lprocfs_exp_print_uuid, &cb_data);
1832 return (*cb_data.len);
1835 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1836 cfs_hlist_node_t *hnode, void *cb_data)
1839 struct exp_uuid_cb_data *data = cb_data;
1840 struct obd_export *exp = cfs_hash_object(hs, hnode);
1842 if (exp->exp_lock_hash != NULL) {
1844 *data->len += cfs_hash_debug_header(data->page,
1847 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1854 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1855 int *eof, void *data)
1857 struct nid_stat *stats = (struct nid_stat *)data;
1858 struct exp_uuid_cb_data cb_data;
1859 struct obd_device *obd = stats->nid_obd;
1864 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1866 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1867 lprocfs_exp_print_hash, &cb_data);
1868 return (*cb_data.len);
1871 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1872 int count, int *eof, void *data)
1875 return snprintf(page, count, "%s\n",
1876 "Write into this file to clear all nid stats and "
1877 "stale nid entries");
1879 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1881 static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1883 struct nid_stat *stat = obj;
1886 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1887 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1888 /* object has only hash references. */
1889 spin_lock(&stat->nid_obd->obd_nid_lock);
1890 cfs_list_move(&stat->nid_list, data);
1891 spin_unlock(&stat->nid_obd->obd_nid_lock);
1894 /* we has reference to object - only clear data*/
1895 if (stat->nid_stats)
1896 lprocfs_clear_stats(stat->nid_stats);
1901 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1902 unsigned long count, void *data)
1904 struct obd_device *obd = (struct obd_device *)data;
1905 struct nid_stat *client_stat;
1906 CFS_LIST_HEAD(free_list);
1908 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1909 lprocfs_nid_stats_clear_write_cb, &free_list);
1911 while (!cfs_list_empty(&free_list)) {
1912 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1914 cfs_list_del_init(&client_stat->nid_list);
1915 lprocfs_free_client_stats(client_stat);
1920 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1922 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1924 struct nid_stat *new_stat, *old_stat;
1925 struct obd_device *obd = NULL;
1926 cfs_proc_dir_entry_t *entry;
1927 char *buffer = NULL;
1933 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1934 !exp->exp_obd->obd_nid_stats_hash)
1937 /* not test against zero because eric say:
1938 * You may only test nid against another nid, or LNET_NID_ANY.
1939 * Anything else is nonsense.*/
1940 if (!nid || *nid == LNET_NID_ANY)
1945 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1947 OBD_ALLOC_PTR(new_stat);
1948 if (new_stat == NULL)
1951 new_stat->nid = *nid;
1952 new_stat->nid_obd = exp->exp_obd;
1953 /* we need set default refcount to 1 to balance obd_disconnect */
1954 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1956 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1957 nid, &new_stat->nid_hash);
1958 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1959 old_stat, libcfs_nid2str(*nid),
1960 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1962 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1963 * been and will never be called. */
1964 if (exp->exp_nid_stats) {
1965 nidstat_putref(exp->exp_nid_stats);
1966 exp->exp_nid_stats = NULL;
1969 /* Return -EALREADY here so that we know that the /proc
1970 * entry already has been created */
1971 if (old_stat != new_stat) {
1972 exp->exp_nid_stats = old_stat;
1973 GOTO(destroy_new, rc = -EALREADY);
1975 /* not found - create */
1976 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1978 GOTO(destroy_new, rc = -ENOMEM);
1980 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1981 new_stat->nid_proc = lprocfs_register(buffer,
1982 obd->obd_proc_exports_entry,
1984 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1986 if (new_stat->nid_proc == NULL) {
1987 CERROR("Error making export directory for nid %s\n",
1988 libcfs_nid2str(*nid));
1989 GOTO(destroy_new_ns, rc = -ENOMEM);
1992 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1993 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1994 if (IS_ERR(entry)) {
1995 CWARN("Error adding the NID stats file\n");
1996 rc = PTR_ERR(entry);
1997 GOTO(destroy_new_ns, rc);
2000 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
2001 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
2002 if (IS_ERR(entry)) {
2003 CWARN("Error adding the hash file\n");
2004 rc = PTR_ERR(entry);
2005 GOTO(destroy_new_ns, rc);
2008 exp->exp_nid_stats = new_stat;
2010 /* protect competitive add to list, not need locking on destroy */
2011 spin_lock(&obd->obd_nid_lock);
2012 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
2013 spin_unlock(&obd->obd_nid_lock);
2018 if (new_stat->nid_proc != NULL)
2019 lprocfs_remove(&new_stat->nid_proc);
2020 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
2023 nidstat_putref(new_stat);
2024 OBD_FREE_PTR(new_stat);
2027 EXPORT_SYMBOL(lprocfs_exp_setup);
2029 int lprocfs_exp_cleanup(struct obd_export *exp)
2031 struct nid_stat *stat = exp->exp_nid_stats;
2033 if(!stat || !exp->exp_obd)
2036 nidstat_putref(exp->exp_nid_stats);
2037 exp->exp_nid_stats = NULL;
2041 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2043 int lprocfs_write_helper(const char *buffer, unsigned long count,
2046 return lprocfs_write_frac_helper(buffer, count, val, 1);
2048 EXPORT_SYMBOL(lprocfs_write_helper);
2050 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
2053 char kernbuf[20], *end, *pbuf;
2055 if (count > (sizeof(kernbuf) - 1))
2058 if (copy_from_user(kernbuf, buffer, count))
2061 kernbuf[count] = '\0';
2068 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
2072 if (end != NULL && *end == '.') {
2073 int temp_val, pow = 1;
2077 if (strlen(pbuf) > 5)
2078 pbuf[5] = '\0'; /*only allow 5bits fractional*/
2080 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
2083 for (i = 0; i < (end - pbuf); i++)
2086 *val += temp_val / pow;
2091 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2093 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
2096 long decimal_val, frac_val;
2102 decimal_val = val / mult;
2103 prtn = snprintf(buffer, count, "%ld", decimal_val);
2104 frac_val = val % mult;
2106 if (prtn < (count - 4) && frac_val > 0) {
2108 int i, temp_mult = 1, frac_bits = 0;
2110 temp_frac = frac_val * 10;
2111 buffer[prtn++] = '.';
2112 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2113 /* only reserved 2 bits fraction */
2114 buffer[prtn++] ='0';
2119 * Need to think these cases :
2120 * 1. #echo x.00 > /proc/xxx output result : x
2121 * 2. #echo x.0x > /proc/xxx output result : x.0x
2122 * 3. #echo x.x0 > /proc/xxx output result : x.x
2123 * 4. #echo x.xx > /proc/xxx output result : x.xx
2124 * Only reserved 2 bits fraction.
2126 for (i = 0; i < (5 - prtn); i++)
2129 frac_bits = min((int)count - prtn, 3 - frac_bits);
2130 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2131 frac_val * temp_mult / mult);
2134 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2136 if (buffer[prtn] == '.') {
2143 buffer[prtn++] ='\n';
2146 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2148 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2150 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2152 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2154 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2155 __u64 *val, int mult)
2157 char kernbuf[22], *end, *pbuf;
2158 __u64 whole, frac = 0, units;
2159 unsigned frac_d = 1;
2161 if (count > (sizeof(kernbuf) - 1))
2164 if (copy_from_user(kernbuf, buffer, count))
2167 kernbuf[count] = '\0';
2174 whole = simple_strtoull(pbuf, &end, 10);
2178 if (end != NULL && *end == '.') {
2182 /* need to limit frac_d to a __u32 */
2183 if (strlen(pbuf) > 10)
2186 frac = simple_strtoull(pbuf, &end, 10);
2187 /* count decimal places */
2188 for (i = 0; i < (end - pbuf); i++)
2205 /* Specified units override the multiplier */
2207 mult = mult < 0 ? -units : units;
2210 do_div(frac, frac_d);
2211 *val = whole * mult + frac;
2214 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2216 static char *lprocfs_strnstr(const char *s1, const char *s2, size_t len)
2225 if (!memcmp(s1, s2, l2))
2233 * Find the string \a name in the input \a buffer, and return a pointer to the
2234 * value immediately following \a name, reducing \a count appropriately.
2235 * If \a name is not found the original \a buffer is returned.
2237 char *lprocfs_find_named_value(const char *buffer, const char *name,
2238 unsigned long *count)
2241 size_t buflen = *count;
2243 /* there is no strnstr() in rhel5 and ubuntu kernels */
2244 val = lprocfs_strnstr(buffer, name, buflen);
2246 return (char *)buffer;
2248 val += strlen(name); /* skip prefix */
2249 while (val < buffer + buflen && isspace(*val)) /* skip separator */
2253 while (val < buffer + buflen && isalnum(*val)) {
2258 return val - *count;
2260 EXPORT_SYMBOL(lprocfs_find_named_value);
2262 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent,
2265 const struct file_operations *seq_fops,
2268 struct proc_dir_entry *entry;
2271 /* Disallow secretly (un)writable entries. */
2272 LASSERT((seq_fops->write == NULL) == ((mode & 0222) == 0));
2274 LPROCFS_WRITE_ENTRY();
2275 entry = create_proc_entry(name, mode, parent);
2277 entry->proc_fops = seq_fops;
2280 LPROCFS_WRITE_EXIT();
2287 EXPORT_SYMBOL(lprocfs_seq_create);
2289 int lprocfs_obd_seq_create(struct obd_device *dev,
2292 const struct file_operations *seq_fops,
2295 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2296 mode, seq_fops, data));
2298 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2300 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2302 if (value >= OBD_HIST_MAX)
2303 value = OBD_HIST_MAX - 1;
2305 spin_lock(&oh->oh_lock);
2306 oh->oh_buckets[value]++;
2307 spin_unlock(&oh->oh_lock);
2309 EXPORT_SYMBOL(lprocfs_oh_tally);
2311 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2315 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2318 lprocfs_oh_tally(oh, val);
2320 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2322 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2324 unsigned long ret = 0;
2327 for (i = 0; i < OBD_HIST_MAX; i++)
2328 ret += oh->oh_buckets[i];
2331 EXPORT_SYMBOL(lprocfs_oh_sum);
2333 void lprocfs_oh_clear(struct obd_histogram *oh)
2335 spin_lock(&oh->oh_lock);
2336 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2337 spin_unlock(&oh->oh_lock);
2339 EXPORT_SYMBOL(lprocfs_oh_clear);
2341 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2342 int count, int *eof, void *data)
2344 struct obd_device *obd = data;
2350 c += cfs_hash_debug_header(page, count);
2351 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2352 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2353 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2357 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2359 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2360 int count, int *eof, void *data)
2362 struct obd_device *obd = data;
2365 LASSERT(obd != NULL);
2366 LASSERT(count >= 0);
2368 /* Set start of user data returned to
2369 page + off since the user may have
2370 requested to read much smaller than
2371 what we need to read */
2372 *start = page + off;
2375 * We know we are allocated a page here.
2376 * Also we know that this function will
2377 * not need to write more than a page
2378 * so we can truncate at PAGE_CACHE_SIZE.
2380 size = min(count + (int)off + 1, (int)PAGE_CACHE_SIZE);
2382 /* Initialize the page */
2383 memset(page, 0, size);
2385 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2387 if (obd->obd_max_recoverable_clients == 0) {
2388 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2394 /* sampled unlocked, but really... */
2395 if (obd->obd_recovering == 0) {
2396 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2398 if (lprocfs_obd_snprintf(&page, size, &len,
2399 "recovery_start: %lu\n",
2400 obd->obd_recovery_start) <= 0)
2402 if (lprocfs_obd_snprintf(&page, size, &len,
2403 "recovery_duration: %lu\n",
2404 obd->obd_recovery_end -
2405 obd->obd_recovery_start) <= 0)
2407 /* Number of clients that have completed recovery */
2408 if (lprocfs_obd_snprintf(&page, size, &len,
2409 "completed_clients: %d/%d\n",
2410 obd->obd_max_recoverable_clients -
2411 obd->obd_stale_clients,
2412 obd->obd_max_recoverable_clients) <= 0)
2414 if (lprocfs_obd_snprintf(&page, size, &len,
2415 "replayed_requests: %d\n",
2416 obd->obd_replayed_requests) <= 0)
2418 if (lprocfs_obd_snprintf(&page, size, &len,
2419 "last_transno: "LPD64"\n",
2420 obd->obd_next_recovery_transno - 1)<=0)
2422 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2423 obd->obd_version_recov ?
2424 "ENABLED" : "DISABLED") <=0)
2426 if (lprocfs_obd_snprintf(&page, size, &len, "IR: %s\n",
2428 "DISABLED" : "ENABLED") <= 0)
2433 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2435 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2436 obd->obd_recovery_start) <= 0)
2438 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2439 cfs_time_current_sec() >=
2440 obd->obd_recovery_start +
2441 obd->obd_recovery_timeout ? 0 :
2442 obd->obd_recovery_start +
2443 obd->obd_recovery_timeout -
2444 cfs_time_current_sec()) <= 0)
2446 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2447 cfs_atomic_read(&obd->obd_connected_clients),
2448 obd->obd_max_recoverable_clients) <= 0)
2450 /* Number of clients that have completed recovery */
2451 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2452 cfs_atomic_read(&obd->obd_req_replay_clients))
2455 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2456 cfs_atomic_read(&obd->obd_lock_replay_clients))
2459 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2460 cfs_atomic_read(&obd->obd_connected_clients) -
2461 cfs_atomic_read(&obd->obd_lock_replay_clients))
2464 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2465 obd->obd_stale_clients) <= 0)
2467 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2468 obd->obd_replayed_requests) <= 0)
2470 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2471 obd->obd_requests_queued_for_recovery) <= 0)
2474 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2475 obd->obd_next_recovery_transno) <= 0)
2481 return min(count, len - (int)off);
2483 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2485 int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off,
2486 int count, int *eof, void *data)
2488 struct obd_device *obd = (struct obd_device *)data;
2489 LASSERT(obd != NULL);
2491 return snprintf(page, count, "%d\n",
2492 obd->obd_recovery_ir_factor);
2494 EXPORT_SYMBOL(lprocfs_obd_rd_ir_factor);
2496 int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer,
2497 unsigned long count, void *data)
2499 struct obd_device *obd = (struct obd_device *)data;
2501 LASSERT(obd != NULL);
2503 rc = lprocfs_write_helper(buffer, count, &val);
2507 if (val < OBD_IR_FACTOR_MIN || val > OBD_IR_FACTOR_MAX)
2510 obd->obd_recovery_ir_factor = val;
2513 EXPORT_SYMBOL(lprocfs_obd_wr_ir_factor);
2515 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2516 int count, int *eof, void *data)
2518 struct obd_device *obd = (struct obd_device *)data;
2519 LASSERT(obd != NULL);
2521 return snprintf(page, count, "%d\n",
2522 obd->obd_recovery_timeout);
2524 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2526 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2527 unsigned long count, void *data)
2529 struct obd_device *obd = (struct obd_device *)data;
2531 LASSERT(obd != NULL);
2533 rc = lprocfs_write_helper(buffer, count, &val);
2537 obd->obd_recovery_timeout = val;
2540 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2542 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2543 int count, int *eof, void *data)
2545 struct obd_device *obd = data;
2546 LASSERT(obd != NULL);
2548 return snprintf(page, count, "%u\n", obd->obd_recovery_time_hard);
2550 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2552 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2553 unsigned long count, void *data)
2555 struct obd_device *obd = data;
2557 LASSERT(obd != NULL);
2559 rc = lprocfs_write_helper(buffer, count, &val);
2563 obd->obd_recovery_time_hard = val;
2566 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2568 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2569 int count, int *eof, void *data)
2571 struct obd_device *dev = data;
2572 struct client_obd *cli = &dev->u.cli;
2575 client_obd_list_lock(&cli->cl_loi_list_lock);
2576 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2577 client_obd_list_unlock(&cli->cl_loi_list_lock);
2580 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2582 #ifdef HAVE_SERVER_SUPPORT
2583 int lprocfs_target_rd_instance(char *page, char **start, off_t off,
2584 int count, int *eof, void *data)
2586 struct obd_device *obd = (struct obd_device *)data;
2587 struct obd_device_target *target = &obd->u.obt;
2589 LASSERT(obd != NULL);
2590 LASSERT(target->obt_magic == OBT_MAGIC);
2592 return snprintf(page, count, "%u\n", obd->u.obt.obt_instance);
2594 EXPORT_SYMBOL(lprocfs_target_rd_instance);