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 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1328 stats->ls_flags = flags;
1329 cfs_spin_lock_init(&stats->ls_lock);
1330 /* Use this lock only if there are no percpu areas */
1332 stats->ls_flags = 0;
1335 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1337 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1339 /* for no percpu area, the 0th entry is for real use,
1340 * for percpu area, the 0th entry is for intialized entry template */
1341 OBD_ALLOC(stats->ls_percpu[0], percpusize);
1342 if (stats->ls_percpu[0] == NULL) {
1344 offsetof(struct lprocfs_stats, ls_percpu[num_entry]));
1350 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1352 struct lprocfs_stats *stats = *statsh;
1353 unsigned int num_entry;
1354 unsigned int percpusize;
1357 if (stats == NULL || stats->ls_num == 0)
1361 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1364 num_entry = cfs_num_possible_cpus() + 1;
1366 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1368 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1369 for (i = 0; i < num_entry; i++)
1370 if (stats->ls_percpu[i] != NULL)
1371 OBD_FREE(stats->ls_percpu[i], percpusize);
1372 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_entry]));
1375 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1377 struct lprocfs_counter *percpu_cntr;
1380 unsigned int num_entry;
1381 unsigned int percpusize;
1382 unsigned long flags = 0;
1384 num_entry = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
1386 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1388 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1390 for (i = 0; i < num_entry; i++) {
1391 if (stats->ls_percpu[i] == NULL)
1393 /* the 1st percpu entry was statically allocated in
1394 * lprocfs_alloc_stats() */
1396 OBD_FREE(stats->ls_percpu[i], percpusize);
1397 stats->ls_percpu[i] = NULL;
1400 for (j = 0; j < stats->ls_num; j++) {
1401 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1402 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1403 percpu_cntr->lc_count = 0;
1404 percpu_cntr->lc_sum = 0;
1405 percpu_cntr->lc_min = LC_MIN_INIT;
1406 percpu_cntr->lc_max = 0;
1407 percpu_cntr->lc_sumsquare = 0;
1408 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1412 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
1415 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1416 size_t len, loff_t *off)
1418 struct seq_file *seq = file->private_data;
1419 struct lprocfs_stats *stats = seq->private;
1421 lprocfs_clear_stats(stats);
1426 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1428 struct lprocfs_stats *stats = p->private;
1429 /* return 1st cpu location */
1430 return (*pos >= stats->ls_num) ? NULL :
1431 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1434 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1438 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1440 struct lprocfs_stats *stats = p->private;
1442 return (*pos >= stats->ls_num) ? NULL :
1443 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1446 /* seq file export of one lprocfs counter */
1447 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1449 struct lprocfs_stats *stats = p->private;
1450 struct lprocfs_counter *cntr = v;
1451 struct lprocfs_counter ret;
1454 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1456 cfs_gettimeofday(&now);
1457 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1458 "snapshot_time", now.tv_sec, now.tv_usec);
1462 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1464 lprocfs_stats_collect(stats, idx, &ret);
1466 if (ret.lc_count == 0)
1469 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1470 ret.lc_count, cntr->lc_units);
1475 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1476 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1477 ret.lc_min, ret.lc_max, ret.lc_sum);
1480 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1481 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1485 rc = seq_printf(p, "\n");
1487 return (rc < 0) ? rc : 0;
1490 struct seq_operations lprocfs_stats_seq_sops = {
1491 start: lprocfs_stats_seq_start,
1492 stop: lprocfs_stats_seq_stop,
1493 next: lprocfs_stats_seq_next,
1494 show: lprocfs_stats_seq_show,
1497 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1499 struct proc_dir_entry *dp = PDE(inode);
1500 struct seq_file *seq;
1503 if (LPROCFS_ENTRY_AND_CHECK(dp))
1506 rc = seq_open(file, &lprocfs_stats_seq_sops);
1511 seq = file->private_data;
1512 seq->private = dp->data;
1516 struct file_operations lprocfs_stats_seq_fops = {
1517 .owner = THIS_MODULE,
1518 .open = lprocfs_stats_seq_open,
1520 .write = lprocfs_stats_seq_write,
1521 .llseek = seq_lseek,
1522 .release = lprocfs_seq_release,
1525 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1526 struct lprocfs_stats *stats)
1528 struct proc_dir_entry *entry;
1529 LASSERT(root != NULL);
1531 LPROCFS_WRITE_ENTRY();
1532 entry = create_proc_entry(name, 0644, root);
1534 entry->proc_fops = &lprocfs_stats_seq_fops;
1535 entry->data = stats;
1538 LPROCFS_WRITE_EXIT();
1546 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1547 unsigned conf, const char *name, const char *units)
1549 struct lprocfs_counter *c = &(stats->ls_percpu[0]->lp_cntr[index]);
1550 unsigned long flags = 0;
1552 LASSERT(stats != NULL);
1553 LASSERT(stats->ls_percpu[0] != NULL);
1555 lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
1556 c->lc_config = conf;
1559 c->lc_min = LC_MIN_INIT;
1562 c->lc_units = units;
1563 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
1565 EXPORT_SYMBOL(lprocfs_counter_init);
1567 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1569 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1570 LASSERT(coffset < stats->ls_num); \
1571 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1574 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1576 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1577 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1578 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1579 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1580 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1581 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1582 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1583 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1584 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1585 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1586 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1587 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1588 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1589 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1590 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1591 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1592 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1593 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1594 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1595 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1596 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1597 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1598 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1599 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1600 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1601 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1602 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1603 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1604 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1605 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1606 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1607 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1608 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1609 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1610 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1611 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1612 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1613 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1614 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1615 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1616 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1617 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1618 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1619 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1620 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1621 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1622 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1623 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1624 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1625 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1626 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1627 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1628 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1629 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1630 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1631 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1632 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1633 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1634 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1635 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1636 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1637 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1638 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1639 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1640 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1641 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1642 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1643 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1644 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1647 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1649 struct lprocfs_stats *stats;
1650 unsigned int num_stats;
1653 LASSERT(obd->obd_stats == NULL);
1654 LASSERT(obd->obd_proc_entry != NULL);
1655 LASSERT(obd->obd_cntr_base == 0);
1657 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1658 num_private_stats - 1 /* o_owner */;
1659 stats = lprocfs_alloc_stats(num_stats, 0);
1663 lprocfs_init_ops_stats(num_private_stats, stats);
1665 for (i = num_private_stats; i < num_stats; i++) {
1666 /* If this LBUGs, it is likely that an obd
1667 * operation was added to struct obd_ops in
1668 * <obd.h>, and that the corresponding line item
1669 * LPROCFS_OBD_OP_INIT(.., .., opname)
1670 * is missing from the list above. */
1671 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1672 "Missing obd_stat initializer obd_op "
1673 "operation at offset %d.\n", i - num_private_stats);
1675 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1677 lprocfs_free_stats(&stats);
1679 obd->obd_stats = stats;
1680 obd->obd_cntr_base = num_private_stats;
1685 void lprocfs_free_obd_stats(struct obd_device *obd)
1688 lprocfs_free_stats(&obd->obd_stats);
1691 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1693 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1694 LASSERT(coffset < stats->ls_num); \
1695 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1698 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1700 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1701 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1702 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1703 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1704 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1705 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1706 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1707 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1708 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1709 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1710 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1711 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1712 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1713 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1714 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1715 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1716 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1717 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1718 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1719 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1720 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1721 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1722 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1723 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1724 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1725 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1726 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1727 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1728 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1729 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1730 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1731 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1734 int lprocfs_alloc_md_stats(struct obd_device *obd,
1735 unsigned num_private_stats)
1737 struct lprocfs_stats *stats;
1738 unsigned int num_stats;
1741 LASSERT(obd->md_stats == NULL);
1742 LASSERT(obd->obd_proc_entry != NULL);
1743 LASSERT(obd->md_cntr_base == 0);
1745 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1747 stats = lprocfs_alloc_stats(num_stats, 0);
1751 lprocfs_init_mps_stats(num_private_stats, stats);
1753 for (i = num_private_stats; i < num_stats; i++) {
1754 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1755 CERROR("Missing md_stat initializer md_op "
1756 "operation at offset %d. Aborting.\n",
1757 i - num_private_stats);
1761 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1763 lprocfs_free_stats(&stats);
1765 obd->md_stats = stats;
1766 obd->md_cntr_base = num_private_stats;
1771 void lprocfs_free_md_stats(struct obd_device *obd)
1773 struct lprocfs_stats *stats = obd->md_stats;
1775 if (stats != NULL) {
1776 obd->md_stats = NULL;
1777 obd->md_cntr_base = 0;
1778 lprocfs_free_stats(&stats);
1782 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1784 lprocfs_counter_init(ldlm_stats,
1785 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1786 0, "ldlm_enqueue", "reqs");
1787 lprocfs_counter_init(ldlm_stats,
1788 LDLM_CONVERT - LDLM_FIRST_OPC,
1789 0, "ldlm_convert", "reqs");
1790 lprocfs_counter_init(ldlm_stats,
1791 LDLM_CANCEL - LDLM_FIRST_OPC,
1792 0, "ldlm_cancel", "reqs");
1793 lprocfs_counter_init(ldlm_stats,
1794 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1795 0, "ldlm_bl_callback", "reqs");
1796 lprocfs_counter_init(ldlm_stats,
1797 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1798 0, "ldlm_cp_callback", "reqs");
1799 lprocfs_counter_init(ldlm_stats,
1800 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1801 0, "ldlm_gl_callback", "reqs");
1804 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1805 int *eof, void *data)
1807 struct obd_export *exp = data;
1808 LASSERT(exp != NULL);
1810 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1813 struct exp_uuid_cb_data {
1821 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1822 int count, int *eof, int *len)
1824 cb_data->page = page;
1825 cb_data->count = count;
1830 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1831 cfs_hlist_node_t *hnode, void *cb_data)
1834 struct obd_export *exp = cfs_hash_object(hs, hnode);
1835 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1837 if (exp->exp_nid_stats)
1838 *data->len += snprintf((data->page + *data->len),
1839 data->count, "%s\n",
1840 obd_uuid2str(&exp->exp_client_uuid));
1844 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1845 int *eof, void *data)
1847 struct nid_stat *stats = (struct nid_stat *)data;
1848 struct exp_uuid_cb_data cb_data;
1849 struct obd_device *obd = stats->nid_obd;
1854 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1855 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1856 lprocfs_exp_print_uuid, &cb_data);
1857 return (*cb_data.len);
1860 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1861 cfs_hlist_node_t *hnode, void *cb_data)
1864 struct exp_uuid_cb_data *data = cb_data;
1865 struct obd_export *exp = cfs_hash_object(hs, hnode);
1867 if (exp->exp_lock_hash != NULL) {
1869 *data->len += cfs_hash_debug_header(data->page,
1872 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1879 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1880 int *eof, void *data)
1882 struct nid_stat *stats = (struct nid_stat *)data;
1883 struct exp_uuid_cb_data cb_data;
1884 struct obd_device *obd = stats->nid_obd;
1889 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1891 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1892 lprocfs_exp_print_hash, &cb_data);
1893 return (*cb_data.len);
1896 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1897 int count, int *eof, void *data)
1900 return snprintf(page, count, "%s\n",
1901 "Write into this file to clear all nid stats and "
1902 "stale nid entries");
1904 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1906 static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1908 struct nid_stat *stat = obj;
1912 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1913 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1914 /* object has only hash references. */
1915 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1916 cfs_list_move(&stat->nid_list, data);
1917 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1920 /* we has reference to object - only clear data*/
1921 if (stat->nid_stats)
1922 lprocfs_clear_stats(stat->nid_stats);
1924 if (stat->nid_brw_stats) {
1925 for (i = 0; i < BRW_LAST; i++)
1926 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1931 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1932 unsigned long count, void *data)
1934 struct obd_device *obd = (struct obd_device *)data;
1935 struct nid_stat *client_stat;
1936 CFS_LIST_HEAD(free_list);
1938 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1939 lprocfs_nid_stats_clear_write_cb, &free_list);
1941 while (!cfs_list_empty(&free_list)) {
1942 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1944 cfs_list_del_init(&client_stat->nid_list);
1945 lprocfs_free_client_stats(client_stat);
1950 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1952 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1954 struct nid_stat *new_stat, *old_stat;
1955 struct obd_device *obd = NULL;
1956 cfs_proc_dir_entry_t *entry;
1957 char *buffer = NULL;
1963 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1964 !exp->exp_obd->obd_nid_stats_hash)
1967 /* not test against zero because eric say:
1968 * You may only test nid against another nid, or LNET_NID_ANY.
1969 * Anything else is nonsense.*/
1970 if (!nid || *nid == LNET_NID_ANY)
1975 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1977 OBD_ALLOC_PTR(new_stat);
1978 if (new_stat == NULL)
1981 new_stat->nid = *nid;
1982 new_stat->nid_obd = exp->exp_obd;
1983 /* we need set default refcount to 1 to balance obd_disconnect */
1984 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1986 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1987 nid, &new_stat->nid_hash);
1988 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1989 old_stat, libcfs_nid2str(*nid),
1990 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1992 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1993 * been and will never be called. */
1994 if (exp->exp_nid_stats) {
1995 nidstat_putref(exp->exp_nid_stats);
1996 exp->exp_nid_stats = NULL;
1999 /* Return -EALREADY here so that we know that the /proc
2000 * entry already has been created */
2001 if (old_stat != new_stat) {
2002 exp->exp_nid_stats = old_stat;
2003 GOTO(destroy_new, rc = -EALREADY);
2005 /* not found - create */
2006 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
2008 GOTO(destroy_new, rc = -ENOMEM);
2010 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
2011 new_stat->nid_proc = lprocfs_register(buffer,
2012 obd->obd_proc_exports_entry,
2014 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
2016 if (new_stat->nid_proc == NULL) {
2017 CERROR("Error making export directory for nid %s\n",
2018 libcfs_nid2str(*nid));
2019 GOTO(destroy_new_ns, rc = -ENOMEM);
2022 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
2023 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
2024 if (IS_ERR(entry)) {
2025 CWARN("Error adding the NID stats file\n");
2026 rc = PTR_ERR(entry);
2027 GOTO(destroy_new_ns, rc);
2030 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
2031 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
2032 if (IS_ERR(entry)) {
2033 CWARN("Error adding the hash file\n");
2034 rc = PTR_ERR(entry);
2035 GOTO(destroy_new_ns, rc);
2038 exp->exp_nid_stats = new_stat;
2040 /* protect competitive add to list, not need locking on destroy */
2041 cfs_spin_lock(&obd->obd_nid_lock);
2042 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
2043 cfs_spin_unlock(&obd->obd_nid_lock);
2048 if (new_stat->nid_proc != NULL)
2049 lprocfs_remove(&new_stat->nid_proc);
2050 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
2053 nidstat_putref(new_stat);
2054 OBD_FREE_PTR(new_stat);
2058 int lprocfs_exp_cleanup(struct obd_export *exp)
2060 struct nid_stat *stat = exp->exp_nid_stats;
2062 if(!stat || !exp->exp_obd)
2065 nidstat_putref(exp->exp_nid_stats);
2066 exp->exp_nid_stats = NULL;
2071 int lprocfs_write_helper(const char *buffer, unsigned long count,
2074 return lprocfs_write_frac_helper(buffer, count, val, 1);
2077 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
2080 char kernbuf[20], *end, *pbuf;
2082 if (count > (sizeof(kernbuf) - 1))
2085 if (cfs_copy_from_user(kernbuf, buffer, count))
2088 kernbuf[count] = '\0';
2095 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
2099 if (end != NULL && *end == '.') {
2100 int temp_val, pow = 1;
2104 if (strlen(pbuf) > 5)
2105 pbuf[5] = '\0'; /*only allow 5bits fractional*/
2107 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
2110 for (i = 0; i < (end - pbuf); i++)
2113 *val += temp_val / pow;
2119 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
2122 long decimal_val, frac_val;
2128 decimal_val = val / mult;
2129 prtn = snprintf(buffer, count, "%ld", decimal_val);
2130 frac_val = val % mult;
2132 if (prtn < (count - 4) && frac_val > 0) {
2134 int i, temp_mult = 1, frac_bits = 0;
2136 temp_frac = frac_val * 10;
2137 buffer[prtn++] = '.';
2138 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2139 /* only reserved 2 bits fraction */
2140 buffer[prtn++] ='0';
2145 * Need to think these cases :
2146 * 1. #echo x.00 > /proc/xxx output result : x
2147 * 2. #echo x.0x > /proc/xxx output result : x.0x
2148 * 3. #echo x.x0 > /proc/xxx output result : x.x
2149 * 4. #echo x.xx > /proc/xxx output result : x.xx
2150 * Only reserved 2 bits fraction.
2152 for (i = 0; i < (5 - prtn); i++)
2155 frac_bits = min((int)count - prtn, 3 - frac_bits);
2156 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2157 frac_val * temp_mult / mult);
2160 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2162 if (buffer[prtn] == '.') {
2169 buffer[prtn++] ='\n';
2173 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2175 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2178 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2179 __u64 *val, int mult)
2181 char kernbuf[22], *end, *pbuf;
2182 __u64 whole, frac = 0, units;
2183 unsigned frac_d = 1;
2185 if (count > (sizeof(kernbuf) - 1))
2188 if (cfs_copy_from_user(kernbuf, buffer, count))
2191 kernbuf[count] = '\0';
2198 whole = simple_strtoull(pbuf, &end, 10);
2202 if (end != NULL && *end == '.') {
2206 /* need to limit frac_d to a __u32 */
2207 if (strlen(pbuf) > 10)
2210 frac = simple_strtoull(pbuf, &end, 10);
2211 /* count decimal places */
2212 for (i = 0; i < (end - pbuf); i++)
2229 /* Specified units override the multiplier */
2231 mult = mult < 0 ? -units : units;
2234 do_div(frac, frac_d);
2235 *val = whole * mult + frac;
2239 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2240 struct file_operations *seq_fops, void *data)
2242 struct proc_dir_entry *entry;
2245 LPROCFS_WRITE_ENTRY();
2246 entry = create_proc_entry(name, mode, parent);
2248 entry->proc_fops = seq_fops;
2251 LPROCFS_WRITE_EXIT();
2258 EXPORT_SYMBOL(lprocfs_seq_create);
2260 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2262 struct file_operations *seq_fops,
2265 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2266 mode, seq_fops, data));
2268 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2270 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2272 if (value >= OBD_HIST_MAX)
2273 value = OBD_HIST_MAX - 1;
2275 cfs_spin_lock(&oh->oh_lock);
2276 oh->oh_buckets[value]++;
2277 cfs_spin_unlock(&oh->oh_lock);
2279 EXPORT_SYMBOL(lprocfs_oh_tally);
2281 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2285 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2288 lprocfs_oh_tally(oh, val);
2290 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2292 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2294 unsigned long ret = 0;
2297 for (i = 0; i < OBD_HIST_MAX; i++)
2298 ret += oh->oh_buckets[i];
2301 EXPORT_SYMBOL(lprocfs_oh_sum);
2303 void lprocfs_oh_clear(struct obd_histogram *oh)
2305 cfs_spin_lock(&oh->oh_lock);
2306 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2307 cfs_spin_unlock(&oh->oh_lock);
2309 EXPORT_SYMBOL(lprocfs_oh_clear);
2311 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2312 int count, int *eof, void *data)
2314 struct obd_device *obd = data;
2320 c += cfs_hash_debug_header(page, count);
2321 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2322 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2323 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2324 #ifdef HAVE_QUOTA_SUPPORT
2325 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2326 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2327 page + c, count - c);
2332 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2334 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2335 int count, int *eof, void *data)
2337 struct obd_device *obd = data;
2340 LASSERT(obd != NULL);
2341 LASSERT(count >= 0);
2343 /* Set start of user data returned to
2344 page + off since the user may have
2345 requested to read much smaller than
2346 what we need to read */
2347 *start = page + off;
2349 /* We know we are allocated a page here.
2350 Also we know that this function will
2351 not need to write more than a page
2352 so we can truncate at CFS_PAGE_SIZE. */
2353 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2355 /* Initialize the page */
2356 memset(page, 0, size);
2358 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2360 if (obd->obd_max_recoverable_clients == 0) {
2361 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2367 /* sampled unlocked, but really... */
2368 if (obd->obd_recovering == 0) {
2369 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2371 if (lprocfs_obd_snprintf(&page, size, &len,
2372 "recovery_start: %lu\n",
2373 obd->obd_recovery_start) <= 0)
2375 if (lprocfs_obd_snprintf(&page, size, &len,
2376 "recovery_duration: %lu\n",
2377 obd->obd_recovery_end -
2378 obd->obd_recovery_start) <= 0)
2380 /* Number of clients that have completed recovery */
2381 if (lprocfs_obd_snprintf(&page, size, &len,
2382 "completed_clients: %d/%d\n",
2383 obd->obd_max_recoverable_clients -
2384 obd->obd_stale_clients,
2385 obd->obd_max_recoverable_clients) <= 0)
2387 if (lprocfs_obd_snprintf(&page, size, &len,
2388 "replayed_requests: %d\n",
2389 obd->obd_replayed_requests) <= 0)
2391 if (lprocfs_obd_snprintf(&page, size, &len,
2392 "last_transno: "LPD64"\n",
2393 obd->obd_next_recovery_transno - 1)<=0)
2395 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2396 obd->obd_version_recov ? "ON" : "OFF")<=0)
2398 if (lprocfs_obd_snprintf(&page, size, &len, "IR: %s\n",
2399 obd->obd_no_ir ? "OFF" : "ON") <= 0)
2404 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2406 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2407 obd->obd_recovery_start) <= 0)
2409 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2410 cfs_time_current_sec() >=
2411 obd->obd_recovery_start +
2412 obd->obd_recovery_timeout ? 0 :
2413 obd->obd_recovery_start +
2414 obd->obd_recovery_timeout -
2415 cfs_time_current_sec()) <= 0)
2417 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2418 cfs_atomic_read(&obd->obd_connected_clients),
2419 obd->obd_max_recoverable_clients) <= 0)
2421 /* Number of clients that have completed recovery */
2422 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2423 cfs_atomic_read(&obd->obd_req_replay_clients))
2426 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2427 cfs_atomic_read(&obd->obd_lock_replay_clients))
2430 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2431 cfs_atomic_read(&obd->obd_connected_clients) -
2432 cfs_atomic_read(&obd->obd_lock_replay_clients))
2435 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2436 obd->obd_stale_clients) <= 0)
2438 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2439 obd->obd_replayed_requests) <= 0)
2441 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2442 obd->obd_requests_queued_for_recovery) <= 0)
2445 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2446 obd->obd_next_recovery_transno) <= 0)
2452 return min(count, len - (int)off);
2454 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2456 int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off,
2457 int count, int *eof, void *data)
2459 struct obd_device *obd = (struct obd_device *)data;
2460 LASSERT(obd != NULL);
2462 return snprintf(page, count, "%d\n",
2463 obd->obd_recovery_ir_factor);
2465 EXPORT_SYMBOL(lprocfs_obd_rd_ir_factor);
2467 int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer,
2468 unsigned long count, void *data)
2470 struct obd_device *obd = (struct obd_device *)data;
2472 LASSERT(obd != NULL);
2474 rc = lprocfs_write_helper(buffer, count, &val);
2478 if (val < OBD_IR_FACTOR_MIN || val > OBD_IR_FACTOR_MAX)
2481 obd->obd_recovery_ir_factor = val;
2484 EXPORT_SYMBOL(lprocfs_obd_wr_ir_factor);
2486 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2487 int count, int *eof, void *data)
2489 struct obd_device *obd = (struct obd_device *)data;
2490 LASSERT(obd != NULL);
2492 return snprintf(page, count, "%d\n",
2493 obd->obd_recovery_timeout);
2495 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2497 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2498 unsigned long count, void *data)
2500 struct obd_device *obd = (struct obd_device *)data;
2502 LASSERT(obd != NULL);
2504 rc = lprocfs_write_helper(buffer, count, &val);
2508 obd->obd_recovery_timeout = val;
2511 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2513 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2514 int count, int *eof, void *data)
2516 struct obd_device *obd = data;
2517 LASSERT(obd != NULL);
2519 return snprintf(page, count, "%u\n", obd->obd_recovery_time_hard);
2521 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2523 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2524 unsigned long count, void *data)
2526 struct obd_device *obd = data;
2528 LASSERT(obd != NULL);
2530 rc = lprocfs_write_helper(buffer, count, &val);
2534 obd->obd_recovery_time_hard = val;
2537 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2539 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2540 int count, int *eof, void *data)
2542 struct obd_device *obd = (struct obd_device *)data;
2544 LASSERT(obd != NULL);
2545 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2547 return snprintf(page, count, "%s\n",
2548 obd->u.obt.obt_vfsmnt->mnt_devname);
2550 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2552 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2553 int count, int *eof, void *data)
2555 struct obd_device *dev = data;
2556 struct client_obd *cli = &dev->u.cli;
2559 client_obd_list_lock(&cli->cl_loi_list_lock);
2560 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2561 client_obd_list_unlock(&cli->cl_loi_list_lock);
2564 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2566 int lprocfs_target_rd_instance(char *page, char **start, off_t off,
2567 int count, int *eof, void *data)
2569 struct obd_device *obd = (struct obd_device *)data;
2570 struct obd_device_target *target = &obd->u.obt;
2572 LASSERT(obd != NULL);
2573 LASSERT(target->obt_magic == OBT_MAGIC);
2575 return snprintf(page, count, "%u\n", obd->u.obt.obt_instance);
2577 EXPORT_SYMBOL(lprocfs_target_rd_instance);
2579 EXPORT_SYMBOL(lprocfs_register);
2580 EXPORT_SYMBOL(lprocfs_srch);
2581 EXPORT_SYMBOL(lprocfs_remove);
2582 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2583 EXPORT_SYMBOL(lprocfs_add_vars);
2584 EXPORT_SYMBOL(lprocfs_obd_setup);
2585 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2586 EXPORT_SYMBOL(lprocfs_add_simple);
2587 EXPORT_SYMBOL(lprocfs_add_symlink);
2588 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2589 EXPORT_SYMBOL(lprocfs_alloc_stats);
2590 EXPORT_SYMBOL(lprocfs_free_stats);
2591 EXPORT_SYMBOL(lprocfs_clear_stats);
2592 EXPORT_SYMBOL(lprocfs_register_stats);
2593 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2594 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2595 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2596 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2597 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2598 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2599 EXPORT_SYMBOL(lprocfs_free_md_stats);
2600 EXPORT_SYMBOL(lprocfs_exp_setup);
2601 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2603 EXPORT_SYMBOL(lprocfs_rd_u64);
2604 EXPORT_SYMBOL(lprocfs_rd_atomic);
2605 EXPORT_SYMBOL(lprocfs_wr_atomic);
2606 EXPORT_SYMBOL(lprocfs_rd_uint);
2607 EXPORT_SYMBOL(lprocfs_wr_uint);
2608 EXPORT_SYMBOL(lprocfs_rd_uuid);
2609 EXPORT_SYMBOL(lprocfs_rd_name);
2610 EXPORT_SYMBOL(lprocfs_rd_fstype);
2611 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2612 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2613 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2614 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2615 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2616 EXPORT_SYMBOL(lprocfs_rd_import);
2617 EXPORT_SYMBOL(lprocfs_rd_state);
2618 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2619 EXPORT_SYMBOL(lprocfs_rd_blksize);
2620 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2621 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2622 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2623 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2624 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2626 EXPORT_SYMBOL(lprocfs_write_helper);
2627 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2628 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2629 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2630 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2631 EXPORT_SYMBOL(lprocfs_stats_collect);