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 CFS_DECLARE_RWSEM(_lprocfs_lock);
64 EXPORT_SYMBOL(_lprocfs_lock);
66 int lprocfs_seq_release(struct inode *inode, struct file *file)
69 return seq_release(inode, file);
71 EXPORT_SYMBOL(lprocfs_seq_release);
73 static struct proc_dir_entry *__lprocfs_srch(struct proc_dir_entry *head,
76 struct proc_dir_entry *temp;
82 while (temp != NULL) {
83 if (strcmp(temp->name, name) == 0) {
92 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
95 struct proc_dir_entry *temp;
98 temp = __lprocfs_srch(head, name);
103 /* lprocfs API calls */
105 /* Function that emulates snprintf but also has the side effect of advancing
106 the page pointer for the next write into the buffer, incrementing the total
107 length written to the buffer, and decrementing the size left in the
109 static int lprocfs_obd_snprintf(char **page, int end, int *len,
110 const char *format, ...)
118 va_start(list, format);
119 n = vsnprintf(*page, end - *len, format, list);
122 *page += n; *len += n;
126 cfs_proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
128 read_proc_t *read_proc,
129 write_proc_t *write_proc,
131 struct file_operations *fops)
133 cfs_proc_dir_entry_t *proc;
136 if (root == NULL || name == NULL)
137 return ERR_PTR(-EINVAL);
144 LPROCFS_WRITE_ENTRY();
145 proc = create_proc_entry(name, mode, root);
147 CERROR("LprocFS: No memory to create /proc entry %s", name);
148 LPROCFS_WRITE_EXIT();
149 return ERR_PTR(-ENOMEM);
151 proc->read_proc = read_proc;
152 proc->write_proc = write_proc;
155 proc->proc_fops = fops;
156 LPROCFS_WRITE_EXIT();
160 struct proc_dir_entry *lprocfs_add_symlink(const char *name,
161 struct proc_dir_entry *parent, const char *format, ...)
163 struct proc_dir_entry *entry;
167 if (parent == NULL || format == NULL)
170 OBD_ALLOC_WAIT(dest, MAX_STRING_SIZE + 1);
174 va_start(ap, format);
175 vsnprintf(dest, MAX_STRING_SIZE, format, ap);
178 entry = proc_symlink(name, parent, dest);
180 CERROR("LprocFS: Could not create symbolic link from %s to %s",
183 OBD_FREE(dest, MAX_STRING_SIZE + 1);
187 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
188 size_t size, loff_t *ppos)
190 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
191 char *page, *start = NULL;
192 int rc = 0, eof = 1, count;
194 if (*ppos >= CFS_PAGE_SIZE)
197 page = (char *)__get_free_page(GFP_KERNEL);
201 if (LPROCFS_ENTRY_AND_CHECK(dp)) {
206 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
208 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
214 /* for lustre proc read, the read count must be less than PAGE_SIZE */
223 start = page + *ppos;
224 } else if (start < page) {
228 count = (rc < size) ? rc : size;
229 if (cfs_copy_to_user(buf, start, count)) {
236 free_page((unsigned long)page);
240 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
241 size_t size, loff_t *ppos)
243 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
246 if (LPROCFS_ENTRY_AND_CHECK(dp))
249 rc = dp->write_proc(f, buf, size, dp->data);
254 static struct file_operations lprocfs_generic_fops = {
255 .owner = THIS_MODULE,
256 .read = lprocfs_fops_read,
257 .write = lprocfs_fops_write,
260 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
262 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
263 struct obd_device *obd = dp->data;
265 cfs_atomic_inc(&obd->obd_evict_inprogress);
270 int lprocfs_evict_client_release(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_dec(&obd->obd_evict_inprogress);
276 cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
281 struct file_operations lprocfs_evict_client_fops = {
282 .owner = THIS_MODULE,
283 .read = lprocfs_fops_read,
284 .write = lprocfs_fops_write,
285 .open = lprocfs_evict_client_open,
286 .release = lprocfs_evict_client_release,
288 EXPORT_SYMBOL(lprocfs_evict_client_fops);
293 * \param root [in] The parent proc entry on which new entry will be added.
294 * \param list [in] Array of proc entries to be added.
295 * \param data [in] The argument to be passed when entries read/write routines
296 * are called through /proc file.
298 * \retval 0 on success
301 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
306 if (root == NULL || list == NULL)
309 LPROCFS_WRITE_ENTRY();
310 while (list->name != NULL) {
311 struct proc_dir_entry *cur_root, *proc;
312 char *pathcopy, *cur, *next, pathbuf[64];
313 int pathsize = strlen(list->name) + 1;
318 /* need copy of path for strsep */
319 if (strlen(list->name) > sizeof(pathbuf) - 1) {
320 OBD_ALLOC(pathcopy, pathsize);
321 if (pathcopy == NULL)
322 GOTO(out, rc = -ENOMEM);
328 strcpy(pathcopy, list->name);
330 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
331 if (*cur =='\0') /* skip double/trailing "/" */
334 proc = __lprocfs_srch(cur_root, cur);
335 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
336 cur_root->name, cur, next,
337 (proc ? "exists" : "new"));
339 cur_root = (proc ? proc :
340 proc_mkdir(cur, cur_root));
341 } else if (proc == NULL) {
343 if (list->proc_mode != 0000) {
344 mode = list->proc_mode;
348 if (list->write_fptr)
351 proc = create_proc_entry(cur, mode, cur_root);
355 if (pathcopy != pathbuf)
356 OBD_FREE(pathcopy, pathsize);
358 if (cur_root == NULL || proc == NULL) {
359 CERROR("LprocFS: No memory to create /proc entry %s",
361 GOTO(out, rc = -ENOMEM);
365 proc->proc_fops = list->fops;
367 proc->proc_fops = &lprocfs_generic_fops;
368 proc->read_proc = list->read_fptr;
369 proc->write_proc = list->write_fptr;
370 proc->data = (list->data ? list->data : data);
374 LPROCFS_WRITE_EXIT();
378 void lprocfs_remove(struct proc_dir_entry **rooth)
380 struct proc_dir_entry *root = *rooth;
381 struct proc_dir_entry *temp = root;
382 struct proc_dir_entry *rm_entry;
383 struct proc_dir_entry *parent;
389 parent = root->parent;
390 LASSERT(parent != NULL);
391 LPROCFS_WRITE_ENTRY(); /* search vs remove race */
394 while (temp->subdir != NULL)
400 /* Memory corruption once caused this to fail, and
401 without this LASSERT we would loop here forever. */
402 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
403 "0x%p %s/%s len %d\n", rm_entry, temp->name,
404 rm_entry->name, (int)strlen(rm_entry->name));
406 #ifdef HAVE_PROCFS_USERS
407 /* if procfs uses user count to synchronize deletion of
408 * proc entry, there is no protection for rm_entry->data,
409 * then lprocfs_fops_read and lprocfs_fops_write maybe
410 * call proc_dir_entry->read_proc (or write_proc) with
411 * proc_dir_entry->data == NULL, then cause kernel Oops.
412 * see bug19706 for detailed information */
414 /* procfs won't free rm_entry->data if it isn't a LINK,
415 * and Lustre won't use rm_entry->data if it is a LINK */
416 if (S_ISLNK(rm_entry->mode))
417 rm_entry->data = NULL;
419 /* Now, the rm_entry->deleted flags is protected
420 * by _lprocfs_lock. */
421 rm_entry->data = NULL;
423 remove_proc_entry(rm_entry->name, temp);
427 LPROCFS_WRITE_EXIT();
430 void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
432 LASSERT(parent != NULL);
433 remove_proc_entry(name, parent);
436 struct proc_dir_entry *lprocfs_register(const char *name,
437 struct proc_dir_entry *parent,
438 struct lprocfs_vars *list, void *data)
440 struct proc_dir_entry *newchild;
442 newchild = lprocfs_srch(parent, name);
443 if (newchild != NULL) {
444 CERROR(" Lproc: Attempting to register %s more than once \n",
446 return ERR_PTR(-EALREADY);
449 newchild = proc_mkdir(name, parent);
450 if (newchild != NULL && list != NULL) {
451 int rc = lprocfs_add_vars(newchild, list, data);
453 lprocfs_remove(&newchild);
460 /* Generic callbacks */
461 int lprocfs_rd_uint(char *page, char **start, off_t off,
462 int count, int *eof, void *data)
464 unsigned int *temp = data;
465 return snprintf(page, count, "%u\n", *temp);
468 int lprocfs_wr_uint(struct file *file, const char *buffer,
469 unsigned long count, void *data)
472 char dummy[MAX_STRING_SIZE + 1], *end;
475 dummy[MAX_STRING_SIZE] = '\0';
476 if (cfs_copy_from_user(dummy, buffer, MAX_STRING_SIZE))
479 tmp = simple_strtoul(dummy, &end, 0);
483 *p = (unsigned int)tmp;
487 int lprocfs_rd_u64(char *page, char **start, off_t off,
488 int count, int *eof, void *data)
490 LASSERT(data != NULL);
492 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
495 int lprocfs_rd_atomic(char *page, char **start, off_t off,
496 int count, int *eof, void *data)
498 cfs_atomic_t *atom = data;
499 LASSERT(atom != NULL);
501 return snprintf(page, count, "%d\n", cfs_atomic_read(atom));
504 int lprocfs_wr_atomic(struct file *file, const char *buffer,
505 unsigned long count, void *data)
507 cfs_atomic_t *atm = data;
511 rc = lprocfs_write_helper(buffer, count, &val);
518 cfs_atomic_set(atm, val);
522 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
523 int *eof, void *data)
525 struct obd_device *obd = data;
527 LASSERT(obd != NULL);
529 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
532 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
533 int *eof, void *data)
535 struct obd_device *dev = data;
537 LASSERT(dev != NULL);
538 LASSERT(dev->obd_name != NULL);
540 return snprintf(page, count, "%s\n", dev->obd_name);
543 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
546 struct obd_device *obd = data;
548 LASSERT(obd != NULL);
549 LASSERT(obd->obd_fsops != NULL);
550 LASSERT(obd->obd_fsops->fs_type != NULL);
551 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
554 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
555 int *eof, void *data)
557 struct obd_device *obd = data;
558 struct obd_statfs osfs;
559 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
560 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
564 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
569 int lprocfs_osd_rd_blksize(char *page, char **start, off_t off,
570 int count, int *eof, void *data)
572 struct dt_device *dt = data;
573 struct obd_statfs osfs;
574 int rc = dt_statfs(NULL, dt, &osfs);
577 rc = snprintf(page, count, "%d\n",
578 (unsigned) osfs.os_bsize);
582 EXPORT_SYMBOL(lprocfs_osd_rd_blksize);
584 int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
585 int *eof, void *data)
587 struct obd_device *obd = data;
588 struct obd_statfs osfs;
589 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
590 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
593 __u32 blk_size = osfs.os_bsize >> 10;
594 __u64 result = osfs.os_blocks;
596 while (blk_size >>= 1)
600 rc = snprintf(page, count, LPU64"\n", result);
605 int lprocfs_osd_rd_kbytestotal(char *page, char **start, off_t off,
606 int count, int *eof, void *data)
608 struct dt_device *dt = data;
609 struct obd_statfs osfs;
610 int rc = dt_statfs(NULL, dt, &osfs);
612 __u32 blk_size = osfs.os_bsize >> 10;
613 __u64 result = osfs.os_blocks;
615 while (blk_size >>= 1)
619 rc = snprintf(page, count, LPU64"\n", result);
623 EXPORT_SYMBOL(lprocfs_osd_rd_kbytestotal);
625 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
626 int *eof, void *data)
628 struct obd_device *obd = data;
629 struct obd_statfs osfs;
630 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
631 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
634 __u32 blk_size = osfs.os_bsize >> 10;
635 __u64 result = osfs.os_bfree;
637 while (blk_size >>= 1)
641 rc = snprintf(page, count, LPU64"\n", result);
646 int lprocfs_osd_rd_kbytesfree(char *page, char **start, off_t off,
647 int count, int *eof, void *data)
649 struct dt_device *dt = data;
650 struct obd_statfs osfs;
651 int rc = dt_statfs(NULL, dt, &osfs);
653 __u32 blk_size = osfs.os_bsize >> 10;
654 __u64 result = osfs.os_bfree;
656 while (blk_size >>= 1)
660 rc = snprintf(page, count, LPU64"\n", result);
664 EXPORT_SYMBOL(lprocfs_osd_rd_kbytesfree);
666 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
667 int *eof, void *data)
669 struct obd_device *obd = data;
670 struct obd_statfs osfs;
671 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
672 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
675 __u32 blk_size = osfs.os_bsize >> 10;
676 __u64 result = osfs.os_bavail;
678 while (blk_size >>= 1)
682 rc = snprintf(page, count, LPU64"\n", result);
687 int lprocfs_osd_rd_kbytesavail(char *page, char **start, off_t off,
688 int count, int *eof, void *data)
690 struct dt_device *dt = data;
691 struct obd_statfs osfs;
692 int rc = dt_statfs(NULL, dt, &osfs);
694 __u32 blk_size = osfs.os_bsize >> 10;
695 __u64 result = osfs.os_bavail;
697 while (blk_size >>= 1)
701 rc = snprintf(page, count, LPU64"\n", result);
705 EXPORT_SYMBOL(lprocfs_osd_rd_kbytesavail);
707 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
708 int *eof, void *data)
710 struct obd_device *obd = data;
711 struct obd_statfs osfs;
712 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
713 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
717 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
723 int lprocfs_osd_rd_filestotal(char *page, char **start, off_t off,
724 int count, int *eof, void *data)
726 struct dt_device *dt = data;
727 struct obd_statfs osfs;
728 int rc = dt_statfs(NULL, dt, &osfs);
731 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
736 EXPORT_SYMBOL(lprocfs_osd_rd_filestotal);
738 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
739 int *eof, void *data)
741 struct obd_device *obd = data;
742 struct obd_statfs osfs;
743 int rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
744 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
748 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
753 int lprocfs_osd_rd_filesfree(char *page, char **start, off_t off,
754 int count, int *eof, void *data)
756 struct dt_device *dt = data;
757 struct obd_statfs osfs;
758 int rc = dt_statfs(NULL, dt, &osfs);
761 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
765 EXPORT_SYMBOL(lprocfs_osd_rd_filesfree);
767 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
768 int *eof, void *data)
770 struct obd_device *obd = data;
771 struct obd_import *imp;
772 char *imp_state_name = NULL;
775 LASSERT(obd != NULL);
776 LPROCFS_CLIMP_CHECK(obd);
777 imp = obd->u.cli.cl_import;
778 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
780 rc = snprintf(page, count, "%s\t%s%s\n",
781 obd2cli_tgt(obd), imp_state_name,
782 imp->imp_deactive ? "\tDEACTIVATED" : "");
784 LPROCFS_CLIMP_EXIT(obd);
788 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
789 int *eof, void *data)
791 struct obd_device *obd = data;
792 struct ptlrpc_connection *conn;
795 LASSERT(obd != NULL);
797 LPROCFS_CLIMP_CHECK(obd);
798 conn = obd->u.cli.cl_import->imp_connection;
800 if (conn && obd->u.cli.cl_import) {
801 rc = snprintf(page, count, "%s\n",
802 conn->c_remote_uuid.uuid);
804 rc = snprintf(page, count, "%s\n", "<none>");
807 LPROCFS_CLIMP_EXIT(obd);
811 /** add up per-cpu counters */
812 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
813 struct lprocfs_counter *cnt)
815 unsigned int num_entry;
816 struct lprocfs_counter t;
817 struct lprocfs_counter *percpu_cntr;
820 unsigned long flags = 0;
822 memset(cnt, 0, sizeof(*cnt));
825 /* set count to 1 to avoid divide-by-zero errs in callers */
830 cnt->lc_min = LC_MIN_INIT;
832 num_entry = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
834 for (i = 0; i < num_entry; i++) {
835 if (stats->ls_percpu[i] == NULL)
837 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
840 centry = cfs_atomic_read(&percpu_cntr-> \
842 t.lc_count = percpu_cntr->lc_count;
843 t.lc_sum = percpu_cntr->lc_sum;
844 t.lc_min = percpu_cntr->lc_min;
845 t.lc_max = percpu_cntr->lc_max;
846 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
847 } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
849 centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
851 cnt->lc_count += t.lc_count;
852 cnt->lc_sum += t.lc_sum;
853 if (t.lc_min < cnt->lc_min)
854 cnt->lc_min = t.lc_min;
855 if (t.lc_max > cnt->lc_max)
856 cnt->lc_max = t.lc_max;
857 cnt->lc_sumsquare += t.lc_sumsquare;
860 cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
861 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
865 * Append a space separated list of current set flags to str.
867 #define flag2str(flag) \
868 if (imp->imp_##flag && max - len > 0) \
869 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
870 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
874 if (imp->imp_obd->obd_no_recov)
875 len += snprintf(str, max - len, "no_recov");
879 flag2str(replayable);
885 static const char *obd_connect_names[] = {
899 "join_file(obsolete)",
903 "remote_client_by_force",
912 "mds_mds_connection",
915 "alt_checksum_algorithm",
934 int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
939 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
941 ret += snprintf(page + ret, count - ret, "%s%s",
942 ret ? sep : "", obd_connect_names[i]);
944 if (flags & ~(mask - 1))
945 ret += snprintf(page + ret, count - ret,
946 "%sunknown flags "LPX64,
947 ret ? sep : "", flags & ~(mask - 1));
950 EXPORT_SYMBOL(obd_connect_flags2str);
952 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
953 int *eof, void *data)
955 struct lprocfs_counter ret;
956 struct obd_device *obd = (struct obd_device *)data;
957 struct obd_import *imp;
958 struct obd_import_conn *conn;
961 LASSERT(obd != NULL);
962 LPROCFS_CLIMP_CHECK(obd);
963 imp = obd->u.cli.cl_import;
966 i = snprintf(page, count,
975 ptlrpc_import_state_name(imp->imp_state),
976 imp->imp_connect_data.ocd_instance);
977 i += obd_connect_flags2str(page + i, count - i,
978 imp->imp_connect_data.ocd_connect_flags,
980 i += snprintf(page + i, count - i,
983 i += obd_import_flags2str(imp, page + i, count - i);
985 i += snprintf(page + i, count - i,
988 " failover_nids: [");
989 cfs_spin_lock(&imp->imp_lock);
991 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
992 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
993 libcfs_nid2str(conn->oic_conn->c_peer.nid));
996 i += snprintf(page + i, count - i,
998 " current_connection: %s\n"
999 " connection_attempts: %u\n"
1001 " in-progress_invalidations: %u\n",
1002 imp->imp_connection == NULL ? "<none>" :
1003 libcfs_nid2str(imp->imp_connection->c_peer.nid),
1005 imp->imp_generation,
1006 cfs_atomic_read(&imp->imp_inval_count));
1007 cfs_spin_unlock(&imp->imp_lock);
1009 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
1010 if (ret.lc_count != 0) {
1011 /* first argument to do_div MUST be __u64 */
1012 __u64 sum = ret.lc_sum;
1013 do_div(sum, ret.lc_count);
1017 i += snprintf(page + i, count - i,
1020 " unregistering: %u\n"
1022 " avg_waittime: "LPU64" %s\n",
1023 cfs_atomic_read(&imp->imp_inflight),
1024 cfs_atomic_read(&imp->imp_unregistering),
1025 cfs_atomic_read(&imp->imp_timeouts),
1026 ret.lc_sum, ret.lc_units);
1029 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
1030 if (imp->imp_at.iat_portal[j] == 0)
1032 k = max_t(unsigned int, k,
1033 at_get(&imp->imp_at.iat_service_estimate[j]));
1035 i += snprintf(page + i, count - i,
1036 " service_estimates:\n"
1037 " services: %u sec\n"
1038 " network: %u sec\n",
1040 at_get(&imp->imp_at.iat_net_latency));
1042 i += snprintf(page + i, count - i,
1044 " last_replay: "LPU64"\n"
1045 " peer_committed: "LPU64"\n"
1046 " last_checked: "LPU64"\n",
1047 imp->imp_last_replay_transno,
1048 imp->imp_peer_committed_transno,
1049 imp->imp_last_transno_checked);
1051 /* avg data rates */
1052 for (rw = 0; rw <= 1; rw++) {
1053 lprocfs_stats_collect(obd->obd_svc_stats,
1054 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
1056 if (ret.lc_sum > 0 && ret.lc_count > 0) {
1057 /* first argument to do_div MUST be __u64 */
1058 __u64 sum = ret.lc_sum;
1059 do_div(sum, ret.lc_count);
1061 i += snprintf(page + i, count - i,
1062 " %s_data_averages:\n"
1063 " bytes_per_rpc: "LPU64"\n",
1064 rw ? "write" : "read",
1067 k = (int)ret.lc_sum;
1068 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
1069 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
1070 if (ret.lc_sum > 0 && ret.lc_count != 0) {
1071 /* first argument to do_div MUST be __u64 */
1072 __u64 sum = ret.lc_sum;
1073 do_div(sum, ret.lc_count);
1075 i += snprintf(page + i, count - i,
1076 " %s_per_rpc: "LPU64"\n",
1077 ret.lc_units, ret.lc_sum);
1078 j = (int)ret.lc_sum;
1080 i += snprintf(page + i, count - i,
1081 " MB_per_sec: %u.%.02u\n",
1082 k / j, (100 * k / j) % 100);
1086 LPROCFS_CLIMP_EXIT(obd);
1090 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
1091 int *eof, void *data)
1093 struct obd_device *obd = (struct obd_device *)data;
1094 struct obd_import *imp;
1097 LASSERT(obd != NULL);
1098 LPROCFS_CLIMP_CHECK(obd);
1099 imp = obd->u.cli.cl_import;
1102 i = snprintf(page, count, "current_state: %s\n",
1103 ptlrpc_import_state_name(imp->imp_state));
1104 i += snprintf(page + i, count - i,
1105 "state_history:\n");
1106 k = imp->imp_state_hist_idx;
1107 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
1108 struct import_state_hist *ish =
1109 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
1110 if (ish->ish_state == 0)
1112 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
1114 ptlrpc_import_state_name(ish->ish_state));
1117 LPROCFS_CLIMP_EXIT(obd);
1121 int lprocfs_at_hist_helper(char *page, int count, int rc,
1122 struct adaptive_timeout *at)
1125 for (i = 0; i < AT_BINS; i++)
1126 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1127 rc += snprintf(page + rc, count - rc, "\n");
1131 /* See also ptlrpc_lprocfs_rd_timeouts */
1132 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1133 int *eof, void *data)
1135 struct obd_device *obd = (struct obd_device *)data;
1136 struct obd_import *imp;
1137 unsigned int cur, worst;
1142 LASSERT(obd != NULL);
1143 LPROCFS_CLIMP_CHECK(obd);
1144 imp = obd->u.cli.cl_import;
1147 now = cfs_time_current_sec();
1149 /* Some network health info for kicks */
1150 s2dhms(&ts, now - imp->imp_last_reply_time);
1151 rc += snprintf(page + rc, count - rc,
1152 "%-10s : %ld, "DHMS_FMT" ago\n",
1153 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1155 cur = at_get(&imp->imp_at.iat_net_latency);
1156 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1157 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1158 s2dhms(&ts, now - worstt);
1159 rc += snprintf(page + rc, count - rc,
1160 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1161 "network", cur, worst, worstt, DHMS_VARS(&ts));
1162 rc = lprocfs_at_hist_helper(page, count, rc,
1163 &imp->imp_at.iat_net_latency);
1165 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1166 if (imp->imp_at.iat_portal[i] == 0)
1168 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1169 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1170 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1171 s2dhms(&ts, now - worstt);
1172 rc += snprintf(page + rc, count - rc,
1173 "portal %-2d : cur %3u worst %3u (at %ld, "
1174 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1175 cur, worst, worstt, DHMS_VARS(&ts));
1176 rc = lprocfs_at_hist_helper(page, count, rc,
1177 &imp->imp_at.iat_service_estimate[i]);
1180 LPROCFS_CLIMP_EXIT(obd);
1184 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1185 int count, int *eof, void *data)
1187 struct obd_device *obd = data;
1191 LPROCFS_CLIMP_CHECK(obd);
1192 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1193 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1194 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1195 ret += snprintf(page + ret, count - ret, "\n");
1196 LPROCFS_CLIMP_EXIT(obd);
1199 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1201 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1202 int *eof, void *data)
1204 struct obd_device *obd = data;
1206 LASSERT(obd != NULL);
1208 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1211 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1212 int *eof, void *data)
1214 struct obd_type *class = (struct obd_type*) data;
1216 LASSERT(class != NULL);
1218 return snprintf(page, count, "%d\n", class->typ_refcnt);
1221 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1225 LASSERT(obd != NULL);
1226 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1227 LASSERT(obd->obd_type->typ_procroot != NULL);
1229 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1230 obd->obd_type->typ_procroot,
1232 if (IS_ERR(obd->obd_proc_entry)) {
1233 rc = PTR_ERR(obd->obd_proc_entry);
1234 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1235 obd->obd_proc_entry = NULL;
1240 int lprocfs_obd_cleanup(struct obd_device *obd)
1244 if (obd->obd_proc_exports_entry) {
1245 /* Should be no exports left */
1246 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1247 lprocfs_remove(&obd->obd_proc_exports_entry);
1248 obd->obd_proc_exports_entry = NULL;
1250 if (obd->obd_proc_entry) {
1251 lprocfs_remove(&obd->obd_proc_entry);
1252 obd->obd_proc_entry = NULL;
1257 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1259 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1260 client_stat->nid_proc, client_stat->nid_stats,
1261 client_stat->nid_brw_stats);
1263 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1264 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1265 atomic_read(&client_stat->nid_exp_ref_count));
1267 if (client_stat->nid_proc)
1268 lprocfs_remove(&client_stat->nid_proc);
1270 if (client_stat->nid_stats)
1271 lprocfs_free_stats(&client_stat->nid_stats);
1273 if (client_stat->nid_brw_stats)
1274 OBD_FREE_PTR(client_stat->nid_brw_stats);
1276 if (client_stat->nid_ldlm_stats)
1277 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1279 OBD_FREE_PTR(client_stat);
1284 void lprocfs_free_per_client_stats(struct obd_device *obd)
1286 cfs_hash_t *hash = obd->obd_nid_stats_hash;
1287 struct nid_stat *stat;
1290 /* we need extra list - because hash_exit called to early */
1291 /* not need locking because all clients is died */
1292 while (!cfs_list_empty(&obd->obd_nid_stats)) {
1293 stat = cfs_list_entry(obd->obd_nid_stats.next,
1294 struct nid_stat, nid_list);
1295 cfs_list_del_init(&stat->nid_list);
1296 cfs_hash_del(hash, &stat->nid, &stat->nid_hash);
1297 lprocfs_free_client_stats(stat);
1302 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1303 enum lprocfs_stats_flags flags)
1305 struct lprocfs_stats *stats;
1306 unsigned int percpusize;
1307 unsigned int num_entry;
1312 if (lprocfs_no_percpu_stats != 0)
1313 flags |= LPROCFS_STATS_FLAG_NOPERCPU;
1315 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1318 num_entry = cfs_num_possible_cpus() + 1;
1320 /* alloc percpu pointers for all possible cpu slots */
1321 OBD_ALLOC(stats, offsetof(struct lprocfs_stats, ls_percpu[num_entry]));
1325 stats->ls_num = num;
1326 stats->ls_biggest_alloc_num = 1;
1327 stats->ls_flags = flags;
1328 cfs_spin_lock_init(&stats->ls_lock);
1330 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1332 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1334 /* for no percpu area, the 0th entry is for real use,
1335 * for percpu area, the 0th entry is for intialized entry template */
1336 OBD_ALLOC(stats->ls_percpu[0], percpusize);
1337 if (stats->ls_percpu[0] == NULL) {
1339 offsetof(struct lprocfs_stats, ls_percpu[num_entry]));
1345 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1347 struct lprocfs_stats *stats = *statsh;
1348 unsigned int num_entry;
1349 unsigned int percpusize;
1352 if (stats == NULL || stats->ls_num == 0)
1356 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1359 num_entry = cfs_num_possible_cpus() + 1;
1361 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1363 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1364 for (i = 0; i < num_entry; i++)
1365 if (stats->ls_percpu[i] != NULL)
1366 OBD_FREE(stats->ls_percpu[i], percpusize);
1367 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_entry]));
1370 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1372 struct lprocfs_counter *percpu_cntr;
1375 unsigned int num_entry;
1376 unsigned long flags = 0;
1378 num_entry = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
1380 for (i = 0; i < num_entry; i++) {
1381 if (stats->ls_percpu[i] == NULL)
1383 for (j = 0; j < stats->ls_num; j++) {
1384 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1385 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1386 percpu_cntr->lc_count = 0;
1387 percpu_cntr->lc_sum = 0;
1388 percpu_cntr->lc_min = LC_MIN_INIT;
1389 percpu_cntr->lc_max = 0;
1390 percpu_cntr->lc_sumsquare = 0;
1391 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1395 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
1398 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1399 size_t len, loff_t *off)
1401 struct seq_file *seq = file->private_data;
1402 struct lprocfs_stats *stats = seq->private;
1404 lprocfs_clear_stats(stats);
1409 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1411 struct lprocfs_stats *stats = p->private;
1412 /* return 1st cpu location */
1413 return (*pos >= stats->ls_num) ? NULL :
1414 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1417 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1421 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1423 struct lprocfs_stats *stats = p->private;
1425 return (*pos >= stats->ls_num) ? NULL :
1426 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1429 /* seq file export of one lprocfs counter */
1430 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1432 struct lprocfs_stats *stats = p->private;
1433 struct lprocfs_counter *cntr = v;
1434 struct lprocfs_counter ret;
1437 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1439 cfs_gettimeofday(&now);
1440 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1441 "snapshot_time", now.tv_sec, now.tv_usec);
1445 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1447 lprocfs_stats_collect(stats, idx, &ret);
1449 if (ret.lc_count == 0)
1452 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1453 ret.lc_count, cntr->lc_units);
1458 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1459 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1460 ret.lc_min, ret.lc_max, ret.lc_sum);
1463 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1464 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1468 rc = seq_printf(p, "\n");
1470 return (rc < 0) ? rc : 0;
1473 struct seq_operations lprocfs_stats_seq_sops = {
1474 start: lprocfs_stats_seq_start,
1475 stop: lprocfs_stats_seq_stop,
1476 next: lprocfs_stats_seq_next,
1477 show: lprocfs_stats_seq_show,
1480 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1482 struct proc_dir_entry *dp = PDE(inode);
1483 struct seq_file *seq;
1486 if (LPROCFS_ENTRY_AND_CHECK(dp))
1489 rc = seq_open(file, &lprocfs_stats_seq_sops);
1494 seq = file->private_data;
1495 seq->private = dp->data;
1499 struct file_operations lprocfs_stats_seq_fops = {
1500 .owner = THIS_MODULE,
1501 .open = lprocfs_stats_seq_open,
1503 .write = lprocfs_stats_seq_write,
1504 .llseek = seq_lseek,
1505 .release = lprocfs_seq_release,
1508 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1509 struct lprocfs_stats *stats)
1511 struct proc_dir_entry *entry;
1512 LASSERT(root != NULL);
1514 LPROCFS_WRITE_ENTRY();
1515 entry = create_proc_entry(name, 0644, root);
1517 entry->proc_fops = &lprocfs_stats_seq_fops;
1518 entry->data = stats;
1521 LPROCFS_WRITE_EXIT();
1529 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1530 unsigned conf, const char *name, const char *units)
1532 struct lprocfs_counter *c = &(stats->ls_percpu[0]->lp_cntr[index]);
1533 unsigned long flags = 0;
1535 LASSERT(stats != NULL);
1536 LASSERT(stats->ls_percpu[0] != NULL);
1538 lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
1539 c->lc_config = conf;
1542 c->lc_min = LC_MIN_INIT;
1545 c->lc_units = units;
1546 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
1548 EXPORT_SYMBOL(lprocfs_counter_init);
1550 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1552 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1553 LASSERT(coffset < stats->ls_num); \
1554 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1557 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1559 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1560 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1561 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1562 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1563 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1564 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1565 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1566 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1567 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1568 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1569 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1570 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1571 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1572 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1573 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1574 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1575 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1576 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1577 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1578 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1579 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1580 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1581 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1582 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1583 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1584 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1585 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1586 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1587 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1588 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1589 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1590 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1591 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1592 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1593 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1594 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1595 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1596 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1597 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1598 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1599 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1600 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1601 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1602 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1603 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1604 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1605 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1606 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1607 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1608 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1609 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1610 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1611 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1612 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1613 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1614 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1615 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1616 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1617 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1618 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1619 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1620 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1621 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1622 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1623 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1624 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1625 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1626 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1627 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1630 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1632 struct lprocfs_stats *stats;
1633 unsigned int num_stats;
1636 LASSERT(obd->obd_stats == NULL);
1637 LASSERT(obd->obd_proc_entry != NULL);
1638 LASSERT(obd->obd_cntr_base == 0);
1640 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1641 num_private_stats - 1 /* o_owner */;
1642 stats = lprocfs_alloc_stats(num_stats, 0);
1646 lprocfs_init_ops_stats(num_private_stats, stats);
1648 for (i = num_private_stats; i < num_stats; i++) {
1649 /* If this LBUGs, it is likely that an obd
1650 * operation was added to struct obd_ops in
1651 * <obd.h>, and that the corresponding line item
1652 * LPROCFS_OBD_OP_INIT(.., .., opname)
1653 * is missing from the list above. */
1654 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1655 "Missing obd_stat initializer obd_op "
1656 "operation at offset %d.\n", i - num_private_stats);
1658 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1660 lprocfs_free_stats(&stats);
1662 obd->obd_stats = stats;
1663 obd->obd_cntr_base = num_private_stats;
1668 void lprocfs_free_obd_stats(struct obd_device *obd)
1671 lprocfs_free_stats(&obd->obd_stats);
1674 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1676 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1677 LASSERT(coffset < stats->ls_num); \
1678 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1681 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1683 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1684 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1685 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1686 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1687 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1688 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1689 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1690 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1691 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1692 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1693 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1694 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1695 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1696 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1697 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1698 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1699 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1700 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1701 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1702 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1703 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1704 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1705 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1706 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1707 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1708 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1709 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1710 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1711 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1712 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1713 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1714 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1717 int lprocfs_alloc_md_stats(struct obd_device *obd,
1718 unsigned num_private_stats)
1720 struct lprocfs_stats *stats;
1721 unsigned int num_stats;
1724 LASSERT(obd->md_stats == NULL);
1725 LASSERT(obd->obd_proc_entry != NULL);
1726 LASSERT(obd->md_cntr_base == 0);
1728 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1730 stats = lprocfs_alloc_stats(num_stats, 0);
1734 lprocfs_init_mps_stats(num_private_stats, stats);
1736 for (i = num_private_stats; i < num_stats; i++) {
1737 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1738 CERROR("Missing md_stat initializer md_op "
1739 "operation at offset %d. Aborting.\n",
1740 i - num_private_stats);
1744 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1746 lprocfs_free_stats(&stats);
1748 obd->md_stats = stats;
1749 obd->md_cntr_base = num_private_stats;
1754 void lprocfs_free_md_stats(struct obd_device *obd)
1756 struct lprocfs_stats *stats = obd->md_stats;
1758 if (stats != NULL) {
1759 obd->md_stats = NULL;
1760 obd->md_cntr_base = 0;
1761 lprocfs_free_stats(&stats);
1765 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1767 lprocfs_counter_init(ldlm_stats,
1768 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1769 0, "ldlm_enqueue", "reqs");
1770 lprocfs_counter_init(ldlm_stats,
1771 LDLM_CONVERT - LDLM_FIRST_OPC,
1772 0, "ldlm_convert", "reqs");
1773 lprocfs_counter_init(ldlm_stats,
1774 LDLM_CANCEL - LDLM_FIRST_OPC,
1775 0, "ldlm_cancel", "reqs");
1776 lprocfs_counter_init(ldlm_stats,
1777 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1778 0, "ldlm_bl_callback", "reqs");
1779 lprocfs_counter_init(ldlm_stats,
1780 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1781 0, "ldlm_cp_callback", "reqs");
1782 lprocfs_counter_init(ldlm_stats,
1783 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1784 0, "ldlm_gl_callback", "reqs");
1787 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1788 int *eof, void *data)
1790 struct obd_export *exp = data;
1791 LASSERT(exp != NULL);
1793 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1796 struct exp_uuid_cb_data {
1804 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1805 int count, int *eof, int *len)
1807 cb_data->page = page;
1808 cb_data->count = count;
1813 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1814 cfs_hlist_node_t *hnode, void *cb_data)
1817 struct obd_export *exp = cfs_hash_object(hs, hnode);
1818 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1820 if (exp->exp_nid_stats)
1821 *data->len += snprintf((data->page + *data->len),
1822 data->count, "%s\n",
1823 obd_uuid2str(&exp->exp_client_uuid));
1827 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1828 int *eof, void *data)
1830 struct nid_stat *stats = (struct nid_stat *)data;
1831 struct exp_uuid_cb_data cb_data;
1832 struct obd_device *obd = stats->nid_obd;
1837 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1838 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1839 lprocfs_exp_print_uuid, &cb_data);
1840 return (*cb_data.len);
1843 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1844 cfs_hlist_node_t *hnode, void *cb_data)
1847 struct exp_uuid_cb_data *data = cb_data;
1848 struct obd_export *exp = cfs_hash_object(hs, hnode);
1850 if (exp->exp_lock_hash != NULL) {
1852 *data->len += cfs_hash_debug_header(data->page,
1855 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1862 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1863 int *eof, void *data)
1865 struct nid_stat *stats = (struct nid_stat *)data;
1866 struct exp_uuid_cb_data cb_data;
1867 struct obd_device *obd = stats->nid_obd;
1872 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1874 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1875 lprocfs_exp_print_hash, &cb_data);
1876 return (*cb_data.len);
1879 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1880 int count, int *eof, void *data)
1883 return snprintf(page, count, "%s\n",
1884 "Write into this file to clear all nid stats and "
1885 "stale nid entries");
1887 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1889 static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1891 struct nid_stat *stat = obj;
1895 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1896 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1897 /* object has only hash references. */
1898 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1899 cfs_list_move(&stat->nid_list, data);
1900 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1903 /* we has reference to object - only clear data*/
1904 if (stat->nid_stats)
1905 lprocfs_clear_stats(stat->nid_stats);
1907 if (stat->nid_brw_stats) {
1908 for (i = 0; i < BRW_LAST; i++)
1909 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1914 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1915 unsigned long count, void *data)
1917 struct obd_device *obd = (struct obd_device *)data;
1918 struct nid_stat *client_stat;
1919 CFS_LIST_HEAD(free_list);
1921 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1922 lprocfs_nid_stats_clear_write_cb, &free_list);
1924 while (!cfs_list_empty(&free_list)) {
1925 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1927 cfs_list_del_init(&client_stat->nid_list);
1928 lprocfs_free_client_stats(client_stat);
1933 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1935 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1937 struct nid_stat *new_stat, *old_stat;
1938 struct obd_device *obd = NULL;
1939 cfs_proc_dir_entry_t *entry;
1940 char *buffer = NULL;
1946 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1947 !exp->exp_obd->obd_nid_stats_hash)
1950 /* not test against zero because eric say:
1951 * You may only test nid against another nid, or LNET_NID_ANY.
1952 * Anything else is nonsense.*/
1953 if (!nid || *nid == LNET_NID_ANY)
1958 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1960 OBD_ALLOC_PTR(new_stat);
1961 if (new_stat == NULL)
1964 new_stat->nid = *nid;
1965 new_stat->nid_obd = exp->exp_obd;
1966 /* we need set default refcount to 1 to balance obd_disconnect */
1967 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1969 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1970 nid, &new_stat->nid_hash);
1971 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1972 old_stat, libcfs_nid2str(*nid),
1973 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1975 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1976 * been and will never be called. */
1977 if (exp->exp_nid_stats) {
1978 nidstat_putref(exp->exp_nid_stats);
1979 exp->exp_nid_stats = NULL;
1982 /* Return -EALREADY here so that we know that the /proc
1983 * entry already has been created */
1984 if (old_stat != new_stat) {
1985 exp->exp_nid_stats = old_stat;
1986 GOTO(destroy_new, rc = -EALREADY);
1988 /* not found - create */
1989 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1991 GOTO(destroy_new, rc = -ENOMEM);
1993 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1994 new_stat->nid_proc = lprocfs_register(buffer,
1995 obd->obd_proc_exports_entry,
1997 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1999 if (new_stat->nid_proc == NULL) {
2000 CERROR("Error making export directory for nid %s\n",
2001 libcfs_nid2str(*nid));
2002 GOTO(destroy_new_ns, rc = -ENOMEM);
2005 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
2006 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
2007 if (IS_ERR(entry)) {
2008 CWARN("Error adding the NID stats file\n");
2009 rc = PTR_ERR(entry);
2010 GOTO(destroy_new_ns, rc);
2013 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
2014 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
2015 if (IS_ERR(entry)) {
2016 CWARN("Error adding the hash file\n");
2017 rc = PTR_ERR(entry);
2018 GOTO(destroy_new_ns, rc);
2021 exp->exp_nid_stats = new_stat;
2023 /* protect competitive add to list, not need locking on destroy */
2024 cfs_spin_lock(&obd->obd_nid_lock);
2025 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
2026 cfs_spin_unlock(&obd->obd_nid_lock);
2031 if (new_stat->nid_proc != NULL)
2032 lprocfs_remove(&new_stat->nid_proc);
2033 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
2036 nidstat_putref(new_stat);
2037 OBD_FREE_PTR(new_stat);
2041 int lprocfs_exp_cleanup(struct obd_export *exp)
2043 struct nid_stat *stat = exp->exp_nid_stats;
2045 if(!stat || !exp->exp_obd)
2048 nidstat_putref(exp->exp_nid_stats);
2049 exp->exp_nid_stats = NULL;
2054 int lprocfs_write_helper(const char *buffer, unsigned long count,
2057 return lprocfs_write_frac_helper(buffer, count, val, 1);
2060 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
2063 char kernbuf[20], *end, *pbuf;
2065 if (count > (sizeof(kernbuf) - 1))
2068 if (cfs_copy_from_user(kernbuf, buffer, count))
2071 kernbuf[count] = '\0';
2078 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
2082 if (end != NULL && *end == '.') {
2083 int temp_val, pow = 1;
2087 if (strlen(pbuf) > 5)
2088 pbuf[5] = '\0'; /*only allow 5bits fractional*/
2090 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
2093 for (i = 0; i < (end - pbuf); i++)
2096 *val += temp_val / pow;
2102 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
2105 long decimal_val, frac_val;
2111 decimal_val = val / mult;
2112 prtn = snprintf(buffer, count, "%ld", decimal_val);
2113 frac_val = val % mult;
2115 if (prtn < (count - 4) && frac_val > 0) {
2117 int i, temp_mult = 1, frac_bits = 0;
2119 temp_frac = frac_val * 10;
2120 buffer[prtn++] = '.';
2121 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2122 /* only reserved 2 bits fraction */
2123 buffer[prtn++] ='0';
2128 * Need to think these cases :
2129 * 1. #echo x.00 > /proc/xxx output result : x
2130 * 2. #echo x.0x > /proc/xxx output result : x.0x
2131 * 3. #echo x.x0 > /proc/xxx output result : x.x
2132 * 4. #echo x.xx > /proc/xxx output result : x.xx
2133 * Only reserved 2 bits fraction.
2135 for (i = 0; i < (5 - prtn); i++)
2138 frac_bits = min((int)count - prtn, 3 - frac_bits);
2139 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2140 frac_val * temp_mult / mult);
2143 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2145 if (buffer[prtn] == '.') {
2152 buffer[prtn++] ='\n';
2156 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2158 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2161 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2162 __u64 *val, int mult)
2164 char kernbuf[22], *end, *pbuf;
2165 __u64 whole, frac = 0, units;
2166 unsigned frac_d = 1;
2168 if (count > (sizeof(kernbuf) - 1))
2171 if (cfs_copy_from_user(kernbuf, buffer, count))
2174 kernbuf[count] = '\0';
2181 whole = simple_strtoull(pbuf, &end, 10);
2185 if (end != NULL && *end == '.') {
2189 /* need to limit frac_d to a __u32 */
2190 if (strlen(pbuf) > 10)
2193 frac = simple_strtoull(pbuf, &end, 10);
2194 /* count decimal places */
2195 for (i = 0; i < (end - pbuf); i++)
2212 /* Specified units override the multiplier */
2214 mult = mult < 0 ? -units : units;
2217 do_div(frac, frac_d);
2218 *val = whole * mult + frac;
2222 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2223 struct file_operations *seq_fops, void *data)
2225 struct proc_dir_entry *entry;
2228 LPROCFS_WRITE_ENTRY();
2229 entry = create_proc_entry(name, mode, parent);
2231 entry->proc_fops = seq_fops;
2234 LPROCFS_WRITE_EXIT();
2241 EXPORT_SYMBOL(lprocfs_seq_create);
2243 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2245 struct file_operations *seq_fops,
2248 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2249 mode, seq_fops, data));
2251 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2253 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2255 if (value >= OBD_HIST_MAX)
2256 value = OBD_HIST_MAX - 1;
2258 cfs_spin_lock(&oh->oh_lock);
2259 oh->oh_buckets[value]++;
2260 cfs_spin_unlock(&oh->oh_lock);
2262 EXPORT_SYMBOL(lprocfs_oh_tally);
2264 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2268 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2271 lprocfs_oh_tally(oh, val);
2273 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2275 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2277 unsigned long ret = 0;
2280 for (i = 0; i < OBD_HIST_MAX; i++)
2281 ret += oh->oh_buckets[i];
2284 EXPORT_SYMBOL(lprocfs_oh_sum);
2286 void lprocfs_oh_clear(struct obd_histogram *oh)
2288 cfs_spin_lock(&oh->oh_lock);
2289 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2290 cfs_spin_unlock(&oh->oh_lock);
2292 EXPORT_SYMBOL(lprocfs_oh_clear);
2294 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2295 int count, int *eof, void *data)
2297 struct obd_device *obd = data;
2303 c += cfs_hash_debug_header(page, count);
2304 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2305 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2306 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2307 #ifdef HAVE_QUOTA_SUPPORT
2308 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2309 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2310 page + c, count - c);
2315 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2317 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2318 int count, int *eof, void *data)
2320 struct obd_device *obd = data;
2323 LASSERT(obd != NULL);
2324 LASSERT(count >= 0);
2326 /* Set start of user data returned to
2327 page + off since the user may have
2328 requested to read much smaller than
2329 what we need to read */
2330 *start = page + off;
2332 /* We know we are allocated a page here.
2333 Also we know that this function will
2334 not need to write more than a page
2335 so we can truncate at CFS_PAGE_SIZE. */
2336 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2338 /* Initialize the page */
2339 memset(page, 0, size);
2341 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2343 if (obd->obd_max_recoverable_clients == 0) {
2344 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2350 /* sampled unlocked, but really... */
2351 if (obd->obd_recovering == 0) {
2352 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2354 if (lprocfs_obd_snprintf(&page, size, &len,
2355 "recovery_start: %lu\n",
2356 obd->obd_recovery_start) <= 0)
2358 if (lprocfs_obd_snprintf(&page, size, &len,
2359 "recovery_duration: %lu\n",
2360 obd->obd_recovery_end -
2361 obd->obd_recovery_start) <= 0)
2363 /* Number of clients that have completed recovery */
2364 if (lprocfs_obd_snprintf(&page, size, &len,
2365 "completed_clients: %d/%d\n",
2366 obd->obd_max_recoverable_clients -
2367 obd->obd_stale_clients,
2368 obd->obd_max_recoverable_clients) <= 0)
2370 if (lprocfs_obd_snprintf(&page, size, &len,
2371 "replayed_requests: %d\n",
2372 obd->obd_replayed_requests) <= 0)
2374 if (lprocfs_obd_snprintf(&page, size, &len,
2375 "last_transno: "LPD64"\n",
2376 obd->obd_next_recovery_transno - 1)<=0)
2378 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2379 obd->obd_version_recov ? "ON" : "OFF")<=0)
2381 if (lprocfs_obd_snprintf(&page, size, &len, "IR: %s\n",
2382 obd->obd_no_ir ? "OFF" : "ON") <= 0)
2387 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2389 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2390 obd->obd_recovery_start) <= 0)
2392 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2393 cfs_time_current_sec() >=
2394 obd->obd_recovery_start +
2395 obd->obd_recovery_timeout ? 0 :
2396 obd->obd_recovery_start +
2397 obd->obd_recovery_timeout -
2398 cfs_time_current_sec()) <= 0)
2400 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2401 cfs_atomic_read(&obd->obd_connected_clients),
2402 obd->obd_max_recoverable_clients) <= 0)
2404 /* Number of clients that have completed recovery */
2405 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2406 cfs_atomic_read(&obd->obd_req_replay_clients))
2409 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2410 cfs_atomic_read(&obd->obd_lock_replay_clients))
2413 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2414 cfs_atomic_read(&obd->obd_connected_clients) -
2415 cfs_atomic_read(&obd->obd_lock_replay_clients))
2418 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2419 obd->obd_stale_clients) <= 0)
2421 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2422 obd->obd_replayed_requests) <= 0)
2424 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2425 obd->obd_requests_queued_for_recovery) <= 0)
2428 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2429 obd->obd_next_recovery_transno) <= 0)
2435 return min(count, len - (int)off);
2437 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2439 int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off,
2440 int count, int *eof, void *data)
2442 struct obd_device *obd = (struct obd_device *)data;
2443 LASSERT(obd != NULL);
2445 return snprintf(page, count, "%d\n",
2446 obd->obd_recovery_ir_factor);
2448 EXPORT_SYMBOL(lprocfs_obd_rd_ir_factor);
2450 int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer,
2451 unsigned long count, void *data)
2453 struct obd_device *obd = (struct obd_device *)data;
2455 LASSERT(obd != NULL);
2457 rc = lprocfs_write_helper(buffer, count, &val);
2461 if (val < OBD_IR_FACTOR_MIN || val > OBD_IR_FACTOR_MAX)
2464 obd->obd_recovery_ir_factor = val;
2467 EXPORT_SYMBOL(lprocfs_obd_wr_ir_factor);
2469 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2470 int count, int *eof, void *data)
2472 struct obd_device *obd = (struct obd_device *)data;
2473 LASSERT(obd != NULL);
2475 return snprintf(page, count, "%d\n",
2476 obd->obd_recovery_timeout);
2478 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2480 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2481 unsigned long count, void *data)
2483 struct obd_device *obd = (struct obd_device *)data;
2485 LASSERT(obd != NULL);
2487 rc = lprocfs_write_helper(buffer, count, &val);
2491 obd->obd_recovery_timeout = val;
2494 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2496 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2497 int count, int *eof, void *data)
2499 struct obd_device *obd = data;
2500 LASSERT(obd != NULL);
2502 return snprintf(page, count, "%u\n", obd->obd_recovery_time_hard);
2504 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2506 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2507 unsigned long count, void *data)
2509 struct obd_device *obd = data;
2511 LASSERT(obd != NULL);
2513 rc = lprocfs_write_helper(buffer, count, &val);
2517 obd->obd_recovery_time_hard = val;
2520 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2522 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2523 int count, int *eof, void *data)
2525 struct obd_device *obd = (struct obd_device *)data;
2527 LASSERT(obd != NULL);
2528 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2530 return snprintf(page, count, "%s\n",
2531 obd->u.obt.obt_vfsmnt->mnt_devname);
2533 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2535 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2536 int count, int *eof, void *data)
2538 struct obd_device *dev = data;
2539 struct client_obd *cli = &dev->u.cli;
2542 client_obd_list_lock(&cli->cl_loi_list_lock);
2543 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2544 client_obd_list_unlock(&cli->cl_loi_list_lock);
2547 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2549 int lprocfs_target_rd_instance(char *page, char **start, off_t off,
2550 int count, int *eof, void *data)
2552 struct obd_device *obd = (struct obd_device *)data;
2553 struct obd_device_target *target = &obd->u.obt;
2555 LASSERT(obd != NULL);
2556 LASSERT(target->obt_magic == OBT_MAGIC);
2558 return snprintf(page, count, "%u\n", obd->u.obt.obt_instance);
2560 EXPORT_SYMBOL(lprocfs_target_rd_instance);
2562 EXPORT_SYMBOL(lprocfs_register);
2563 EXPORT_SYMBOL(lprocfs_srch);
2564 EXPORT_SYMBOL(lprocfs_remove);
2565 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2566 EXPORT_SYMBOL(lprocfs_add_vars);
2567 EXPORT_SYMBOL(lprocfs_obd_setup);
2568 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2569 EXPORT_SYMBOL(lprocfs_add_simple);
2570 EXPORT_SYMBOL(lprocfs_add_symlink);
2571 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2572 EXPORT_SYMBOL(lprocfs_alloc_stats);
2573 EXPORT_SYMBOL(lprocfs_free_stats);
2574 EXPORT_SYMBOL(lprocfs_clear_stats);
2575 EXPORT_SYMBOL(lprocfs_register_stats);
2576 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2577 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2578 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2579 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2580 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2581 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2582 EXPORT_SYMBOL(lprocfs_free_md_stats);
2583 EXPORT_SYMBOL(lprocfs_exp_setup);
2584 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2586 EXPORT_SYMBOL(lprocfs_rd_u64);
2587 EXPORT_SYMBOL(lprocfs_rd_atomic);
2588 EXPORT_SYMBOL(lprocfs_wr_atomic);
2589 EXPORT_SYMBOL(lprocfs_rd_uint);
2590 EXPORT_SYMBOL(lprocfs_wr_uint);
2591 EXPORT_SYMBOL(lprocfs_rd_uuid);
2592 EXPORT_SYMBOL(lprocfs_rd_name);
2593 EXPORT_SYMBOL(lprocfs_rd_fstype);
2594 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2595 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2596 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2597 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2598 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2599 EXPORT_SYMBOL(lprocfs_rd_import);
2600 EXPORT_SYMBOL(lprocfs_rd_state);
2601 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2602 EXPORT_SYMBOL(lprocfs_rd_blksize);
2603 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2604 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2605 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2606 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2607 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2609 EXPORT_SYMBOL(lprocfs_write_helper);
2610 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2611 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2612 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2613 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2614 EXPORT_SYMBOL(lprocfs_stats_collect);