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>
41 #define DEBUG_SUBSYSTEM S_CLASS
44 # include <liblustre.h>
47 #include <obd_class.h>
48 #include <lprocfs_status.h>
49 #include <lustre_fsfilt.h>
50 #include <lustre_log.h>
51 #include <lustre/lustre_idl.h>
52 #include <dt_object.h>
56 static int lprocfs_no_percpu_stats = 0;
57 CFS_MODULE_PARM(lprocfs_no_percpu_stats, "i", int, 0644,
58 "Do not alloc percpu data for lprocfs stats");
60 #define MAX_STRING_SIZE 128
62 /* for bug 10866, global variable */
63 DECLARE_RWSEM(_lprocfs_lock);
64 EXPORT_SYMBOL(_lprocfs_lock);
66 int lprocfs_single_release(struct inode *inode, struct file *file)
69 return single_release(inode, file);
71 EXPORT_SYMBOL(lprocfs_single_release);
73 int lprocfs_seq_release(struct inode *inode, struct file *file)
76 return seq_release(inode, file);
78 EXPORT_SYMBOL(lprocfs_seq_release);
80 static struct proc_dir_entry *__lprocfs_srch(struct proc_dir_entry *head,
83 struct proc_dir_entry *temp;
89 while (temp != NULL) {
90 if (strcmp(temp->name, name) == 0) {
99 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
102 struct proc_dir_entry *temp;
104 LPROCFS_SRCH_ENTRY();
105 temp = __lprocfs_srch(head, name);
109 EXPORT_SYMBOL(lprocfs_srch);
111 /* lprocfs API calls */
113 /* Function that emulates snprintf but also has the side effect of advancing
114 the page pointer for the next write into the buffer, incrementing the total
115 length written to the buffer, and decrementing the size left in the
117 static int lprocfs_obd_snprintf(char **page, int end, int *len,
118 const char *format, ...)
126 va_start(list, format);
127 n = vsnprintf(*page, end - *len, format, list);
130 *page += n; *len += n;
134 cfs_proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
136 read_proc_t *read_proc,
137 write_proc_t *write_proc,
139 struct file_operations *fops)
141 cfs_proc_dir_entry_t *proc;
144 if (root == NULL || name == NULL)
145 return ERR_PTR(-EINVAL);
152 LPROCFS_WRITE_ENTRY();
153 proc = create_proc_entry(name, mode, root);
155 CERROR("LprocFS: No memory to create /proc entry %s", name);
156 LPROCFS_WRITE_EXIT();
157 return ERR_PTR(-ENOMEM);
159 proc->read_proc = read_proc;
160 proc->write_proc = write_proc;
163 proc->proc_fops = fops;
164 LPROCFS_WRITE_EXIT();
167 EXPORT_SYMBOL(lprocfs_add_simple);
169 struct proc_dir_entry *lprocfs_add_symlink(const char *name,
170 struct proc_dir_entry *parent, const char *format, ...)
172 struct proc_dir_entry *entry;
176 if (parent == NULL || format == NULL)
179 OBD_ALLOC_WAIT(dest, MAX_STRING_SIZE + 1);
183 va_start(ap, format);
184 vsnprintf(dest, MAX_STRING_SIZE, format, ap);
187 entry = proc_symlink(name, parent, dest);
189 CERROR("LprocFS: Could not create symbolic link from %s to %s",
192 OBD_FREE(dest, MAX_STRING_SIZE + 1);
195 EXPORT_SYMBOL(lprocfs_add_symlink);
197 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
198 size_t size, loff_t *ppos)
200 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
201 char *page, *start = NULL;
202 int rc = 0, eof = 1, count;
204 if (*ppos >= CFS_PAGE_SIZE)
207 page = (char *)__get_free_page(GFP_KERNEL);
211 if (LPROCFS_ENTRY_AND_CHECK(dp)) {
216 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
218 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
224 /* for lustre proc read, the read count must be less than PAGE_SIZE */
233 start = page + *ppos;
234 } else if (start < page) {
238 count = (rc < size) ? rc : size;
239 if (cfs_copy_to_user(buf, start, count)) {
246 free_page((unsigned long)page);
250 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
251 size_t size, loff_t *ppos)
253 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
256 if (LPROCFS_ENTRY_AND_CHECK(dp))
259 rc = dp->write_proc(f, buf, size, dp->data);
264 static struct file_operations lprocfs_generic_fops = {
265 .owner = THIS_MODULE,
266 .read = lprocfs_fops_read,
267 .write = lprocfs_fops_write,
270 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
272 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
273 struct obd_device *obd = dp->data;
275 cfs_atomic_inc(&obd->obd_evict_inprogress);
280 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
282 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
283 struct obd_device *obd = dp->data;
285 cfs_atomic_dec(&obd->obd_evict_inprogress);
286 cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
291 struct file_operations lprocfs_evict_client_fops = {
292 .owner = THIS_MODULE,
293 .read = lprocfs_fops_read,
294 .write = lprocfs_fops_write,
295 .open = lprocfs_evict_client_open,
296 .release = lprocfs_evict_client_release,
298 EXPORT_SYMBOL(lprocfs_evict_client_fops);
303 * \param root [in] The parent proc entry on which new entry will be added.
304 * \param list [in] Array of proc entries to be added.
305 * \param data [in] The argument to be passed when entries read/write routines
306 * are called through /proc file.
308 * \retval 0 on success
311 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
316 if (root == NULL || list == NULL)
319 LPROCFS_WRITE_ENTRY();
320 while (list->name != NULL) {
321 struct proc_dir_entry *cur_root, *proc;
322 char *pathcopy, *cur, *next, pathbuf[64];
323 int pathsize = strlen(list->name) + 1;
328 /* need copy of path for strsep */
329 if (strlen(list->name) > sizeof(pathbuf) - 1) {
330 OBD_ALLOC(pathcopy, pathsize);
331 if (pathcopy == NULL)
332 GOTO(out, rc = -ENOMEM);
338 strcpy(pathcopy, list->name);
340 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
341 if (*cur =='\0') /* skip double/trailing "/" */
344 proc = __lprocfs_srch(cur_root, cur);
345 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
346 cur_root->name, cur, next,
347 (proc ? "exists" : "new"));
349 cur_root = (proc ? proc :
350 proc_mkdir(cur, cur_root));
351 } else if (proc == NULL) {
353 if (list->proc_mode != 0000) {
354 mode = list->proc_mode;
358 if (list->write_fptr)
361 proc = create_proc_entry(cur, mode, cur_root);
365 if (pathcopy != pathbuf)
366 OBD_FREE(pathcopy, pathsize);
368 if (cur_root == NULL || proc == NULL) {
369 CERROR("LprocFS: No memory to create /proc entry %s",
371 GOTO(out, rc = -ENOMEM);
375 proc->proc_fops = list->fops;
377 proc->proc_fops = &lprocfs_generic_fops;
378 proc->read_proc = list->read_fptr;
379 proc->write_proc = list->write_fptr;
380 proc->data = (list->data ? list->data : data);
384 LPROCFS_WRITE_EXIT();
387 EXPORT_SYMBOL(lprocfs_add_vars);
389 void lprocfs_remove_nolock(struct proc_dir_entry **rooth)
391 struct proc_dir_entry *root = *rooth;
392 struct proc_dir_entry *temp = root;
393 struct proc_dir_entry *rm_entry;
394 struct proc_dir_entry *parent;
400 parent = root->parent;
401 LASSERT(parent != NULL);
404 while (temp->subdir != NULL)
410 /* Memory corruption once caused this to fail, and
411 without this LASSERT we would loop here forever. */
412 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
413 "0x%p %s/%s len %d\n", rm_entry, temp->name,
414 rm_entry->name, (int)strlen(rm_entry->name));
416 remove_proc_entry(rm_entry->name, temp);
422 void lprocfs_remove(struct proc_dir_entry **rooth)
424 LPROCFS_WRITE_ENTRY(); /* search vs remove race */
425 lprocfs_remove_nolock(rooth);
426 LPROCFS_WRITE_EXIT();
428 EXPORT_SYMBOL(lprocfs_remove);
430 void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
432 LASSERT(parent != NULL);
433 remove_proc_entry(name, parent);
435 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
437 void lprocfs_try_remove_proc_entry(const char *name,
438 struct proc_dir_entry *parent)
440 struct proc_dir_entry *t = NULL;
441 struct proc_dir_entry **p;
444 LASSERT(parent != NULL);
447 LPROCFS_WRITE_ENTRY();
449 /* lookup target name */
450 for (p = &parent->subdir; *p; p = &(*p)->next) {
451 if ((*p)->namelen != len)
453 if (memcmp(name, (*p)->name, len))
460 /* verify it's empty: do not count "num_refs" */
461 for (p = &t->subdir; *p; p = &(*p)->next) {
462 if ((*p)->namelen != strlen("num_refs")) {
466 if (memcmp("num_refs", (*p)->name,
467 strlen("num_refs"))) {
475 lprocfs_remove_nolock(&t);
477 LPROCFS_WRITE_EXIT();
481 EXPORT_SYMBOL(lprocfs_try_remove_proc_entry);
483 struct proc_dir_entry *lprocfs_register(const char *name,
484 struct proc_dir_entry *parent,
485 struct lprocfs_vars *list, void *data)
487 struct proc_dir_entry *newchild;
489 newchild = lprocfs_srch(parent, name);
490 if (newchild != NULL) {
491 CERROR(" Lproc: Attempting to register %s more than once \n",
493 return ERR_PTR(-EALREADY);
496 newchild = proc_mkdir(name, parent);
497 if (newchild != NULL && list != NULL) {
498 int rc = lprocfs_add_vars(newchild, list, data);
500 lprocfs_remove(&newchild);
506 EXPORT_SYMBOL(lprocfs_register);
508 /* Generic callbacks */
509 int lprocfs_rd_uint(char *page, char **start, off_t off,
510 int count, int *eof, void *data)
512 unsigned int *temp = data;
513 return snprintf(page, count, "%u\n", *temp);
515 EXPORT_SYMBOL(lprocfs_rd_uint);
517 int lprocfs_wr_uint(struct file *file, const char *buffer,
518 unsigned long count, void *data)
521 char dummy[MAX_STRING_SIZE + 1], *end;
524 dummy[MAX_STRING_SIZE] = '\0';
525 if (cfs_copy_from_user(dummy, buffer, MAX_STRING_SIZE))
528 tmp = simple_strtoul(dummy, &end, 0);
532 *p = (unsigned int)tmp;
535 EXPORT_SYMBOL(lprocfs_wr_uint);
537 int lprocfs_rd_u64(char *page, char **start, off_t off,
538 int count, int *eof, void *data)
540 LASSERT(data != NULL);
542 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
544 EXPORT_SYMBOL(lprocfs_rd_u64);
546 int lprocfs_rd_atomic(char *page, char **start, off_t off,
547 int count, int *eof, void *data)
549 cfs_atomic_t *atom = data;
550 LASSERT(atom != NULL);
552 return snprintf(page, count, "%d\n", cfs_atomic_read(atom));
554 EXPORT_SYMBOL(lprocfs_rd_atomic);
556 int lprocfs_wr_atomic(struct file *file, const char *buffer,
557 unsigned long count, void *data)
559 cfs_atomic_t *atm = data;
563 rc = lprocfs_write_helper(buffer, count, &val);
570 cfs_atomic_set(atm, val);
573 EXPORT_SYMBOL(lprocfs_wr_atomic);
575 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
576 int *eof, void *data)
578 struct obd_device *obd = data;
580 LASSERT(obd != NULL);
582 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
584 EXPORT_SYMBOL(lprocfs_rd_uuid);
586 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
587 int *eof, void *data)
589 struct obd_device *dev = data;
591 LASSERT(dev != NULL);
592 LASSERT(dev->obd_name != NULL);
594 return snprintf(page, count, "%s\n", dev->obd_name);
596 EXPORT_SYMBOL(lprocfs_rd_name);
598 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
601 struct obd_device *obd = data;
603 LASSERT(obd != NULL);
604 LASSERT(obd->obd_fsops != NULL);
605 LASSERT(obd->obd_fsops->fs_type != NULL);
606 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
608 EXPORT_SYMBOL(lprocfs_rd_fstype);
610 int lprocfs_rd_blksize(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),
620 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
624 EXPORT_SYMBOL(lprocfs_rd_blksize);
626 int lprocfs_osd_rd_blksize(char *page, char **start, off_t off,
627 int count, int *eof, void *data)
629 struct dt_device *dt = data;
630 struct obd_statfs osfs;
631 int rc = dt_statfs(NULL, dt, &osfs);
634 rc = snprintf(page, count, "%d\n",
635 (unsigned) osfs.os_bsize);
639 EXPORT_SYMBOL(lprocfs_osd_rd_blksize);
641 int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
642 int *eof, void *data)
644 struct obd_device *obd = data;
645 struct obd_statfs osfs;
646 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
647 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
650 __u32 blk_size = osfs.os_bsize >> 10;
651 __u64 result = osfs.os_blocks;
653 while (blk_size >>= 1)
657 rc = snprintf(page, count, LPU64"\n", result);
661 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
663 int lprocfs_osd_rd_kbytestotal(char *page, char **start, off_t off,
664 int count, int *eof, void *data)
666 struct dt_device *dt = data;
667 struct obd_statfs osfs;
668 int rc = dt_statfs(NULL, dt, &osfs);
670 __u32 blk_size = osfs.os_bsize >> 10;
671 __u64 result = osfs.os_blocks;
673 while (blk_size >>= 1)
677 rc = snprintf(page, count, LPU64"\n", result);
681 EXPORT_SYMBOL(lprocfs_osd_rd_kbytestotal);
683 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
684 int *eof, void *data)
686 struct obd_device *obd = data;
687 struct obd_statfs osfs;
688 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
689 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
692 __u32 blk_size = osfs.os_bsize >> 10;
693 __u64 result = osfs.os_bfree;
695 while (blk_size >>= 1)
699 rc = snprintf(page, count, LPU64"\n", result);
703 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
705 int lprocfs_osd_rd_kbytesfree(char *page, char **start, off_t off,
706 int count, int *eof, void *data)
708 struct dt_device *dt = data;
709 struct obd_statfs osfs;
710 int rc = dt_statfs(NULL, dt, &osfs);
712 __u32 blk_size = osfs.os_bsize >> 10;
713 __u64 result = osfs.os_bfree;
715 while (blk_size >>= 1)
719 rc = snprintf(page, count, LPU64"\n", result);
723 EXPORT_SYMBOL(lprocfs_osd_rd_kbytesfree);
725 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
726 int *eof, void *data)
728 struct obd_device *obd = data;
729 struct obd_statfs osfs;
730 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
731 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
734 __u32 blk_size = osfs.os_bsize >> 10;
735 __u64 result = osfs.os_bavail;
737 while (blk_size >>= 1)
741 rc = snprintf(page, count, LPU64"\n", result);
745 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
747 int lprocfs_osd_rd_kbytesavail(char *page, char **start, off_t off,
748 int count, int *eof, void *data)
750 struct dt_device *dt = data;
751 struct obd_statfs osfs;
752 int rc = dt_statfs(NULL, dt, &osfs);
754 __u32 blk_size = osfs.os_bsize >> 10;
755 __u64 result = osfs.os_bavail;
757 while (blk_size >>= 1)
761 rc = snprintf(page, count, LPU64"\n", result);
765 EXPORT_SYMBOL(lprocfs_osd_rd_kbytesavail);
767 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
768 int *eof, void *data)
770 struct obd_device *obd = data;
771 struct obd_statfs osfs;
772 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
773 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
777 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
782 EXPORT_SYMBOL(lprocfs_rd_filestotal);
784 int lprocfs_osd_rd_filestotal(char *page, char **start, off_t off,
785 int count, int *eof, void *data)
787 struct dt_device *dt = data;
788 struct obd_statfs osfs;
789 int rc = dt_statfs(NULL, dt, &osfs);
792 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
797 EXPORT_SYMBOL(lprocfs_osd_rd_filestotal);
799 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
800 int *eof, void *data)
802 struct obd_device *obd = data;
803 struct obd_statfs osfs;
804 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
805 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
809 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
813 EXPORT_SYMBOL(lprocfs_rd_filesfree);
815 int lprocfs_osd_rd_filesfree(char *page, char **start, off_t off,
816 int count, int *eof, void *data)
818 struct dt_device *dt = data;
819 struct obd_statfs osfs;
820 int rc = dt_statfs(NULL, dt, &osfs);
823 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
827 EXPORT_SYMBOL(lprocfs_osd_rd_filesfree);
829 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
830 int *eof, void *data)
832 struct obd_device *obd = data;
833 struct obd_import *imp;
834 char *imp_state_name = NULL;
837 LASSERT(obd != NULL);
838 LPROCFS_CLIMP_CHECK(obd);
839 imp = obd->u.cli.cl_import;
840 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
842 rc = snprintf(page, count, "%s\t%s%s\n",
843 obd2cli_tgt(obd), imp_state_name,
844 imp->imp_deactive ? "\tDEACTIVATED" : "");
846 LPROCFS_CLIMP_EXIT(obd);
849 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
851 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
852 int *eof, void *data)
854 struct obd_device *obd = data;
855 struct ptlrpc_connection *conn;
858 LASSERT(obd != NULL);
860 LPROCFS_CLIMP_CHECK(obd);
861 conn = obd->u.cli.cl_import->imp_connection;
863 if (conn && obd->u.cli.cl_import) {
864 rc = snprintf(page, count, "%s\n",
865 conn->c_remote_uuid.uuid);
867 rc = snprintf(page, count, "%s\n", "<none>");
870 LPROCFS_CLIMP_EXIT(obd);
873 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
875 /** add up per-cpu counters */
876 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
877 struct lprocfs_counter *cnt)
879 struct lprocfs_counter *ptr;
880 unsigned int num_entry;
882 unsigned long flags = 0;
884 memset(cnt, 0, sizeof(*cnt));
887 /* set count to 1 to avoid divide-by-zero errs in callers */
892 cnt->lc_min = LC_MIN_INIT;
894 num_entry = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
896 for (i = 0; i < num_entry; i++) {
897 if (stats->ls_percpu[i] == NULL)
900 ptr = &(stats->ls_percpu[i])->lp_cntr[idx];
901 cnt->lc_count += ptr->lc_count;
902 cnt->lc_sum += ptr->lc_sum;
903 if (ptr->lc_min < cnt->lc_min)
904 cnt->lc_min = ptr->lc_min;
905 if (ptr->lc_max > cnt->lc_max)
906 cnt->lc_max = ptr->lc_max;
907 cnt->lc_sumsquare += ptr->lc_sumsquare;
910 cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
911 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
913 EXPORT_SYMBOL(lprocfs_stats_collect);
916 * Append a space separated list of current set flags to str.
918 #define flag2str(flag) \
919 if (imp->imp_##flag && max - len > 0) \
920 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
921 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
925 if (imp->imp_obd->obd_no_recov)
926 len += snprintf(str, max - len, "no_recov");
930 flag2str(replayable);
936 static const char *obd_connect_names[] = {
950 "join_file(obsolete)",
954 "remote_client_by_force",
963 "mds_mds_connection",
966 "alt_checksum_algorithm",
991 int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
996 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
998 ret += snprintf(page + ret, count - ret, "%s%s",
999 ret ? sep : "", obd_connect_names[i]);
1001 if (flags & ~(mask - 1))
1002 ret += snprintf(page + ret, count - ret,
1003 "%sunknown flags "LPX64,
1004 ret ? sep : "", flags & ~(mask - 1));
1007 EXPORT_SYMBOL(obd_connect_flags2str);
1009 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
1010 int *eof, void *data)
1012 struct lprocfs_counter ret;
1013 struct obd_device *obd = (struct obd_device *)data;
1014 struct obd_import *imp;
1015 struct obd_import_conn *conn;
1016 int i, j, k, rw = 0;
1018 LASSERT(obd != NULL);
1019 LPROCFS_CLIMP_CHECK(obd);
1020 imp = obd->u.cli.cl_import;
1023 i = snprintf(page, count,
1029 " connect_flags: [",
1032 ptlrpc_import_state_name(imp->imp_state),
1033 imp->imp_connect_data.ocd_instance);
1034 i += obd_connect_flags2str(page + i, count - i,
1035 imp->imp_connect_data.ocd_connect_flags,
1037 i += snprintf(page + i, count - i,
1039 " import_flags: [");
1040 i += obd_import_flags2str(imp, page + i, count - i);
1042 i += snprintf(page + i, count - i,
1045 " failover_nids: [");
1046 spin_lock(&imp->imp_lock);
1048 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
1049 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
1050 libcfs_nid2str(conn->oic_conn->c_peer.nid));
1053 i += snprintf(page + i, count - i,
1055 " current_connection: %s\n"
1056 " connection_attempts: %u\n"
1058 " in-progress_invalidations: %u\n",
1059 imp->imp_connection == NULL ? "<none>" :
1060 libcfs_nid2str(imp->imp_connection->c_peer.nid),
1062 imp->imp_generation,
1063 cfs_atomic_read(&imp->imp_inval_count));
1064 spin_unlock(&imp->imp_lock);
1066 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
1067 if (ret.lc_count != 0) {
1068 /* first argument to do_div MUST be __u64 */
1069 __u64 sum = ret.lc_sum;
1070 do_div(sum, ret.lc_count);
1074 i += snprintf(page + i, count - i,
1077 " unregistering: %u\n"
1079 " avg_waittime: "LPU64" %s\n",
1080 cfs_atomic_read(&imp->imp_inflight),
1081 cfs_atomic_read(&imp->imp_unregistering),
1082 cfs_atomic_read(&imp->imp_timeouts),
1083 ret.lc_sum, ret.lc_units);
1086 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
1087 if (imp->imp_at.iat_portal[j] == 0)
1089 k = max_t(unsigned int, k,
1090 at_get(&imp->imp_at.iat_service_estimate[j]));
1092 i += snprintf(page + i, count - i,
1093 " service_estimates:\n"
1094 " services: %u sec\n"
1095 " network: %u sec\n",
1097 at_get(&imp->imp_at.iat_net_latency));
1099 i += snprintf(page + i, count - i,
1101 " last_replay: "LPU64"\n"
1102 " peer_committed: "LPU64"\n"
1103 " last_checked: "LPU64"\n",
1104 imp->imp_last_replay_transno,
1105 imp->imp_peer_committed_transno,
1106 imp->imp_last_transno_checked);
1108 /* avg data rates */
1109 for (rw = 0; rw <= 1; rw++) {
1110 lprocfs_stats_collect(obd->obd_svc_stats,
1111 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
1113 if (ret.lc_sum > 0 && ret.lc_count > 0) {
1114 /* first argument to do_div MUST be __u64 */
1115 __u64 sum = ret.lc_sum;
1116 do_div(sum, ret.lc_count);
1118 i += snprintf(page + i, count - i,
1119 " %s_data_averages:\n"
1120 " bytes_per_rpc: "LPU64"\n",
1121 rw ? "write" : "read",
1124 k = (int)ret.lc_sum;
1125 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
1126 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
1127 if (ret.lc_sum > 0 && ret.lc_count != 0) {
1128 /* first argument to do_div MUST be __u64 */
1129 __u64 sum = ret.lc_sum;
1130 do_div(sum, ret.lc_count);
1132 i += snprintf(page + i, count - i,
1133 " %s_per_rpc: "LPU64"\n",
1134 ret.lc_units, ret.lc_sum);
1135 j = (int)ret.lc_sum;
1137 i += snprintf(page + i, count - i,
1138 " MB_per_sec: %u.%.02u\n",
1139 k / j, (100 * k / j) % 100);
1143 LPROCFS_CLIMP_EXIT(obd);
1146 EXPORT_SYMBOL(lprocfs_rd_import);
1148 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
1149 int *eof, void *data)
1151 struct obd_device *obd = (struct obd_device *)data;
1152 struct obd_import *imp;
1155 LASSERT(obd != NULL);
1156 LPROCFS_CLIMP_CHECK(obd);
1157 imp = obd->u.cli.cl_import;
1160 i = snprintf(page, count, "current_state: %s\n",
1161 ptlrpc_import_state_name(imp->imp_state));
1162 i += snprintf(page + i, count - i,
1163 "state_history:\n");
1164 k = imp->imp_state_hist_idx;
1165 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
1166 struct import_state_hist *ish =
1167 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
1168 if (ish->ish_state == 0)
1170 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
1172 ptlrpc_import_state_name(ish->ish_state));
1175 LPROCFS_CLIMP_EXIT(obd);
1178 EXPORT_SYMBOL(lprocfs_rd_state);
1180 int lprocfs_at_hist_helper(char *page, int count, int rc,
1181 struct adaptive_timeout *at)
1184 for (i = 0; i < AT_BINS; i++)
1185 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1186 rc += snprintf(page + rc, count - rc, "\n");
1189 EXPORT_SYMBOL(lprocfs_at_hist_helper);
1191 /* See also ptlrpc_lprocfs_rd_timeouts */
1192 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1193 int *eof, void *data)
1195 struct obd_device *obd = (struct obd_device *)data;
1196 struct obd_import *imp;
1197 unsigned int cur, worst;
1202 LASSERT(obd != NULL);
1203 LPROCFS_CLIMP_CHECK(obd);
1204 imp = obd->u.cli.cl_import;
1207 now = cfs_time_current_sec();
1209 /* Some network health info for kicks */
1210 s2dhms(&ts, now - imp->imp_last_reply_time);
1211 rc += snprintf(page + rc, count - rc,
1212 "%-10s : %ld, "DHMS_FMT" ago\n",
1213 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1215 cur = at_get(&imp->imp_at.iat_net_latency);
1216 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1217 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1218 s2dhms(&ts, now - worstt);
1219 rc += snprintf(page + rc, count - rc,
1220 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1221 "network", cur, worst, worstt, DHMS_VARS(&ts));
1222 rc = lprocfs_at_hist_helper(page, count, rc,
1223 &imp->imp_at.iat_net_latency);
1225 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1226 if (imp->imp_at.iat_portal[i] == 0)
1228 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1229 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1230 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1231 s2dhms(&ts, now - worstt);
1232 rc += snprintf(page + rc, count - rc,
1233 "portal %-2d : cur %3u worst %3u (at %ld, "
1234 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1235 cur, worst, worstt, DHMS_VARS(&ts));
1236 rc = lprocfs_at_hist_helper(page, count, rc,
1237 &imp->imp_at.iat_service_estimate[i]);
1240 LPROCFS_CLIMP_EXIT(obd);
1243 EXPORT_SYMBOL(lprocfs_rd_timeouts);
1245 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1246 int count, int *eof, void *data)
1248 struct obd_device *obd = data;
1252 LPROCFS_CLIMP_CHECK(obd);
1253 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1254 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1255 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1256 ret += snprintf(page + ret, count - ret, "\n");
1257 LPROCFS_CLIMP_EXIT(obd);
1260 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1262 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1263 int *eof, void *data)
1265 struct obd_device *obd = data;
1267 LASSERT(obd != NULL);
1269 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1271 EXPORT_SYMBOL(lprocfs_rd_num_exports);
1273 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1274 int *eof, void *data)
1276 struct obd_type *class = (struct obd_type*) data;
1278 LASSERT(class != NULL);
1280 return snprintf(page, count, "%d\n", class->typ_refcnt);
1282 EXPORT_SYMBOL(lprocfs_rd_numrefs);
1284 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1288 LASSERT(obd != NULL);
1289 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1290 LASSERT(obd->obd_type->typ_procroot != NULL);
1292 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1293 obd->obd_type->typ_procroot,
1295 if (IS_ERR(obd->obd_proc_entry)) {
1296 rc = PTR_ERR(obd->obd_proc_entry);
1297 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1298 obd->obd_proc_entry = NULL;
1302 EXPORT_SYMBOL(lprocfs_obd_setup);
1304 int lprocfs_obd_cleanup(struct obd_device *obd)
1308 if (obd->obd_proc_exports_entry) {
1309 /* Should be no exports left */
1310 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1311 lprocfs_remove(&obd->obd_proc_exports_entry);
1312 obd->obd_proc_exports_entry = NULL;
1314 if (obd->obd_proc_entry) {
1315 lprocfs_remove(&obd->obd_proc_entry);
1316 obd->obd_proc_entry = NULL;
1320 EXPORT_SYMBOL(lprocfs_obd_cleanup);
1322 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1324 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1325 client_stat->nid_proc, client_stat->nid_stats,
1326 client_stat->nid_brw_stats);
1328 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1329 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1330 atomic_read(&client_stat->nid_exp_ref_count));
1332 if (client_stat->nid_proc)
1333 lprocfs_remove(&client_stat->nid_proc);
1335 if (client_stat->nid_stats)
1336 lprocfs_free_stats(&client_stat->nid_stats);
1338 if (client_stat->nid_brw_stats)
1339 OBD_FREE_PTR(client_stat->nid_brw_stats);
1341 if (client_stat->nid_ldlm_stats)
1342 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1344 OBD_FREE_PTR(client_stat);
1349 void lprocfs_free_per_client_stats(struct obd_device *obd)
1351 cfs_hash_t *hash = obd->obd_nid_stats_hash;
1352 struct nid_stat *stat;
1355 /* we need extra list - because hash_exit called to early */
1356 /* not need locking because all clients is died */
1357 while (!cfs_list_empty(&obd->obd_nid_stats)) {
1358 stat = cfs_list_entry(obd->obd_nid_stats.next,
1359 struct nid_stat, nid_list);
1360 cfs_list_del_init(&stat->nid_list);
1361 cfs_hash_del(hash, &stat->nid, &stat->nid_hash);
1362 lprocfs_free_client_stats(stat);
1366 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
1368 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1369 enum lprocfs_stats_flags flags)
1371 struct lprocfs_stats *stats;
1372 unsigned int percpusize;
1373 unsigned int num_entry;
1378 if (lprocfs_no_percpu_stats != 0)
1379 flags |= LPROCFS_STATS_FLAG_NOPERCPU;
1381 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1384 num_entry = cfs_num_possible_cpus() + 1;
1386 /* alloc percpu pointers for all possible cpu slots */
1387 OBD_ALLOC(stats, offsetof(struct lprocfs_stats, ls_percpu[num_entry]));
1391 stats->ls_num = num;
1392 stats->ls_biggest_alloc_num = 1;
1393 stats->ls_flags = flags;
1394 spin_lock_init(&stats->ls_lock);
1396 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1398 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1400 /* for no percpu area, the 0th entry is for real use,
1401 * for percpu area, the 0th entry is for intialized entry template */
1402 OBD_ALLOC(stats->ls_percpu[0], percpusize);
1403 if (stats->ls_percpu[0] == NULL) {
1405 offsetof(struct lprocfs_stats, ls_percpu[num_entry]));
1410 EXPORT_SYMBOL(lprocfs_alloc_stats);
1412 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1414 struct lprocfs_stats *stats = *statsh;
1415 unsigned int num_entry;
1416 unsigned int percpusize;
1419 if (stats == NULL || stats->ls_num == 0)
1423 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1426 num_entry = cfs_num_possible_cpus() + 1;
1428 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1430 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1431 for (i = 0; i < num_entry; i++)
1432 if (stats->ls_percpu[i] != NULL)
1433 OBD_FREE(stats->ls_percpu[i], percpusize);
1434 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_entry]));
1436 EXPORT_SYMBOL(lprocfs_free_stats);
1438 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1440 struct lprocfs_counter *percpu_cntr;
1443 unsigned int num_entry;
1444 unsigned long flags = 0;
1446 num_entry = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
1448 for (i = 0; i < num_entry; i++) {
1449 if (stats->ls_percpu[i] == NULL)
1451 for (j = 0; j < stats->ls_num; j++) {
1452 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1453 percpu_cntr->lc_count = 0;
1454 percpu_cntr->lc_sum = 0;
1455 percpu_cntr->lc_min = LC_MIN_INIT;
1456 percpu_cntr->lc_max = 0;
1457 percpu_cntr->lc_sumsquare = 0;
1461 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
1463 EXPORT_SYMBOL(lprocfs_clear_stats);
1465 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1466 size_t len, loff_t *off)
1468 struct seq_file *seq = file->private_data;
1469 struct lprocfs_stats *stats = seq->private;
1471 lprocfs_clear_stats(stats);
1476 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1478 struct lprocfs_stats *stats = p->private;
1479 /* return 1st cpu location */
1480 return (*pos >= stats->ls_num) ? NULL :
1481 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1484 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1488 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1490 struct lprocfs_stats *stats = p->private;
1492 return (*pos >= stats->ls_num) ? NULL :
1493 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1496 /* seq file export of one lprocfs counter */
1497 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1499 struct lprocfs_stats *stats = p->private;
1500 struct lprocfs_counter *cntr = v;
1501 struct lprocfs_counter ret;
1504 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1506 cfs_gettimeofday(&now);
1507 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1508 "snapshot_time", now.tv_sec, now.tv_usec);
1512 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1514 lprocfs_stats_collect(stats, idx, &ret);
1516 if (ret.lc_count == 0)
1519 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1520 ret.lc_count, cntr->lc_units);
1525 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1526 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1527 ret.lc_min, ret.lc_max, ret.lc_sum);
1530 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1531 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1535 rc = seq_printf(p, "\n");
1537 return (rc < 0) ? rc : 0;
1540 struct seq_operations lprocfs_stats_seq_sops = {
1541 start: lprocfs_stats_seq_start,
1542 stop: lprocfs_stats_seq_stop,
1543 next: lprocfs_stats_seq_next,
1544 show: lprocfs_stats_seq_show,
1547 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1549 struct proc_dir_entry *dp = PDE(inode);
1550 struct seq_file *seq;
1553 if (LPROCFS_ENTRY_AND_CHECK(dp))
1556 rc = seq_open(file, &lprocfs_stats_seq_sops);
1561 seq = file->private_data;
1562 seq->private = dp->data;
1566 struct file_operations lprocfs_stats_seq_fops = {
1567 .owner = THIS_MODULE,
1568 .open = lprocfs_stats_seq_open,
1570 .write = lprocfs_stats_seq_write,
1571 .llseek = seq_lseek,
1572 .release = lprocfs_seq_release,
1575 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1576 struct lprocfs_stats *stats)
1578 struct proc_dir_entry *entry;
1579 LASSERT(root != NULL);
1581 LPROCFS_WRITE_ENTRY();
1582 entry = create_proc_entry(name, 0644, root);
1584 entry->proc_fops = &lprocfs_stats_seq_fops;
1585 entry->data = stats;
1588 LPROCFS_WRITE_EXIT();
1595 EXPORT_SYMBOL(lprocfs_register_stats);
1597 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1598 unsigned conf, const char *name, const char *units)
1600 struct lprocfs_counter *c = &(stats->ls_percpu[0]->lp_cntr[index]);
1601 unsigned long flags = 0;
1603 LASSERT(stats != NULL);
1604 LASSERT(stats->ls_percpu[0] != NULL);
1606 lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
1607 c->lc_config = conf;
1610 c->lc_min = LC_MIN_INIT;
1613 c->lc_units = units;
1614 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
1616 EXPORT_SYMBOL(lprocfs_counter_init);
1618 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1620 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1621 LASSERT(coffset < stats->ls_num); \
1622 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1625 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1627 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1628 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1629 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1630 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1631 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1632 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1633 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1634 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1635 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1636 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1637 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1638 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1639 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1640 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1641 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1642 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1643 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1644 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1645 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1646 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1647 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1648 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1649 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1650 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1651 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1652 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1653 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1654 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1655 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1656 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1657 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1658 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1659 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1660 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1661 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1662 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1663 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1664 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1665 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1666 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1667 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1668 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1669 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1670 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1671 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1672 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1673 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1674 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1675 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1676 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1677 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1678 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1679 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1680 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1681 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1682 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1683 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1684 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1685 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1686 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1687 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1688 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1689 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1690 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1691 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1692 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1693 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1695 EXPORT_SYMBOL(lprocfs_init_ops_stats);
1697 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1699 struct lprocfs_stats *stats;
1700 unsigned int num_stats;
1703 LASSERT(obd->obd_stats == NULL);
1704 LASSERT(obd->obd_proc_entry != NULL);
1705 LASSERT(obd->obd_cntr_base == 0);
1707 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1708 num_private_stats - 1 /* o_owner */;
1709 stats = lprocfs_alloc_stats(num_stats, 0);
1713 lprocfs_init_ops_stats(num_private_stats, stats);
1715 for (i = num_private_stats; i < num_stats; i++) {
1716 /* If this LBUGs, it is likely that an obd
1717 * operation was added to struct obd_ops in
1718 * <obd.h>, and that the corresponding line item
1719 * LPROCFS_OBD_OP_INIT(.., .., opname)
1720 * is missing from the list above. */
1721 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1722 "Missing obd_stat initializer obd_op "
1723 "operation at offset %d.\n", i - num_private_stats);
1725 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1727 lprocfs_free_stats(&stats);
1729 obd->obd_stats = stats;
1730 obd->obd_cntr_base = num_private_stats;
1734 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
1736 void lprocfs_free_obd_stats(struct obd_device *obd)
1739 lprocfs_free_stats(&obd->obd_stats);
1741 EXPORT_SYMBOL(lprocfs_free_obd_stats);
1743 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1745 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1746 LASSERT(coffset < stats->ls_num); \
1747 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1750 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1752 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1753 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1754 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1755 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1756 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1757 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1758 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1759 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1760 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1761 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1762 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1763 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1764 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1765 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1766 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1767 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1768 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1769 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1770 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1771 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1772 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1773 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1774 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1775 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1776 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1777 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1778 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1779 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1780 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1781 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1782 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1783 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1785 EXPORT_SYMBOL(lprocfs_init_mps_stats);
1787 int lprocfs_alloc_md_stats(struct obd_device *obd,
1788 unsigned num_private_stats)
1790 struct lprocfs_stats *stats;
1791 unsigned int num_stats;
1794 LASSERT(obd->md_stats == NULL);
1795 LASSERT(obd->obd_proc_entry != NULL);
1796 LASSERT(obd->md_cntr_base == 0);
1798 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1800 stats = lprocfs_alloc_stats(num_stats, 0);
1804 lprocfs_init_mps_stats(num_private_stats, stats);
1806 for (i = num_private_stats; i < num_stats; i++) {
1807 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1808 CERROR("Missing md_stat initializer md_op "
1809 "operation at offset %d. Aborting.\n",
1810 i - num_private_stats);
1814 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1816 lprocfs_free_stats(&stats);
1818 obd->md_stats = stats;
1819 obd->md_cntr_base = num_private_stats;
1823 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
1825 void lprocfs_free_md_stats(struct obd_device *obd)
1827 struct lprocfs_stats *stats = obd->md_stats;
1829 if (stats != NULL) {
1830 obd->md_stats = NULL;
1831 obd->md_cntr_base = 0;
1832 lprocfs_free_stats(&stats);
1835 EXPORT_SYMBOL(lprocfs_free_md_stats);
1837 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1839 lprocfs_counter_init(ldlm_stats,
1840 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1841 0, "ldlm_enqueue", "reqs");
1842 lprocfs_counter_init(ldlm_stats,
1843 LDLM_CONVERT - LDLM_FIRST_OPC,
1844 0, "ldlm_convert", "reqs");
1845 lprocfs_counter_init(ldlm_stats,
1846 LDLM_CANCEL - LDLM_FIRST_OPC,
1847 0, "ldlm_cancel", "reqs");
1848 lprocfs_counter_init(ldlm_stats,
1849 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1850 0, "ldlm_bl_callback", "reqs");
1851 lprocfs_counter_init(ldlm_stats,
1852 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1853 0, "ldlm_cp_callback", "reqs");
1854 lprocfs_counter_init(ldlm_stats,
1855 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1856 0, "ldlm_gl_callback", "reqs");
1858 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
1860 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1861 int *eof, void *data)
1863 struct obd_export *exp = data;
1864 LASSERT(exp != NULL);
1866 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1869 struct exp_uuid_cb_data {
1877 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1878 int count, int *eof, int *len)
1880 cb_data->page = page;
1881 cb_data->count = count;
1886 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1887 cfs_hlist_node_t *hnode, void *cb_data)
1890 struct obd_export *exp = cfs_hash_object(hs, hnode);
1891 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1893 if (exp->exp_nid_stats)
1894 *data->len += snprintf((data->page + *data->len),
1895 data->count, "%s\n",
1896 obd_uuid2str(&exp->exp_client_uuid));
1900 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1901 int *eof, void *data)
1903 struct nid_stat *stats = (struct nid_stat *)data;
1904 struct exp_uuid_cb_data cb_data;
1905 struct obd_device *obd = stats->nid_obd;
1910 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1911 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1912 lprocfs_exp_print_uuid, &cb_data);
1913 return (*cb_data.len);
1916 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1917 cfs_hlist_node_t *hnode, void *cb_data)
1920 struct exp_uuid_cb_data *data = cb_data;
1921 struct obd_export *exp = cfs_hash_object(hs, hnode);
1923 if (exp->exp_lock_hash != NULL) {
1925 *data->len += cfs_hash_debug_header(data->page,
1928 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1935 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1936 int *eof, void *data)
1938 struct nid_stat *stats = (struct nid_stat *)data;
1939 struct exp_uuid_cb_data cb_data;
1940 struct obd_device *obd = stats->nid_obd;
1945 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1947 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1948 lprocfs_exp_print_hash, &cb_data);
1949 return (*cb_data.len);
1952 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1953 int count, int *eof, void *data)
1956 return snprintf(page, count, "%s\n",
1957 "Write into this file to clear all nid stats and "
1958 "stale nid entries");
1960 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1962 static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1964 struct nid_stat *stat = obj;
1968 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1969 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1970 /* object has only hash references. */
1971 spin_lock(&stat->nid_obd->obd_nid_lock);
1972 cfs_list_move(&stat->nid_list, data);
1973 spin_unlock(&stat->nid_obd->obd_nid_lock);
1976 /* we has reference to object - only clear data*/
1977 if (stat->nid_stats)
1978 lprocfs_clear_stats(stat->nid_stats);
1980 if (stat->nid_brw_stats) {
1981 for (i = 0; i < BRW_LAST; i++)
1982 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1987 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1988 unsigned long count, void *data)
1990 struct obd_device *obd = (struct obd_device *)data;
1991 struct nid_stat *client_stat;
1992 CFS_LIST_HEAD(free_list);
1994 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1995 lprocfs_nid_stats_clear_write_cb, &free_list);
1997 while (!cfs_list_empty(&free_list)) {
1998 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
2000 cfs_list_del_init(&client_stat->nid_list);
2001 lprocfs_free_client_stats(client_stat);
2006 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
2008 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
2010 struct nid_stat *new_stat, *old_stat;
2011 struct obd_device *obd = NULL;
2012 cfs_proc_dir_entry_t *entry;
2013 char *buffer = NULL;
2019 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
2020 !exp->exp_obd->obd_nid_stats_hash)
2023 /* not test against zero because eric say:
2024 * You may only test nid against another nid, or LNET_NID_ANY.
2025 * Anything else is nonsense.*/
2026 if (!nid || *nid == LNET_NID_ANY)
2031 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
2033 OBD_ALLOC_PTR(new_stat);
2034 if (new_stat == NULL)
2037 new_stat->nid = *nid;
2038 new_stat->nid_obd = exp->exp_obd;
2039 /* we need set default refcount to 1 to balance obd_disconnect */
2040 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
2042 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
2043 nid, &new_stat->nid_hash);
2044 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
2045 old_stat, libcfs_nid2str(*nid),
2046 cfs_atomic_read(&new_stat->nid_exp_ref_count));
2048 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
2049 * been and will never be called. */
2050 if (exp->exp_nid_stats) {
2051 nidstat_putref(exp->exp_nid_stats);
2052 exp->exp_nid_stats = NULL;
2055 /* Return -EALREADY here so that we know that the /proc
2056 * entry already has been created */
2057 if (old_stat != new_stat) {
2058 exp->exp_nid_stats = old_stat;
2059 GOTO(destroy_new, rc = -EALREADY);
2061 /* not found - create */
2062 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
2064 GOTO(destroy_new, rc = -ENOMEM);
2066 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
2067 new_stat->nid_proc = lprocfs_register(buffer,
2068 obd->obd_proc_exports_entry,
2070 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
2072 if (new_stat->nid_proc == NULL) {
2073 CERROR("Error making export directory for nid %s\n",
2074 libcfs_nid2str(*nid));
2075 GOTO(destroy_new_ns, rc = -ENOMEM);
2078 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
2079 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
2080 if (IS_ERR(entry)) {
2081 CWARN("Error adding the NID stats file\n");
2082 rc = PTR_ERR(entry);
2083 GOTO(destroy_new_ns, rc);
2086 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
2087 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
2088 if (IS_ERR(entry)) {
2089 CWARN("Error adding the hash file\n");
2090 rc = PTR_ERR(entry);
2091 GOTO(destroy_new_ns, rc);
2094 exp->exp_nid_stats = new_stat;
2096 /* protect competitive add to list, not need locking on destroy */
2097 spin_lock(&obd->obd_nid_lock);
2098 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
2099 spin_unlock(&obd->obd_nid_lock);
2104 if (new_stat->nid_proc != NULL)
2105 lprocfs_remove(&new_stat->nid_proc);
2106 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
2109 nidstat_putref(new_stat);
2110 OBD_FREE_PTR(new_stat);
2113 EXPORT_SYMBOL(lprocfs_exp_setup);
2115 int lprocfs_exp_cleanup(struct obd_export *exp)
2117 struct nid_stat *stat = exp->exp_nid_stats;
2119 if(!stat || !exp->exp_obd)
2122 nidstat_putref(exp->exp_nid_stats);
2123 exp->exp_nid_stats = NULL;
2127 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2129 int lprocfs_write_helper(const char *buffer, unsigned long count,
2132 return lprocfs_write_frac_helper(buffer, count, val, 1);
2134 EXPORT_SYMBOL(lprocfs_write_helper);
2136 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
2139 char kernbuf[20], *end, *pbuf;
2141 if (count > (sizeof(kernbuf) - 1))
2144 if (cfs_copy_from_user(kernbuf, buffer, count))
2147 kernbuf[count] = '\0';
2154 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
2158 if (end != NULL && *end == '.') {
2159 int temp_val, pow = 1;
2163 if (strlen(pbuf) > 5)
2164 pbuf[5] = '\0'; /*only allow 5bits fractional*/
2166 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
2169 for (i = 0; i < (end - pbuf); i++)
2172 *val += temp_val / pow;
2177 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2179 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
2182 long decimal_val, frac_val;
2188 decimal_val = val / mult;
2189 prtn = snprintf(buffer, count, "%ld", decimal_val);
2190 frac_val = val % mult;
2192 if (prtn < (count - 4) && frac_val > 0) {
2194 int i, temp_mult = 1, frac_bits = 0;
2196 temp_frac = frac_val * 10;
2197 buffer[prtn++] = '.';
2198 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2199 /* only reserved 2 bits fraction */
2200 buffer[prtn++] ='0';
2205 * Need to think these cases :
2206 * 1. #echo x.00 > /proc/xxx output result : x
2207 * 2. #echo x.0x > /proc/xxx output result : x.0x
2208 * 3. #echo x.x0 > /proc/xxx output result : x.x
2209 * 4. #echo x.xx > /proc/xxx output result : x.xx
2210 * Only reserved 2 bits fraction.
2212 for (i = 0; i < (5 - prtn); i++)
2215 frac_bits = min((int)count - prtn, 3 - frac_bits);
2216 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2217 frac_val * temp_mult / mult);
2220 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2222 if (buffer[prtn] == '.') {
2229 buffer[prtn++] ='\n';
2232 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2234 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2236 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2238 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2240 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2241 __u64 *val, int mult)
2243 char kernbuf[22], *end, *pbuf;
2244 __u64 whole, frac = 0, units;
2245 unsigned frac_d = 1;
2247 if (count > (sizeof(kernbuf) - 1))
2250 if (cfs_copy_from_user(kernbuf, buffer, count))
2253 kernbuf[count] = '\0';
2260 whole = simple_strtoull(pbuf, &end, 10);
2264 if (end != NULL && *end == '.') {
2268 /* need to limit frac_d to a __u32 */
2269 if (strlen(pbuf) > 10)
2272 frac = simple_strtoull(pbuf, &end, 10);
2273 /* count decimal places */
2274 for (i = 0; i < (end - pbuf); i++)
2291 /* Specified units override the multiplier */
2293 mult = mult < 0 ? -units : units;
2296 do_div(frac, frac_d);
2297 *val = whole * mult + frac;
2300 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2302 static char *lprocfs_strnstr(const char *s1, const char *s2, size_t len)
2311 if (!memcmp(s1, s2, l2))
2319 * Find the string \a name in the input \a buffer, and return a pointer to the
2320 * value immediately following \a name, reducing \a count appropriately.
2321 * If \a name is not found the original \a buffer is returned.
2323 char *lprocfs_find_named_value(const char *buffer, const char *name,
2324 unsigned long *count)
2327 size_t buflen = *count;
2329 /* there is no strnstr() in rhel5 and ubuntu kernels */
2330 val = lprocfs_strnstr(buffer, name, buflen);
2332 return (char *)buffer;
2334 val += strlen(name); /* skip prefix */
2335 while (val < buffer + buflen && isspace(*val)) /* skip separator */
2339 while (val < buffer + buflen && isalnum(*val)) {
2344 return val - *count;
2346 EXPORT_SYMBOL(lprocfs_find_named_value);
2348 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent,
2351 const struct file_operations *seq_fops,
2354 struct proc_dir_entry *entry;
2357 LPROCFS_WRITE_ENTRY();
2358 entry = create_proc_entry(name, mode, parent);
2360 entry->proc_fops = seq_fops;
2363 LPROCFS_WRITE_EXIT();
2370 EXPORT_SYMBOL(lprocfs_seq_create);
2372 int lprocfs_obd_seq_create(struct obd_device *dev,
2375 const struct file_operations *seq_fops,
2378 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2379 mode, seq_fops, data));
2381 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2383 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2385 if (value >= OBD_HIST_MAX)
2386 value = OBD_HIST_MAX - 1;
2388 spin_lock(&oh->oh_lock);
2389 oh->oh_buckets[value]++;
2390 spin_unlock(&oh->oh_lock);
2392 EXPORT_SYMBOL(lprocfs_oh_tally);
2394 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2398 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2401 lprocfs_oh_tally(oh, val);
2403 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2405 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2407 unsigned long ret = 0;
2410 for (i = 0; i < OBD_HIST_MAX; i++)
2411 ret += oh->oh_buckets[i];
2414 EXPORT_SYMBOL(lprocfs_oh_sum);
2416 void lprocfs_oh_clear(struct obd_histogram *oh)
2418 spin_lock(&oh->oh_lock);
2419 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2420 spin_unlock(&oh->oh_lock);
2422 EXPORT_SYMBOL(lprocfs_oh_clear);
2424 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2425 int count, int *eof, void *data)
2427 struct obd_device *obd = data;
2433 c += cfs_hash_debug_header(page, count);
2434 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2435 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2436 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2440 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2442 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2443 int count, int *eof, void *data)
2445 struct obd_device *obd = data;
2448 LASSERT(obd != NULL);
2449 LASSERT(count >= 0);
2451 /* Set start of user data returned to
2452 page + off since the user may have
2453 requested to read much smaller than
2454 what we need to read */
2455 *start = page + off;
2457 /* We know we are allocated a page here.
2458 Also we know that this function will
2459 not need to write more than a page
2460 so we can truncate at CFS_PAGE_SIZE. */
2461 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2463 /* Initialize the page */
2464 memset(page, 0, size);
2466 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2468 if (obd->obd_max_recoverable_clients == 0) {
2469 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2475 /* sampled unlocked, but really... */
2476 if (obd->obd_recovering == 0) {
2477 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2479 if (lprocfs_obd_snprintf(&page, size, &len,
2480 "recovery_start: %lu\n",
2481 obd->obd_recovery_start) <= 0)
2483 if (lprocfs_obd_snprintf(&page, size, &len,
2484 "recovery_duration: %lu\n",
2485 obd->obd_recovery_end -
2486 obd->obd_recovery_start) <= 0)
2488 /* Number of clients that have completed recovery */
2489 if (lprocfs_obd_snprintf(&page, size, &len,
2490 "completed_clients: %d/%d\n",
2491 obd->obd_max_recoverable_clients -
2492 obd->obd_stale_clients,
2493 obd->obd_max_recoverable_clients) <= 0)
2495 if (lprocfs_obd_snprintf(&page, size, &len,
2496 "replayed_requests: %d\n",
2497 obd->obd_replayed_requests) <= 0)
2499 if (lprocfs_obd_snprintf(&page, size, &len,
2500 "last_transno: "LPD64"\n",
2501 obd->obd_next_recovery_transno - 1)<=0)
2503 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2504 obd->obd_version_recov ?
2505 "ENABLED" : "DISABLED") <=0)
2507 if (lprocfs_obd_snprintf(&page, size, &len, "IR: %s\n",
2509 "DISABLED" : "ENABLED") <= 0)
2514 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2516 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2517 obd->obd_recovery_start) <= 0)
2519 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2520 cfs_time_current_sec() >=
2521 obd->obd_recovery_start +
2522 obd->obd_recovery_timeout ? 0 :
2523 obd->obd_recovery_start +
2524 obd->obd_recovery_timeout -
2525 cfs_time_current_sec()) <= 0)
2527 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2528 cfs_atomic_read(&obd->obd_connected_clients),
2529 obd->obd_max_recoverable_clients) <= 0)
2531 /* Number of clients that have completed recovery */
2532 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2533 cfs_atomic_read(&obd->obd_req_replay_clients))
2536 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2537 cfs_atomic_read(&obd->obd_lock_replay_clients))
2540 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2541 cfs_atomic_read(&obd->obd_connected_clients) -
2542 cfs_atomic_read(&obd->obd_lock_replay_clients))
2545 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2546 obd->obd_stale_clients) <= 0)
2548 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2549 obd->obd_replayed_requests) <= 0)
2551 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2552 obd->obd_requests_queued_for_recovery) <= 0)
2555 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2556 obd->obd_next_recovery_transno) <= 0)
2562 return min(count, len - (int)off);
2564 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2566 int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off,
2567 int count, int *eof, void *data)
2569 struct obd_device *obd = (struct obd_device *)data;
2570 LASSERT(obd != NULL);
2572 return snprintf(page, count, "%d\n",
2573 obd->obd_recovery_ir_factor);
2575 EXPORT_SYMBOL(lprocfs_obd_rd_ir_factor);
2577 int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer,
2578 unsigned long count, void *data)
2580 struct obd_device *obd = (struct obd_device *)data;
2582 LASSERT(obd != NULL);
2584 rc = lprocfs_write_helper(buffer, count, &val);
2588 if (val < OBD_IR_FACTOR_MIN || val > OBD_IR_FACTOR_MAX)
2591 obd->obd_recovery_ir_factor = val;
2594 EXPORT_SYMBOL(lprocfs_obd_wr_ir_factor);
2596 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2597 int count, int *eof, void *data)
2599 struct obd_device *obd = (struct obd_device *)data;
2600 LASSERT(obd != NULL);
2602 return snprintf(page, count, "%d\n",
2603 obd->obd_recovery_timeout);
2605 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2607 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2608 unsigned long count, void *data)
2610 struct obd_device *obd = (struct obd_device *)data;
2612 LASSERT(obd != NULL);
2614 rc = lprocfs_write_helper(buffer, count, &val);
2618 obd->obd_recovery_timeout = val;
2621 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2623 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2624 int count, int *eof, void *data)
2626 struct obd_device *obd = data;
2627 LASSERT(obd != NULL);
2629 return snprintf(page, count, "%u\n", obd->obd_recovery_time_hard);
2631 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2633 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2634 unsigned long count, void *data)
2636 struct obd_device *obd = data;
2638 LASSERT(obd != NULL);
2640 rc = lprocfs_write_helper(buffer, count, &val);
2644 obd->obd_recovery_time_hard = val;
2647 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2649 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2650 int count, int *eof, void *data)
2652 struct obd_device *obd = (struct obd_device *)data;
2654 LASSERT(obd != NULL);
2655 LASSERT(mnt_get_devname(obd->u.obt.obt_vfsmnt));
2657 return snprintf(page, count, "%s\n",
2658 mnt_get_devname(obd->u.obt.obt_vfsmnt));
2660 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2662 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2663 int count, int *eof, void *data)
2665 struct obd_device *dev = data;
2666 struct client_obd *cli = &dev->u.cli;
2669 client_obd_list_lock(&cli->cl_loi_list_lock);
2670 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2671 client_obd_list_unlock(&cli->cl_loi_list_lock);
2674 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2676 int lprocfs_target_rd_instance(char *page, char **start, off_t off,
2677 int count, int *eof, void *data)
2679 struct obd_device *obd = (struct obd_device *)data;
2680 struct obd_device_target *target = &obd->u.obt;
2682 LASSERT(obd != NULL);
2683 LASSERT(target->obt_magic == OBT_MAGIC);
2685 return snprintf(page, count, "%u\n", obd->u.obt.obt_instance);
2687 EXPORT_SYMBOL(lprocfs_target_rd_instance);