4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, Whamcloud, Inc.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/obdclass/lprocfs_status.c
38 * Author: Hariharan Thantry <thantry@users.sourceforge.net>
42 # define EXPORT_SYMTAB
44 #define DEBUG_SUBSYSTEM S_CLASS
47 # include <liblustre.h>
50 #include <obd_class.h>
51 #include <lprocfs_status.h>
52 #include <lustre_fsfilt.h>
53 #include <lustre_log.h>
54 #include <lustre/lustre_idl.h>
58 static int lprocfs_no_percpu_stats = 0;
59 CFS_MODULE_PARM(lprocfs_no_percpu_stats, "i", int, 0644,
60 "Do not alloc percpu data for lprocfs stats");
62 #define MAX_STRING_SIZE 128
64 /* for bug 10866, global variable */
65 CFS_DECLARE_RWSEM(_lprocfs_lock);
66 EXPORT_SYMBOL(_lprocfs_lock);
68 int lprocfs_seq_release(struct inode *inode, struct file *file)
71 return seq_release(inode, file);
73 EXPORT_SYMBOL(lprocfs_seq_release);
75 static struct proc_dir_entry *__lprocfs_srch(struct proc_dir_entry *head,
78 struct proc_dir_entry *temp;
84 while (temp != NULL) {
85 if (strcmp(temp->name, name) == 0) {
94 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
97 struct proc_dir_entry *temp;
100 temp = __lprocfs_srch(head, name);
105 /* lprocfs API calls */
107 /* Function that emulates snprintf but also has the side effect of advancing
108 the page pointer for the next write into the buffer, incrementing the total
109 length written to the buffer, and decrementing the size left in the
111 static int lprocfs_obd_snprintf(char **page, int end, int *len,
112 const char *format, ...)
120 va_start(list, format);
121 n = vsnprintf(*page, end - *len, format, list);
124 *page += n; *len += n;
128 cfs_proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
130 read_proc_t *read_proc,
131 write_proc_t *write_proc,
133 struct file_operations *fops)
135 cfs_proc_dir_entry_t *proc;
138 if (root == NULL || name == NULL)
139 return ERR_PTR(-EINVAL);
146 LPROCFS_WRITE_ENTRY();
147 proc = create_proc_entry(name, mode, root);
149 CERROR("LprocFS: No memory to create /proc entry %s", name);
150 LPROCFS_WRITE_EXIT();
151 return ERR_PTR(-ENOMEM);
153 proc->read_proc = read_proc;
154 proc->write_proc = write_proc;
157 proc->proc_fops = fops;
158 LPROCFS_WRITE_EXIT();
162 struct proc_dir_entry *lprocfs_add_symlink(const char *name,
163 struct proc_dir_entry *parent, const char *format, ...)
165 struct proc_dir_entry *entry;
169 if (parent == NULL || format == NULL)
172 OBD_ALLOC_WAIT(dest, MAX_STRING_SIZE + 1);
176 va_start(ap, format);
177 vsnprintf(dest, MAX_STRING_SIZE, format, ap);
180 entry = proc_symlink(name, parent, dest);
182 CERROR("LprocFS: Could not create symbolic link from %s to %s",
185 OBD_FREE(dest, MAX_STRING_SIZE + 1);
189 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
190 size_t size, loff_t *ppos)
192 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
193 char *page, *start = NULL;
194 int rc = 0, eof = 1, count;
196 if (*ppos >= CFS_PAGE_SIZE)
199 page = (char *)__get_free_page(GFP_KERNEL);
203 if (LPROCFS_ENTRY_AND_CHECK(dp)) {
208 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
210 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
216 /* for lustre proc read, the read count must be less than PAGE_SIZE */
225 start = page + *ppos;
226 } else if (start < page) {
230 count = (rc < size) ? rc : size;
231 if (cfs_copy_to_user(buf, start, count)) {
238 free_page((unsigned long)page);
242 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
243 size_t size, loff_t *ppos)
245 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
248 if (LPROCFS_ENTRY_AND_CHECK(dp))
251 rc = dp->write_proc(f, buf, size, dp->data);
256 static struct file_operations lprocfs_generic_fops = {
257 .owner = THIS_MODULE,
258 .read = lprocfs_fops_read,
259 .write = lprocfs_fops_write,
262 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
264 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
265 struct obd_device *obd = dp->data;
267 cfs_atomic_inc(&obd->obd_evict_inprogress);
272 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
274 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
275 struct obd_device *obd = dp->data;
277 cfs_atomic_dec(&obd->obd_evict_inprogress);
278 cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
283 struct file_operations lprocfs_evict_client_fops = {
284 .owner = THIS_MODULE,
285 .read = lprocfs_fops_read,
286 .write = lprocfs_fops_write,
287 .open = lprocfs_evict_client_open,
288 .release = lprocfs_evict_client_release,
290 EXPORT_SYMBOL(lprocfs_evict_client_fops);
295 * \param root [in] The parent proc entry on which new entry will be added.
296 * \param list [in] Array of proc entries to be added.
297 * \param data [in] The argument to be passed when entries read/write routines
298 * are called through /proc file.
300 * \retval 0 on success
303 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
308 if (root == NULL || list == NULL)
311 LPROCFS_WRITE_ENTRY();
312 while (list->name != NULL) {
313 struct proc_dir_entry *cur_root, *proc;
314 char *pathcopy, *cur, *next, pathbuf[64];
315 int pathsize = strlen(list->name) + 1;
320 /* need copy of path for strsep */
321 if (strlen(list->name) > sizeof(pathbuf) - 1) {
322 OBD_ALLOC(pathcopy, pathsize);
323 if (pathcopy == NULL)
324 GOTO(out, rc = -ENOMEM);
330 strcpy(pathcopy, list->name);
332 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
333 if (*cur =='\0') /* skip double/trailing "/" */
336 proc = __lprocfs_srch(cur_root, cur);
337 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
338 cur_root->name, cur, next,
339 (proc ? "exists" : "new"));
341 cur_root = (proc ? proc :
342 proc_mkdir(cur, cur_root));
343 } else if (proc == NULL) {
345 if (list->proc_mode != 0000) {
346 mode = list->proc_mode;
350 if (list->write_fptr)
353 proc = create_proc_entry(cur, mode, cur_root);
357 if (pathcopy != pathbuf)
358 OBD_FREE(pathcopy, pathsize);
360 if (cur_root == NULL || proc == NULL) {
361 CERROR("LprocFS: No memory to create /proc entry %s",
363 GOTO(out, rc = -ENOMEM);
367 proc->proc_fops = list->fops;
369 proc->proc_fops = &lprocfs_generic_fops;
370 proc->read_proc = list->read_fptr;
371 proc->write_proc = list->write_fptr;
372 proc->data = (list->data ? list->data : data);
376 LPROCFS_WRITE_EXIT();
380 void lprocfs_remove(struct proc_dir_entry **rooth)
382 struct proc_dir_entry *root = *rooth;
383 struct proc_dir_entry *temp = root;
384 struct proc_dir_entry *rm_entry;
385 struct proc_dir_entry *parent;
391 parent = root->parent;
392 LASSERT(parent != NULL);
393 LPROCFS_WRITE_ENTRY(); /* search vs remove race */
396 while (temp->subdir != NULL)
402 /* Memory corruption once caused this to fail, and
403 without this LASSERT we would loop here forever. */
404 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
405 "0x%p %s/%s len %d\n", rm_entry, temp->name,
406 rm_entry->name, (int)strlen(rm_entry->name));
408 #ifdef HAVE_PROCFS_USERS
409 /* if procfs uses user count to synchronize deletion of
410 * proc entry, there is no protection for rm_entry->data,
411 * then lprocfs_fops_read and lprocfs_fops_write maybe
412 * call proc_dir_entry->read_proc (or write_proc) with
413 * proc_dir_entry->data == NULL, then cause kernel Oops.
414 * see bug19706 for detailed information */
416 /* procfs won't free rm_entry->data if it isn't a LINK,
417 * and Lustre won't use rm_entry->data if it is a LINK */
418 if (S_ISLNK(rm_entry->mode))
419 rm_entry->data = NULL;
421 /* Now, the rm_entry->deleted flags is protected
422 * by _lprocfs_lock. */
423 rm_entry->data = NULL;
425 remove_proc_entry(rm_entry->name, temp);
429 LPROCFS_WRITE_EXIT();
432 void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
434 LASSERT(parent != NULL);
435 remove_proc_entry(name, parent);
438 struct proc_dir_entry *lprocfs_register(const char *name,
439 struct proc_dir_entry *parent,
440 struct lprocfs_vars *list, void *data)
442 struct proc_dir_entry *newchild;
444 newchild = lprocfs_srch(parent, name);
445 if (newchild != NULL) {
446 CERROR(" Lproc: Attempting to register %s more than once \n",
448 return ERR_PTR(-EALREADY);
451 newchild = proc_mkdir(name, parent);
452 if (newchild != NULL && list != NULL) {
453 int rc = lprocfs_add_vars(newchild, list, data);
455 lprocfs_remove(&newchild);
462 /* Generic callbacks */
463 int lprocfs_rd_uint(char *page, char **start, off_t off,
464 int count, int *eof, void *data)
466 unsigned int *temp = data;
467 return snprintf(page, count, "%u\n", *temp);
470 int lprocfs_wr_uint(struct file *file, const char *buffer,
471 unsigned long count, void *data)
474 char dummy[MAX_STRING_SIZE + 1], *end;
477 dummy[MAX_STRING_SIZE] = '\0';
478 if (cfs_copy_from_user(dummy, buffer, MAX_STRING_SIZE))
481 tmp = simple_strtoul(dummy, &end, 0);
485 *p = (unsigned int)tmp;
489 int lprocfs_rd_u64(char *page, char **start, off_t off,
490 int count, int *eof, void *data)
492 LASSERT(data != NULL);
494 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
497 int lprocfs_rd_atomic(char *page, char **start, off_t off,
498 int count, int *eof, void *data)
500 cfs_atomic_t *atom = data;
501 LASSERT(atom != NULL);
503 return snprintf(page, count, "%d\n", cfs_atomic_read(atom));
506 int lprocfs_wr_atomic(struct file *file, const char *buffer,
507 unsigned long count, void *data)
509 cfs_atomic_t *atm = data;
513 rc = lprocfs_write_helper(buffer, count, &val);
520 cfs_atomic_set(atm, val);
524 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
525 int *eof, void *data)
527 struct obd_device *obd = data;
529 LASSERT(obd != NULL);
531 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
534 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
535 int *eof, void *data)
537 struct obd_device *dev = data;
539 LASSERT(dev != NULL);
540 LASSERT(dev->obd_name != NULL);
542 return snprintf(page, count, "%s\n", dev->obd_name);
545 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
548 struct obd_device *obd = data;
550 LASSERT(obd != NULL);
551 LASSERT(obd->obd_fsops != NULL);
552 LASSERT(obd->obd_fsops->fs_type != NULL);
553 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
556 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
557 int *eof, void *data)
559 struct obd_statfs osfs;
560 int rc = obd_statfs(data, &osfs,
561 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
565 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
570 int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
571 int *eof, void *data)
573 struct obd_statfs osfs;
574 int rc = obd_statfs(data, &osfs,
575 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
578 __u32 blk_size = osfs.os_bsize >> 10;
579 __u64 result = osfs.os_blocks;
581 while (blk_size >>= 1)
585 rc = snprintf(page, count, LPU64"\n", result);
590 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
591 int *eof, void *data)
593 struct obd_statfs osfs;
594 int rc = obd_statfs(data, &osfs,
595 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
598 __u32 blk_size = osfs.os_bsize >> 10;
599 __u64 result = osfs.os_bfree;
601 while (blk_size >>= 1)
605 rc = snprintf(page, count, LPU64"\n", result);
610 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
611 int *eof, void *data)
613 struct obd_statfs osfs;
614 int rc = obd_statfs(data, &osfs,
615 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
618 __u32 blk_size = osfs.os_bsize >> 10;
619 __u64 result = osfs.os_bavail;
621 while (blk_size >>= 1)
625 rc = snprintf(page, count, LPU64"\n", result);
630 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
631 int *eof, void *data)
633 struct obd_statfs osfs;
634 int rc = obd_statfs(data, &osfs,
635 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
639 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
645 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
646 int *eof, void *data)
648 struct obd_statfs osfs;
649 int rc = obd_statfs(data, &osfs,
650 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
654 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
659 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
660 int *eof, void *data)
662 struct obd_device *obd = data;
663 struct obd_import *imp;
664 char *imp_state_name = NULL;
667 LASSERT(obd != NULL);
668 LPROCFS_CLIMP_CHECK(obd);
669 imp = obd->u.cli.cl_import;
670 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
672 rc = snprintf(page, count, "%s\t%s%s\n",
673 obd2cli_tgt(obd), imp_state_name,
674 imp->imp_deactive ? "\tDEACTIVATED" : "");
676 LPROCFS_CLIMP_EXIT(obd);
680 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
681 int *eof, void *data)
683 struct obd_device *obd = data;
684 struct ptlrpc_connection *conn;
687 LASSERT(obd != NULL);
689 LPROCFS_CLIMP_CHECK(obd);
690 conn = obd->u.cli.cl_import->imp_connection;
692 if (conn && obd->u.cli.cl_import) {
693 rc = snprintf(page, count, "%s\n",
694 conn->c_remote_uuid.uuid);
696 rc = snprintf(page, count, "%s\n", "<none>");
699 LPROCFS_CLIMP_EXIT(obd);
703 /** add up per-cpu counters */
704 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
705 struct lprocfs_counter *cnt)
707 unsigned int num_cpu;
708 struct lprocfs_counter t;
709 struct lprocfs_counter *percpu_cntr;
712 memset(cnt, 0, sizeof(*cnt));
715 /* set count to 1 to avoid divide-by-zero errs in callers */
720 cnt->lc_min = LC_MIN_INIT;
722 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
724 for (i = 0; i < num_cpu; i++) {
725 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
728 centry = cfs_atomic_read(&percpu_cntr-> \
730 t.lc_count = percpu_cntr->lc_count;
731 t.lc_sum = percpu_cntr->lc_sum;
732 t.lc_min = percpu_cntr->lc_min;
733 t.lc_max = percpu_cntr->lc_max;
734 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
735 } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
737 centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
739 cnt->lc_count += t.lc_count;
740 cnt->lc_sum += t.lc_sum;
741 if (t.lc_min < cnt->lc_min)
742 cnt->lc_min = t.lc_min;
743 if (t.lc_max > cnt->lc_max)
744 cnt->lc_max = t.lc_max;
745 cnt->lc_sumsquare += t.lc_sumsquare;
748 cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
749 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
753 * Append a space separated list of current set flags to str.
755 #define flag2str(flag) \
756 if (imp->imp_##flag && max - len > 0) \
757 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
758 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
762 if (imp->imp_obd->obd_no_recov)
763 len += snprintf(str, max - len, "no_recov");
767 flag2str(replayable);
773 static const char *obd_connect_names[] = {
787 "join_file(obsolete)",
791 "remote_client_by_force",
800 "mds_mds_connection",
803 "alt_checksum_algorithm",
822 int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
827 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
829 ret += snprintf(page + ret, count - ret, "%s%s",
830 ret ? sep : "", obd_connect_names[i]);
832 if (flags & ~(mask - 1))
833 ret += snprintf(page + ret, count - ret,
834 "%sunknown flags "LPX64,
835 ret ? sep : "", flags & ~(mask - 1));
838 EXPORT_SYMBOL(obd_connect_flags2str);
840 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
841 int *eof, void *data)
843 struct lprocfs_counter ret;
844 struct obd_device *obd = (struct obd_device *)data;
845 struct obd_import *imp;
846 struct obd_import_conn *conn;
849 LASSERT(obd != NULL);
850 LPROCFS_CLIMP_CHECK(obd);
851 imp = obd->u.cli.cl_import;
854 i = snprintf(page, count,
863 ptlrpc_import_state_name(imp->imp_state),
864 imp->imp_connect_data.ocd_instance);
865 i += obd_connect_flags2str(page + i, count - i,
866 imp->imp_connect_data.ocd_connect_flags,
868 i += snprintf(page + i, count - i,
871 i += obd_import_flags2str(imp, page + i, count - i);
873 i += snprintf(page + i, count - i,
876 " failover_nids: [");
877 cfs_spin_lock(&imp->imp_lock);
879 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
880 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
881 libcfs_nid2str(conn->oic_conn->c_peer.nid));
884 cfs_spin_unlock(&imp->imp_lock);
885 i += snprintf(page + i, count - i,
887 " current_connection: %s\n"
888 " connection_attempts: %u\n"
890 " in-progress_invalidations: %u\n",
891 libcfs_nid2str(imp->imp_connection->c_peer.nid),
894 cfs_atomic_read(&imp->imp_inval_count));
896 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
897 if (ret.lc_count != 0) {
898 /* first argument to do_div MUST be __u64 */
899 __u64 sum = ret.lc_sum;
900 do_div(sum, ret.lc_count);
904 i += snprintf(page + i, count - i,
907 " unregistering: %u\n"
909 " avg_waittime: "LPU64" %s\n",
910 cfs_atomic_read(&imp->imp_inflight),
911 cfs_atomic_read(&imp->imp_unregistering),
912 cfs_atomic_read(&imp->imp_timeouts),
913 ret.lc_sum, ret.lc_units);
916 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
917 if (imp->imp_at.iat_portal[j] == 0)
919 k = max_t(unsigned int, k,
920 at_get(&imp->imp_at.iat_service_estimate[j]));
922 i += snprintf(page + i, count - i,
923 " service_estimates:\n"
924 " services: %u sec\n"
925 " network: %u sec\n",
927 at_get(&imp->imp_at.iat_net_latency));
929 i += snprintf(page + i, count - i,
931 " last_replay: "LPU64"\n"
932 " peer_committed: "LPU64"\n"
933 " last_checked: "LPU64"\n",
934 imp->imp_last_replay_transno,
935 imp->imp_peer_committed_transno,
936 imp->imp_last_transno_checked);
939 for (rw = 0; rw <= 1; rw++) {
940 lprocfs_stats_collect(obd->obd_svc_stats,
941 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
943 if (ret.lc_sum > 0 && ret.lc_count > 0) {
944 /* first argument to do_div MUST be __u64 */
945 __u64 sum = ret.lc_sum;
946 do_div(sum, ret.lc_count);
948 i += snprintf(page + i, count - i,
949 " %s_data_averages:\n"
950 " bytes_per_rpc: "LPU64"\n",
951 rw ? "write" : "read",
955 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
956 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
957 if (ret.lc_sum > 0 && ret.lc_count != 0) {
958 /* first argument to do_div MUST be __u64 */
959 __u64 sum = ret.lc_sum;
960 do_div(sum, ret.lc_count);
962 i += snprintf(page + i, count - i,
963 " %s_per_rpc: "LPU64"\n",
964 ret.lc_units, ret.lc_sum);
967 i += snprintf(page + i, count - i,
968 " MB_per_sec: %u.%.02u\n",
969 k / j, (100 * k / j) % 100);
973 LPROCFS_CLIMP_EXIT(obd);
977 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
978 int *eof, void *data)
980 struct obd_device *obd = (struct obd_device *)data;
981 struct obd_import *imp;
984 LASSERT(obd != NULL);
985 LPROCFS_CLIMP_CHECK(obd);
986 imp = obd->u.cli.cl_import;
989 i = snprintf(page, count, "current_state: %s\n",
990 ptlrpc_import_state_name(imp->imp_state));
991 i += snprintf(page + i, count - i,
993 k = imp->imp_state_hist_idx;
994 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
995 struct import_state_hist *ish =
996 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
997 if (ish->ish_state == 0)
999 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
1001 ptlrpc_import_state_name(ish->ish_state));
1004 LPROCFS_CLIMP_EXIT(obd);
1008 int lprocfs_at_hist_helper(char *page, int count, int rc,
1009 struct adaptive_timeout *at)
1012 for (i = 0; i < AT_BINS; i++)
1013 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1014 rc += snprintf(page + rc, count - rc, "\n");
1018 /* See also ptlrpc_lprocfs_rd_timeouts */
1019 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1020 int *eof, void *data)
1022 struct obd_device *obd = (struct obd_device *)data;
1023 struct obd_import *imp;
1024 unsigned int cur, worst;
1029 LASSERT(obd != NULL);
1030 LPROCFS_CLIMP_CHECK(obd);
1031 imp = obd->u.cli.cl_import;
1034 now = cfs_time_current_sec();
1036 /* Some network health info for kicks */
1037 s2dhms(&ts, now - imp->imp_last_reply_time);
1038 rc += snprintf(page + rc, count - rc,
1039 "%-10s : %ld, "DHMS_FMT" ago\n",
1040 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1042 cur = at_get(&imp->imp_at.iat_net_latency);
1043 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1044 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1045 s2dhms(&ts, now - worstt);
1046 rc += snprintf(page + rc, count - rc,
1047 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1048 "network", cur, worst, worstt, DHMS_VARS(&ts));
1049 rc = lprocfs_at_hist_helper(page, count, rc,
1050 &imp->imp_at.iat_net_latency);
1052 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1053 if (imp->imp_at.iat_portal[i] == 0)
1055 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1056 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1057 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1058 s2dhms(&ts, now - worstt);
1059 rc += snprintf(page + rc, count - rc,
1060 "portal %-2d : cur %3u worst %3u (at %ld, "
1061 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1062 cur, worst, worstt, DHMS_VARS(&ts));
1063 rc = lprocfs_at_hist_helper(page, count, rc,
1064 &imp->imp_at.iat_service_estimate[i]);
1067 LPROCFS_CLIMP_EXIT(obd);
1071 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1072 int count, int *eof, void *data)
1074 struct obd_device *obd = data;
1078 LPROCFS_CLIMP_CHECK(obd);
1079 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1080 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1081 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1082 ret += snprintf(page + ret, count - ret, "\n");
1083 LPROCFS_CLIMP_EXIT(obd);
1086 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1088 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1089 int *eof, void *data)
1091 struct obd_device *obd = data;
1093 LASSERT(obd != NULL);
1095 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1098 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1099 int *eof, void *data)
1101 struct obd_type *class = (struct obd_type*) data;
1103 LASSERT(class != NULL);
1105 return snprintf(page, count, "%d\n", class->typ_refcnt);
1108 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1112 LASSERT(obd != NULL);
1113 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1114 LASSERT(obd->obd_type->typ_procroot != NULL);
1116 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1117 obd->obd_type->typ_procroot,
1119 if (IS_ERR(obd->obd_proc_entry)) {
1120 rc = PTR_ERR(obd->obd_proc_entry);
1121 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1122 obd->obd_proc_entry = NULL;
1127 int lprocfs_obd_cleanup(struct obd_device *obd)
1131 if (obd->obd_proc_exports_entry) {
1132 /* Should be no exports left */
1133 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1134 lprocfs_remove(&obd->obd_proc_exports_entry);
1135 obd->obd_proc_exports_entry = NULL;
1137 if (obd->obd_proc_entry) {
1138 lprocfs_remove(&obd->obd_proc_entry);
1139 obd->obd_proc_entry = NULL;
1144 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1146 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1147 client_stat->nid_proc, client_stat->nid_stats,
1148 client_stat->nid_brw_stats);
1150 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1151 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1152 atomic_read(&client_stat->nid_exp_ref_count));
1154 if (client_stat->nid_proc)
1155 lprocfs_remove(&client_stat->nid_proc);
1157 if (client_stat->nid_stats)
1158 lprocfs_free_stats(&client_stat->nid_stats);
1160 if (client_stat->nid_brw_stats)
1161 OBD_FREE_PTR(client_stat->nid_brw_stats);
1163 if (client_stat->nid_ldlm_stats)
1164 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1166 OBD_FREE_PTR(client_stat);
1171 void lprocfs_free_per_client_stats(struct obd_device *obd)
1173 cfs_hash_t *hash = obd->obd_nid_stats_hash;
1174 struct nid_stat *stat;
1177 /* we need extra list - because hash_exit called to early */
1178 /* not need locking because all clients is died */
1179 while (!cfs_list_empty(&obd->obd_nid_stats)) {
1180 stat = cfs_list_entry(obd->obd_nid_stats.next,
1181 struct nid_stat, nid_list);
1182 cfs_list_del_init(&stat->nid_list);
1183 cfs_hash_del(hash, &stat->nid, &stat->nid_hash);
1184 lprocfs_free_client_stats(stat);
1189 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1190 enum lprocfs_stats_flags flags)
1192 struct lprocfs_stats *stats;
1193 unsigned int percpusize;
1195 unsigned int num_cpu;
1200 if (lprocfs_no_percpu_stats != 0)
1201 flags |= LPROCFS_STATS_FLAG_NOPERCPU;
1203 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1206 num_cpu = cfs_num_possible_cpus();
1208 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1212 if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
1213 stats->ls_flags = flags;
1214 cfs_spin_lock_init(&stats->ls_lock);
1215 /* Use this lock only if there are no percpu areas */
1217 stats->ls_flags = 0;
1220 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1222 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1224 for (i = 0; i < num_cpu; i++) {
1225 OBD_ALLOC(stats->ls_percpu[i], percpusize);
1226 if (stats->ls_percpu[i] == NULL) {
1227 for (j = 0; j < i; j++) {
1228 OBD_FREE(stats->ls_percpu[j], percpusize);
1229 stats->ls_percpu[j] = NULL;
1234 if (stats->ls_percpu[0] == NULL) {
1235 OBD_FREE(stats, offsetof(typeof(*stats),
1236 ls_percpu[num_cpu]));
1240 stats->ls_num = num;
1244 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1246 struct lprocfs_stats *stats = *statsh;
1247 unsigned int num_cpu;
1248 unsigned int percpusize;
1251 if (stats == NULL || stats->ls_num == 0)
1255 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1258 num_cpu = cfs_num_possible_cpus();
1260 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1262 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1263 for (i = 0; i < num_cpu; i++)
1264 OBD_FREE(stats->ls_percpu[i], percpusize);
1265 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
1268 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1270 struct lprocfs_counter *percpu_cntr;
1272 unsigned int num_cpu;
1274 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1276 for (i = 0; i < num_cpu; i++) {
1277 for (j = 0; j < stats->ls_num; j++) {
1278 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1279 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1280 percpu_cntr->lc_count = 0;
1281 percpu_cntr->lc_sum = 0;
1282 percpu_cntr->lc_min = LC_MIN_INIT;
1283 percpu_cntr->lc_max = 0;
1284 percpu_cntr->lc_sumsquare = 0;
1285 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1289 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1292 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1293 size_t len, loff_t *off)
1295 struct seq_file *seq = file->private_data;
1296 struct lprocfs_stats *stats = seq->private;
1298 lprocfs_clear_stats(stats);
1303 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1305 struct lprocfs_stats *stats = p->private;
1306 /* return 1st cpu location */
1307 return (*pos >= stats->ls_num) ? NULL :
1308 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1311 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1315 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1317 struct lprocfs_stats *stats = p->private;
1319 return (*pos >= stats->ls_num) ? NULL :
1320 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1323 /* seq file export of one lprocfs counter */
1324 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1326 struct lprocfs_stats *stats = p->private;
1327 struct lprocfs_counter *cntr = v;
1328 struct lprocfs_counter ret;
1331 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1333 cfs_gettimeofday(&now);
1334 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1335 "snapshot_time", now.tv_sec, now.tv_usec);
1339 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1341 lprocfs_stats_collect(stats, idx, &ret);
1343 if (ret.lc_count == 0)
1346 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1347 ret.lc_count, cntr->lc_units);
1352 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1353 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1354 ret.lc_min, ret.lc_max, ret.lc_sum);
1357 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1358 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1362 rc = seq_printf(p, "\n");
1364 return (rc < 0) ? rc : 0;
1367 struct seq_operations lprocfs_stats_seq_sops = {
1368 start: lprocfs_stats_seq_start,
1369 stop: lprocfs_stats_seq_stop,
1370 next: lprocfs_stats_seq_next,
1371 show: lprocfs_stats_seq_show,
1374 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1376 struct proc_dir_entry *dp = PDE(inode);
1377 struct seq_file *seq;
1380 if (LPROCFS_ENTRY_AND_CHECK(dp))
1383 rc = seq_open(file, &lprocfs_stats_seq_sops);
1388 seq = file->private_data;
1389 seq->private = dp->data;
1393 struct file_operations lprocfs_stats_seq_fops = {
1394 .owner = THIS_MODULE,
1395 .open = lprocfs_stats_seq_open,
1397 .write = lprocfs_stats_seq_write,
1398 .llseek = seq_lseek,
1399 .release = lprocfs_seq_release,
1402 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1403 struct lprocfs_stats *stats)
1405 struct proc_dir_entry *entry;
1406 LASSERT(root != NULL);
1408 LPROCFS_WRITE_ENTRY();
1409 entry = create_proc_entry(name, 0644, root);
1411 entry->proc_fops = &lprocfs_stats_seq_fops;
1412 entry->data = stats;
1415 LPROCFS_WRITE_EXIT();
1423 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1424 unsigned conf, const char *name, const char *units)
1426 struct lprocfs_counter *c;
1428 unsigned int num_cpu;
1430 LASSERT(stats != NULL);
1432 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
1434 for (i = 0; i < num_cpu; i++) {
1435 c = &(stats->ls_percpu[i]->lp_cntr[index]);
1436 c->lc_config = conf;
1439 c->lc_min = LC_MIN_INIT;
1442 c->lc_units = units;
1445 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
1447 EXPORT_SYMBOL(lprocfs_counter_init);
1449 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1451 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1452 LASSERT(coffset < stats->ls_num); \
1453 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1456 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1458 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1459 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1460 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1461 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1462 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1463 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1467 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1468 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1469 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1470 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1471 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1472 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1473 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1474 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1475 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1476 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1477 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1478 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1479 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1480 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1481 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1482 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1483 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1484 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1485 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1486 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1487 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1488 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1489 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1490 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1491 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1492 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1493 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1494 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1495 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1496 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1497 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1498 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1499 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1500 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1501 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1502 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1503 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1504 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1505 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1506 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1507 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1508 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1509 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1510 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1511 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1512 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1513 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1514 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1515 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1516 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1517 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1518 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1519 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1520 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1521 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1522 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1523 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1524 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1525 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1526 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1529 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1531 struct lprocfs_stats *stats;
1532 unsigned int num_stats;
1535 LASSERT(obd->obd_stats == NULL);
1536 LASSERT(obd->obd_proc_entry != NULL);
1537 LASSERT(obd->obd_cntr_base == 0);
1539 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1540 num_private_stats - 1 /* o_owner */;
1541 stats = lprocfs_alloc_stats(num_stats, 0);
1545 lprocfs_init_ops_stats(num_private_stats, stats);
1547 for (i = num_private_stats; i < num_stats; i++) {
1548 /* If this LBUGs, it is likely that an obd
1549 * operation was added to struct obd_ops in
1550 * <obd.h>, and that the corresponding line item
1551 * LPROCFS_OBD_OP_INIT(.., .., opname)
1552 * is missing from the list above. */
1553 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1554 "Missing obd_stat initializer obd_op "
1555 "operation at offset %d.\n", i - num_private_stats);
1557 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1559 lprocfs_free_stats(&stats);
1561 obd->obd_stats = stats;
1562 obd->obd_cntr_base = num_private_stats;
1567 void lprocfs_free_obd_stats(struct obd_device *obd)
1570 lprocfs_free_stats(&obd->obd_stats);
1573 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1575 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1576 LASSERT(coffset < stats->ls_num); \
1577 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1580 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1582 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1583 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1584 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1585 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1586 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1587 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1588 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1589 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1590 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1591 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1592 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1593 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1594 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1595 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1596 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1597 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1598 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1599 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1600 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1601 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1602 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1603 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1604 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1605 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1606 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1607 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1608 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1609 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1610 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1611 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1612 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1613 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1616 int lprocfs_alloc_md_stats(struct obd_device *obd,
1617 unsigned num_private_stats)
1619 struct lprocfs_stats *stats;
1620 unsigned int num_stats;
1623 LASSERT(obd->md_stats == NULL);
1624 LASSERT(obd->obd_proc_entry != NULL);
1625 LASSERT(obd->md_cntr_base == 0);
1627 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1629 stats = lprocfs_alloc_stats(num_stats, 0);
1633 lprocfs_init_mps_stats(num_private_stats, stats);
1635 for (i = num_private_stats; i < num_stats; i++) {
1636 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1637 CERROR("Missing md_stat initializer md_op "
1638 "operation at offset %d. Aborting.\n",
1639 i - num_private_stats);
1643 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1645 lprocfs_free_stats(&stats);
1647 obd->md_stats = stats;
1648 obd->md_cntr_base = num_private_stats;
1653 void lprocfs_free_md_stats(struct obd_device *obd)
1655 struct lprocfs_stats *stats = obd->md_stats;
1657 if (stats != NULL) {
1658 obd->md_stats = NULL;
1659 obd->md_cntr_base = 0;
1660 lprocfs_free_stats(&stats);
1664 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1666 lprocfs_counter_init(ldlm_stats,
1667 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1668 0, "ldlm_enqueue", "reqs");
1669 lprocfs_counter_init(ldlm_stats,
1670 LDLM_CONVERT - LDLM_FIRST_OPC,
1671 0, "ldlm_convert", "reqs");
1672 lprocfs_counter_init(ldlm_stats,
1673 LDLM_CANCEL - LDLM_FIRST_OPC,
1674 0, "ldlm_cancel", "reqs");
1675 lprocfs_counter_init(ldlm_stats,
1676 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1677 0, "ldlm_bl_callback", "reqs");
1678 lprocfs_counter_init(ldlm_stats,
1679 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1680 0, "ldlm_cp_callback", "reqs");
1681 lprocfs_counter_init(ldlm_stats,
1682 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1683 0, "ldlm_gl_callback", "reqs");
1686 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1687 int *eof, void *data)
1689 struct obd_export *exp = data;
1690 LASSERT(exp != NULL);
1692 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1695 struct exp_uuid_cb_data {
1703 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1704 int count, int *eof, int *len)
1706 cb_data->page = page;
1707 cb_data->count = count;
1712 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1713 cfs_hlist_node_t *hnode, void *cb_data)
1716 struct obd_export *exp = cfs_hash_object(hs, hnode);
1717 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1719 if (exp->exp_nid_stats)
1720 *data->len += snprintf((data->page + *data->len),
1721 data->count, "%s\n",
1722 obd_uuid2str(&exp->exp_client_uuid));
1726 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1727 int *eof, void *data)
1729 struct nid_stat *stats = (struct nid_stat *)data;
1730 struct exp_uuid_cb_data cb_data;
1731 struct obd_device *obd = stats->nid_obd;
1736 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1737 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1738 lprocfs_exp_print_uuid, &cb_data);
1739 return (*cb_data.len);
1742 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1743 cfs_hlist_node_t *hnode, void *cb_data)
1746 struct exp_uuid_cb_data *data = cb_data;
1747 struct obd_export *exp = cfs_hash_object(hs, hnode);
1749 if (exp->exp_lock_hash != NULL) {
1751 *data->len += cfs_hash_debug_header(data->page,
1754 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1761 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1762 int *eof, void *data)
1764 struct nid_stat *stats = (struct nid_stat *)data;
1765 struct exp_uuid_cb_data cb_data;
1766 struct obd_device *obd = stats->nid_obd;
1771 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1773 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1774 lprocfs_exp_print_hash, &cb_data);
1775 return (*cb_data.len);
1778 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1779 int count, int *eof, void *data)
1782 return snprintf(page, count, "%s\n",
1783 "Write into this file to clear all nid stats and "
1784 "stale nid entries");
1786 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1788 static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1790 struct nid_stat *stat = obj;
1794 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1795 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1796 /* object has only hash references. */
1797 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1798 cfs_list_move(&stat->nid_list, data);
1799 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1802 /* we has reference to object - only clear data*/
1803 if (stat->nid_stats)
1804 lprocfs_clear_stats(stat->nid_stats);
1806 if (stat->nid_brw_stats) {
1807 for (i = 0; i < BRW_LAST; i++)
1808 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1813 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1814 unsigned long count, void *data)
1816 struct obd_device *obd = (struct obd_device *)data;
1817 struct nid_stat *client_stat;
1818 CFS_LIST_HEAD(free_list);
1820 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1821 lprocfs_nid_stats_clear_write_cb, &free_list);
1823 while (!cfs_list_empty(&free_list)) {
1824 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1826 cfs_list_del_init(&client_stat->nid_list);
1827 lprocfs_free_client_stats(client_stat);
1832 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1834 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1836 struct nid_stat *new_stat, *old_stat;
1837 struct obd_device *obd = NULL;
1838 cfs_proc_dir_entry_t *entry;
1839 char *buffer = NULL;
1845 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1846 !exp->exp_obd->obd_nid_stats_hash)
1849 /* not test against zero because eric say:
1850 * You may only test nid against another nid, or LNET_NID_ANY.
1851 * Anything else is nonsense.*/
1852 if (!nid || *nid == LNET_NID_ANY)
1857 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1859 OBD_ALLOC_PTR(new_stat);
1860 if (new_stat == NULL)
1863 new_stat->nid = *nid;
1864 new_stat->nid_obd = exp->exp_obd;
1865 /* we need set default refcount to 1 to balance obd_disconnect */
1866 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1868 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1869 nid, &new_stat->nid_hash);
1870 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1871 old_stat, libcfs_nid2str(*nid),
1872 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1874 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1875 * been and will never be called. */
1876 if (exp->exp_nid_stats) {
1877 nidstat_putref(exp->exp_nid_stats);
1878 exp->exp_nid_stats = NULL;
1881 /* Return -EALREADY here so that we know that the /proc
1882 * entry already has been created */
1883 if (old_stat != new_stat) {
1884 exp->exp_nid_stats = old_stat;
1885 GOTO(destroy_new, rc = -EALREADY);
1887 /* not found - create */
1888 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1890 GOTO(destroy_new, rc = -ENOMEM);
1892 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1893 new_stat->nid_proc = lprocfs_register(buffer,
1894 obd->obd_proc_exports_entry,
1896 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1898 if (new_stat->nid_proc == NULL) {
1899 CERROR("Error making export directory for nid %s\n",
1900 libcfs_nid2str(*nid));
1901 GOTO(destroy_new_ns, rc = -ENOMEM);
1904 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1905 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1906 if (IS_ERR(entry)) {
1907 CWARN("Error adding the NID stats file\n");
1908 rc = PTR_ERR(entry);
1909 GOTO(destroy_new_ns, rc);
1912 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1913 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1914 if (IS_ERR(entry)) {
1915 CWARN("Error adding the hash file\n");
1916 rc = PTR_ERR(entry);
1917 GOTO(destroy_new_ns, rc);
1920 exp->exp_nid_stats = new_stat;
1922 /* protect competitive add to list, not need locking on destroy */
1923 cfs_spin_lock(&obd->obd_nid_lock);
1924 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1925 cfs_spin_unlock(&obd->obd_nid_lock);
1930 if (new_stat->nid_proc != NULL)
1931 lprocfs_remove(&new_stat->nid_proc);
1932 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1935 nidstat_putref(new_stat);
1936 OBD_FREE_PTR(new_stat);
1940 int lprocfs_exp_cleanup(struct obd_export *exp)
1942 struct nid_stat *stat = exp->exp_nid_stats;
1944 if(!stat || !exp->exp_obd)
1947 nidstat_putref(exp->exp_nid_stats);
1948 exp->exp_nid_stats = NULL;
1953 int lprocfs_write_helper(const char *buffer, unsigned long count,
1956 return lprocfs_write_frac_helper(buffer, count, val, 1);
1959 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1962 char kernbuf[20], *end, *pbuf;
1964 if (count > (sizeof(kernbuf) - 1))
1967 if (cfs_copy_from_user(kernbuf, buffer, count))
1970 kernbuf[count] = '\0';
1977 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1981 if (end != NULL && *end == '.') {
1982 int temp_val, pow = 1;
1986 if (strlen(pbuf) > 5)
1987 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1989 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1992 for (i = 0; i < (end - pbuf); i++)
1995 *val += temp_val / pow;
2001 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
2004 long decimal_val, frac_val;
2010 decimal_val = val / mult;
2011 prtn = snprintf(buffer, count, "%ld", decimal_val);
2012 frac_val = val % mult;
2014 if (prtn < (count - 4) && frac_val > 0) {
2016 int i, temp_mult = 1, frac_bits = 0;
2018 temp_frac = frac_val * 10;
2019 buffer[prtn++] = '.';
2020 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2021 /* only reserved 2 bits fraction */
2022 buffer[prtn++] ='0';
2027 * Need to think these cases :
2028 * 1. #echo x.00 > /proc/xxx output result : x
2029 * 2. #echo x.0x > /proc/xxx output result : x.0x
2030 * 3. #echo x.x0 > /proc/xxx output result : x.x
2031 * 4. #echo x.xx > /proc/xxx output result : x.xx
2032 * Only reserved 2 bits fraction.
2034 for (i = 0; i < (5 - prtn); i++)
2037 frac_bits = min((int)count - prtn, 3 - frac_bits);
2038 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2039 frac_val * temp_mult / mult);
2042 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2044 if (buffer[prtn] == '.') {
2051 buffer[prtn++] ='\n';
2055 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2057 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2060 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2061 __u64 *val, int mult)
2063 char kernbuf[22], *end, *pbuf;
2064 __u64 whole, frac = 0, units;
2065 unsigned frac_d = 1;
2067 if (count > (sizeof(kernbuf) - 1))
2070 if (cfs_copy_from_user(kernbuf, buffer, count))
2073 kernbuf[count] = '\0';
2080 whole = simple_strtoull(pbuf, &end, 10);
2084 if (end != NULL && *end == '.') {
2088 /* need to limit frac_d to a __u32 */
2089 if (strlen(pbuf) > 10)
2092 frac = simple_strtoull(pbuf, &end, 10);
2093 /* count decimal places */
2094 for (i = 0; i < (end - pbuf); i++)
2111 /* Specified units override the multiplier */
2113 mult = mult < 0 ? -units : units;
2116 do_div(frac, frac_d);
2117 *val = whole * mult + frac;
2121 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2122 struct file_operations *seq_fops, void *data)
2124 struct proc_dir_entry *entry;
2127 LPROCFS_WRITE_ENTRY();
2128 entry = create_proc_entry(name, mode, parent);
2130 entry->proc_fops = seq_fops;
2133 LPROCFS_WRITE_EXIT();
2140 EXPORT_SYMBOL(lprocfs_seq_create);
2142 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2144 struct file_operations *seq_fops,
2147 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2148 mode, seq_fops, data));
2150 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2152 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2154 if (value >= OBD_HIST_MAX)
2155 value = OBD_HIST_MAX - 1;
2157 cfs_spin_lock(&oh->oh_lock);
2158 oh->oh_buckets[value]++;
2159 cfs_spin_unlock(&oh->oh_lock);
2161 EXPORT_SYMBOL(lprocfs_oh_tally);
2163 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2167 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2170 lprocfs_oh_tally(oh, val);
2172 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2174 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2176 unsigned long ret = 0;
2179 for (i = 0; i < OBD_HIST_MAX; i++)
2180 ret += oh->oh_buckets[i];
2183 EXPORT_SYMBOL(lprocfs_oh_sum);
2185 void lprocfs_oh_clear(struct obd_histogram *oh)
2187 cfs_spin_lock(&oh->oh_lock);
2188 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2189 cfs_spin_unlock(&oh->oh_lock);
2191 EXPORT_SYMBOL(lprocfs_oh_clear);
2193 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2194 int count, int *eof, void *data)
2196 struct obd_device *obd = data;
2202 c += cfs_hash_debug_header(page, count);
2203 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2204 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2205 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2206 #ifdef HAVE_QUOTA_SUPPORT
2207 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2208 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2209 page + c, count - c);
2214 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2216 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2217 int count, int *eof, void *data)
2219 struct obd_device *obd = data;
2222 LASSERT(obd != NULL);
2223 LASSERT(count >= 0);
2225 /* Set start of user data returned to
2226 page + off since the user may have
2227 requested to read much smaller than
2228 what we need to read */
2229 *start = page + off;
2231 /* We know we are allocated a page here.
2232 Also we know that this function will
2233 not need to write more than a page
2234 so we can truncate at CFS_PAGE_SIZE. */
2235 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2237 /* Initialize the page */
2238 memset(page, 0, size);
2240 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2242 if (obd->obd_max_recoverable_clients == 0) {
2243 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2249 /* sampled unlocked, but really... */
2250 if (obd->obd_recovering == 0) {
2251 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2253 if (lprocfs_obd_snprintf(&page, size, &len,
2254 "recovery_start: %lu\n",
2255 obd->obd_recovery_start) <= 0)
2257 if (lprocfs_obd_snprintf(&page, size, &len,
2258 "recovery_duration: %lu\n",
2259 obd->obd_recovery_end -
2260 obd->obd_recovery_start) <= 0)
2262 /* Number of clients that have completed recovery */
2263 if (lprocfs_obd_snprintf(&page, size, &len,
2264 "completed_clients: %d/%d\n",
2265 obd->obd_max_recoverable_clients -
2266 obd->obd_stale_clients,
2267 obd->obd_max_recoverable_clients) <= 0)
2269 if (lprocfs_obd_snprintf(&page, size, &len,
2270 "replayed_requests: %d\n",
2271 obd->obd_replayed_requests) <= 0)
2273 if (lprocfs_obd_snprintf(&page, size, &len,
2274 "last_transno: "LPD64"\n",
2275 obd->obd_next_recovery_transno - 1)<=0)
2277 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2278 obd->obd_version_recov ? "ON" : "OFF")<=0)
2280 if (lprocfs_obd_snprintf(&page, size, &len, "IR: %s\n",
2281 obd->obd_no_ir ? "OFF" : "ON") <= 0)
2286 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2288 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2289 obd->obd_recovery_start) <= 0)
2291 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2292 cfs_time_current_sec() >=
2293 obd->obd_recovery_start +
2294 obd->obd_recovery_timeout ? 0 :
2295 obd->obd_recovery_start +
2296 obd->obd_recovery_timeout -
2297 cfs_time_current_sec()) <= 0)
2299 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2300 cfs_atomic_read(&obd->obd_connected_clients),
2301 obd->obd_max_recoverable_clients) <= 0)
2303 /* Number of clients that have completed recovery */
2304 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2305 cfs_atomic_read(&obd->obd_req_replay_clients))
2308 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2309 cfs_atomic_read(&obd->obd_lock_replay_clients))
2312 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2313 cfs_atomic_read(&obd->obd_connected_clients) -
2314 cfs_atomic_read(&obd->obd_lock_replay_clients))
2317 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2318 obd->obd_stale_clients) <= 0)
2320 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2321 obd->obd_replayed_requests) <= 0)
2323 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2324 obd->obd_requests_queued_for_recovery) <= 0)
2327 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2328 obd->obd_next_recovery_transno) <= 0)
2334 return min(count, len - (int)off);
2336 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2338 int lprocfs_obd_rd_ir_factor(char *page, char **start, off_t off,
2339 int count, int *eof, void *data)
2341 struct obd_device *obd = (struct obd_device *)data;
2342 LASSERT(obd != NULL);
2344 return snprintf(page, count, "%d\n",
2345 obd->obd_recovery_ir_factor);
2347 EXPORT_SYMBOL(lprocfs_obd_rd_ir_factor);
2349 int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer,
2350 unsigned long count, void *data)
2352 struct obd_device *obd = (struct obd_device *)data;
2354 LASSERT(obd != NULL);
2356 rc = lprocfs_write_helper(buffer, count, &val);
2360 if (val < OBD_IR_FACTOR_MIN || val > OBD_IR_FACTOR_MAX)
2363 obd->obd_recovery_ir_factor = val;
2366 EXPORT_SYMBOL(lprocfs_obd_wr_ir_factor);
2368 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2369 int count, int *eof, void *data)
2371 struct obd_device *obd = (struct obd_device *)data;
2372 LASSERT(obd != NULL);
2374 return snprintf(page, count, "%d\n",
2375 obd->obd_recovery_timeout);
2377 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2379 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2380 unsigned long count, void *data)
2382 struct obd_device *obd = (struct obd_device *)data;
2384 LASSERT(obd != NULL);
2386 rc = lprocfs_write_helper(buffer, count, &val);
2390 obd->obd_recovery_timeout = val;
2393 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2395 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2396 int count, int *eof, void *data)
2398 struct obd_device *obd = data;
2399 LASSERT(obd != NULL);
2401 return snprintf(page, count, "%u\n", obd->obd_recovery_time_hard);
2403 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2405 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2406 unsigned long count, void *data)
2408 struct obd_device *obd = data;
2410 LASSERT(obd != NULL);
2412 rc = lprocfs_write_helper(buffer, count, &val);
2416 obd->obd_recovery_time_hard = val;
2419 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2421 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2422 int count, int *eof, void *data)
2424 struct obd_device *obd = (struct obd_device *)data;
2426 LASSERT(obd != NULL);
2427 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2429 return snprintf(page, count, "%s\n",
2430 obd->u.obt.obt_vfsmnt->mnt_devname);
2432 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2434 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2435 int count, int *eof, void *data)
2437 struct obd_device *dev = data;
2438 struct client_obd *cli = &dev->u.cli;
2441 client_obd_list_lock(&cli->cl_loi_list_lock);
2442 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2443 client_obd_list_unlock(&cli->cl_loi_list_lock);
2446 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2448 int lprocfs_obd_wr_max_pages_per_rpc(struct file *file, const char *buffer,
2449 unsigned long count, void *data)
2451 struct obd_device *dev = data;
2452 struct client_obd *cli = &dev->u.cli;
2453 struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
2456 rc = lprocfs_write_helper(buffer, count, &val);
2460 LPROCFS_CLIMP_CHECK(dev);
2461 if (val < 1 || val > ocd->ocd_brw_size >> CFS_PAGE_SHIFT) {
2462 LPROCFS_CLIMP_EXIT(dev);
2465 client_obd_list_lock(&cli->cl_loi_list_lock);
2466 cli->cl_max_pages_per_rpc = val;
2467 client_obd_list_unlock(&cli->cl_loi_list_lock);
2469 LPROCFS_CLIMP_EXIT(dev);
2472 EXPORT_SYMBOL(lprocfs_obd_wr_max_pages_per_rpc);
2474 int lprocfs_target_rd_instance(char *page, char **start, off_t off,
2475 int count, int *eof, void *data)
2477 struct obd_device *obd = (struct obd_device *)data;
2478 struct obd_device_target *target = &obd->u.obt;
2480 LASSERT(obd != NULL);
2481 LASSERT(target->obt_magic == OBT_MAGIC);
2483 return snprintf(page, count, "%u\n", obd->u.obt.obt_instance);
2485 EXPORT_SYMBOL(lprocfs_target_rd_instance);
2487 EXPORT_SYMBOL(lprocfs_register);
2488 EXPORT_SYMBOL(lprocfs_srch);
2489 EXPORT_SYMBOL(lprocfs_remove);
2490 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2491 EXPORT_SYMBOL(lprocfs_add_vars);
2492 EXPORT_SYMBOL(lprocfs_obd_setup);
2493 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2494 EXPORT_SYMBOL(lprocfs_add_simple);
2495 EXPORT_SYMBOL(lprocfs_add_symlink);
2496 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2497 EXPORT_SYMBOL(lprocfs_alloc_stats);
2498 EXPORT_SYMBOL(lprocfs_free_stats);
2499 EXPORT_SYMBOL(lprocfs_clear_stats);
2500 EXPORT_SYMBOL(lprocfs_register_stats);
2501 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2502 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2503 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2504 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2505 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2506 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2507 EXPORT_SYMBOL(lprocfs_free_md_stats);
2508 EXPORT_SYMBOL(lprocfs_exp_setup);
2509 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2511 EXPORT_SYMBOL(lprocfs_rd_u64);
2512 EXPORT_SYMBOL(lprocfs_rd_atomic);
2513 EXPORT_SYMBOL(lprocfs_wr_atomic);
2514 EXPORT_SYMBOL(lprocfs_rd_uint);
2515 EXPORT_SYMBOL(lprocfs_wr_uint);
2516 EXPORT_SYMBOL(lprocfs_rd_uuid);
2517 EXPORT_SYMBOL(lprocfs_rd_name);
2518 EXPORT_SYMBOL(lprocfs_rd_fstype);
2519 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2520 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2521 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2522 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2523 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2524 EXPORT_SYMBOL(lprocfs_rd_import);
2525 EXPORT_SYMBOL(lprocfs_rd_state);
2526 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2527 EXPORT_SYMBOL(lprocfs_rd_blksize);
2528 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2529 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2530 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2531 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2532 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2534 EXPORT_SYMBOL(lprocfs_write_helper);
2535 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2536 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2537 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2538 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2539 EXPORT_SYMBOL(lprocfs_stats_collect);