1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
30 * Use is subject to license terms.
33 * Copyright (c) 2011 Whamcloud, Inc.
36 * This file is part of Lustre, http://www.lustre.org/
37 * Lustre is a trademark of Sun Microsystems, Inc.
39 * lustre/obdclass/lprocfs_status.c
41 * Author: Hariharan Thantry <thantry@users.sourceforge.net>
45 # define EXPORT_SYMTAB
47 #define DEBUG_SUBSYSTEM S_CLASS
50 # include <liblustre.h>
53 #include <obd_class.h>
54 #include <lprocfs_status.h>
55 #include <lustre_fsfilt.h>
56 #include <lustre_log.h>
57 #include <lustre/lustre_idl.h>
61 static int lprocfs_no_percpu_stats = 0;
62 CFS_MODULE_PARM(lprocfs_no_percpu_stats, "i", int, 0644,
63 "Do not alloc percpu data for lprocfs stats");
65 #define MAX_STRING_SIZE 128
67 /* for bug 10866, global variable */
68 CFS_DECLARE_RWSEM(_lprocfs_lock);
69 EXPORT_SYMBOL(_lprocfs_lock);
71 int lprocfs_seq_release(struct inode *inode, struct file *file)
74 return seq_release(inode, file);
76 EXPORT_SYMBOL(lprocfs_seq_release);
78 static struct proc_dir_entry *__lprocfs_srch(struct proc_dir_entry *head,
81 struct proc_dir_entry *temp;
87 while (temp != NULL) {
88 if (strcmp(temp->name, name) == 0) {
97 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
100 struct proc_dir_entry *temp;
102 LPROCFS_SRCH_ENTRY();
103 temp = __lprocfs_srch(head, name);
108 /* lprocfs API calls */
110 /* Function that emulates snprintf but also has the side effect of advancing
111 the page pointer for the next write into the buffer, incrementing the total
112 length written to the buffer, and decrementing the size left in the
114 static int lprocfs_obd_snprintf(char **page, int end, int *len,
115 const char *format, ...)
123 va_start(list, format);
124 n = vsnprintf(*page, end - *len, format, list);
127 *page += n; *len += n;
131 cfs_proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
133 read_proc_t *read_proc,
134 write_proc_t *write_proc,
136 struct file_operations *fops)
138 cfs_proc_dir_entry_t *proc;
141 if (root == NULL || name == NULL)
142 return ERR_PTR(-EINVAL);
149 LPROCFS_WRITE_ENTRY();
150 proc = create_proc_entry(name, mode, root);
152 CERROR("LprocFS: No memory to create /proc entry %s", name);
153 LPROCFS_WRITE_EXIT();
154 return ERR_PTR(-ENOMEM);
156 proc->read_proc = read_proc;
157 proc->write_proc = write_proc;
160 proc->proc_fops = fops;
161 LPROCFS_WRITE_EXIT();
165 struct proc_dir_entry *lprocfs_add_symlink(const char *name,
166 struct proc_dir_entry *parent, const char *format, ...)
168 struct proc_dir_entry *entry;
172 if (parent == NULL || format == NULL)
175 OBD_ALLOC_WAIT(dest, MAX_STRING_SIZE + 1);
179 va_start(ap, format);
180 vsnprintf(dest, MAX_STRING_SIZE, format, ap);
183 entry = proc_symlink(name, parent, dest);
185 CERROR("LprocFS: Could not create symbolic link from %s to %s",
188 OBD_FREE(dest, MAX_STRING_SIZE + 1);
192 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
193 size_t size, loff_t *ppos)
195 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
196 char *page, *start = NULL;
197 int rc = 0, eof = 1, count;
199 if (*ppos >= CFS_PAGE_SIZE)
202 page = (char *)__get_free_page(GFP_KERNEL);
206 if (LPROCFS_ENTRY_AND_CHECK(dp)) {
211 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
213 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
219 /* for lustre proc read, the read count must be less than PAGE_SIZE */
228 start = page + *ppos;
229 } else if (start < page) {
233 count = (rc < size) ? rc : size;
234 if (cfs_copy_to_user(buf, start, count)) {
241 free_page((unsigned long)page);
245 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
246 size_t size, loff_t *ppos)
248 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
251 if (LPROCFS_ENTRY_AND_CHECK(dp))
254 rc = dp->write_proc(f, buf, size, dp->data);
259 static struct file_operations lprocfs_generic_fops = {
260 .owner = THIS_MODULE,
261 .read = lprocfs_fops_read,
262 .write = lprocfs_fops_write,
265 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
267 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
268 struct obd_device *obd = dp->data;
270 cfs_atomic_inc(&obd->obd_evict_inprogress);
275 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
277 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
278 struct obd_device *obd = dp->data;
280 cfs_atomic_dec(&obd->obd_evict_inprogress);
281 cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
286 struct file_operations lprocfs_evict_client_fops = {
287 .owner = THIS_MODULE,
288 .read = lprocfs_fops_read,
289 .write = lprocfs_fops_write,
290 .open = lprocfs_evict_client_open,
291 .release = lprocfs_evict_client_release,
293 EXPORT_SYMBOL(lprocfs_evict_client_fops);
298 * \param root [in] The parent proc entry on which new entry will be added.
299 * \param list [in] Array of proc entries to be added.
300 * \param data [in] The argument to be passed when entries read/write routines
301 * are called through /proc file.
303 * \retval 0 on success
306 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
311 if (root == NULL || list == NULL)
314 LPROCFS_WRITE_ENTRY();
315 while (list->name != NULL) {
316 struct proc_dir_entry *cur_root, *proc;
317 char *pathcopy, *cur, *next, pathbuf[64];
318 int pathsize = strlen(list->name) + 1;
323 /* need copy of path for strsep */
324 if (strlen(list->name) > sizeof(pathbuf) - 1) {
325 OBD_ALLOC(pathcopy, pathsize);
326 if (pathcopy == NULL)
327 GOTO(out, rc = -ENOMEM);
333 strcpy(pathcopy, list->name);
335 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
336 if (*cur =='\0') /* skip double/trailing "/" */
339 proc = __lprocfs_srch(cur_root, cur);
340 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
341 cur_root->name, cur, next,
342 (proc ? "exists" : "new"));
344 cur_root = (proc ? proc :
345 proc_mkdir(cur, cur_root));
346 } else if (proc == NULL) {
348 if (list->proc_mode != 0000) {
349 mode = list->proc_mode;
353 if (list->write_fptr)
356 proc = create_proc_entry(cur, mode, cur_root);
360 if (pathcopy != pathbuf)
361 OBD_FREE(pathcopy, pathsize);
363 if (cur_root == NULL || proc == NULL) {
364 CERROR("LprocFS: No memory to create /proc entry %s",
366 GOTO(out, rc = -ENOMEM);
370 proc->proc_fops = list->fops;
372 proc->proc_fops = &lprocfs_generic_fops;
373 proc->read_proc = list->read_fptr;
374 proc->write_proc = list->write_fptr;
375 proc->data = (list->data ? list->data : data);
379 LPROCFS_WRITE_EXIT();
383 void lprocfs_remove(struct proc_dir_entry **rooth)
385 struct proc_dir_entry *root = *rooth;
386 struct proc_dir_entry *temp = root;
387 struct proc_dir_entry *rm_entry;
388 struct proc_dir_entry *parent;
394 parent = root->parent;
395 LASSERT(parent != NULL);
396 LPROCFS_WRITE_ENTRY(); /* search vs remove race */
399 while (temp->subdir != NULL)
405 /* Memory corruption once caused this to fail, and
406 without this LASSERT we would loop here forever. */
407 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
408 "0x%p %s/%s len %d\n", rm_entry, temp->name,
409 rm_entry->name, (int)strlen(rm_entry->name));
411 #ifdef HAVE_PROCFS_USERS
412 /* if procfs uses user count to synchronize deletion of
413 * proc entry, there is no protection for rm_entry->data,
414 * then lprocfs_fops_read and lprocfs_fops_write maybe
415 * call proc_dir_entry->read_proc (or write_proc) with
416 * proc_dir_entry->data == NULL, then cause kernel Oops.
417 * see bug19706 for detailed information */
419 /* procfs won't free rm_entry->data if it isn't a LINK,
420 * and Lustre won't use rm_entry->data if it is a LINK */
421 if (S_ISLNK(rm_entry->mode))
422 rm_entry->data = NULL;
424 /* Now, the rm_entry->deleted flags is protected
425 * by _lprocfs_lock. */
426 rm_entry->data = NULL;
428 remove_proc_entry(rm_entry->name, temp);
432 LPROCFS_WRITE_EXIT();
435 void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
437 LASSERT(parent != NULL);
438 remove_proc_entry(name, parent);
441 struct proc_dir_entry *lprocfs_register(const char *name,
442 struct proc_dir_entry *parent,
443 struct lprocfs_vars *list, void *data)
445 struct proc_dir_entry *newchild;
447 newchild = lprocfs_srch(parent, name);
448 if (newchild != NULL) {
449 CERROR(" Lproc: Attempting to register %s more than once \n",
451 return ERR_PTR(-EALREADY);
454 newchild = proc_mkdir(name, parent);
455 if (newchild != NULL && list != NULL) {
456 int rc = lprocfs_add_vars(newchild, list, data);
458 lprocfs_remove(&newchild);
465 /* Generic callbacks */
466 int lprocfs_rd_uint(char *page, char **start, off_t off,
467 int count, int *eof, void *data)
469 unsigned int *temp = data;
470 return snprintf(page, count, "%u\n", *temp);
473 int lprocfs_wr_uint(struct file *file, const char *buffer,
474 unsigned long count, void *data)
477 char dummy[MAX_STRING_SIZE + 1], *end;
480 dummy[MAX_STRING_SIZE] = '\0';
481 if (cfs_copy_from_user(dummy, buffer, MAX_STRING_SIZE))
484 tmp = simple_strtoul(dummy, &end, 0);
488 *p = (unsigned int)tmp;
492 int lprocfs_rd_u64(char *page, char **start, off_t off,
493 int count, int *eof, void *data)
495 LASSERT(data != NULL);
497 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
500 int lprocfs_rd_atomic(char *page, char **start, off_t off,
501 int count, int *eof, void *data)
503 cfs_atomic_t *atom = data;
504 LASSERT(atom != NULL);
506 return snprintf(page, count, "%d\n", cfs_atomic_read(atom));
509 int lprocfs_wr_atomic(struct file *file, const char *buffer,
510 unsigned long count, void *data)
512 cfs_atomic_t *atm = data;
516 rc = lprocfs_write_helper(buffer, count, &val);
523 cfs_atomic_set(atm, val);
527 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
528 int *eof, void *data)
530 struct obd_device *obd = data;
532 LASSERT(obd != NULL);
534 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
537 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
538 int *eof, void *data)
540 struct obd_device *dev = data;
542 LASSERT(dev != NULL);
543 LASSERT(dev->obd_name != NULL);
545 return snprintf(page, count, "%s\n", dev->obd_name);
548 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
551 struct obd_device *obd = data;
553 LASSERT(obd != NULL);
554 LASSERT(obd->obd_fsops != NULL);
555 LASSERT(obd->obd_fsops->fs_type != NULL);
556 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
559 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
560 int *eof, void *data)
562 struct obd_statfs osfs;
563 int rc = obd_statfs(data, &osfs,
564 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
568 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
573 int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
574 int *eof, void *data)
576 struct obd_statfs osfs;
577 int rc = obd_statfs(data, &osfs,
578 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
581 __u32 blk_size = osfs.os_bsize >> 10;
582 __u64 result = osfs.os_blocks;
584 while (blk_size >>= 1)
588 rc = snprintf(page, count, LPU64"\n", result);
593 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
594 int *eof, void *data)
596 struct obd_statfs osfs;
597 int rc = obd_statfs(data, &osfs,
598 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
601 __u32 blk_size = osfs.os_bsize >> 10;
602 __u64 result = osfs.os_bfree;
604 while (blk_size >>= 1)
608 rc = snprintf(page, count, LPU64"\n", result);
613 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
614 int *eof, void *data)
616 struct obd_statfs osfs;
617 int rc = obd_statfs(data, &osfs,
618 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
621 __u32 blk_size = osfs.os_bsize >> 10;
622 __u64 result = osfs.os_bavail;
624 while (blk_size >>= 1)
628 rc = snprintf(page, count, LPU64"\n", result);
633 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
634 int *eof, void *data)
636 struct obd_statfs osfs;
637 int rc = obd_statfs(data, &osfs,
638 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
642 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
648 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
649 int *eof, void *data)
651 struct obd_statfs osfs;
652 int rc = obd_statfs(data, &osfs,
653 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
657 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
662 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
663 int *eof, void *data)
665 struct obd_device *obd = data;
666 struct obd_import *imp;
667 char *imp_state_name = NULL;
670 LASSERT(obd != NULL);
671 LPROCFS_CLIMP_CHECK(obd);
672 imp = obd->u.cli.cl_import;
673 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
675 rc = snprintf(page, count, "%s\t%s%s\n",
676 obd2cli_tgt(obd), imp_state_name,
677 imp->imp_deactive ? "\tDEACTIVATED" : "");
679 LPROCFS_CLIMP_EXIT(obd);
683 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
684 int *eof, void *data)
686 struct obd_device *obd = data;
687 struct ptlrpc_connection *conn;
690 LASSERT(obd != NULL);
692 LPROCFS_CLIMP_CHECK(obd);
693 conn = obd->u.cli.cl_import->imp_connection;
695 if (conn && obd->u.cli.cl_import) {
696 rc = snprintf(page, count, "%s\n",
697 conn->c_remote_uuid.uuid);
699 rc = snprintf(page, count, "%s\n", "<none>");
702 LPROCFS_CLIMP_EXIT(obd);
706 /** add up per-cpu counters */
707 void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
708 struct lprocfs_counter *cnt)
710 unsigned int num_entry;
711 struct lprocfs_counter t;
712 struct lprocfs_counter *percpu_cntr;
715 unsigned long flags = 0;
717 memset(cnt, 0, sizeof(*cnt));
720 /* set count to 1 to avoid divide-by-zero errs in callers */
725 cnt->lc_min = LC_MIN_INIT;
727 num_entry = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
729 for (i = 0; i < num_entry; i++) {
730 if (stats->ls_percpu[i] == NULL)
732 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
735 centry = cfs_atomic_read(&percpu_cntr-> \
737 t.lc_count = percpu_cntr->lc_count;
738 t.lc_sum = percpu_cntr->lc_sum;
739 t.lc_min = percpu_cntr->lc_min;
740 t.lc_max = percpu_cntr->lc_max;
741 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
742 } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
744 centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \
746 cnt->lc_count += t.lc_count;
747 cnt->lc_sum += t.lc_sum;
748 if (t.lc_min < cnt->lc_min)
749 cnt->lc_min = t.lc_min;
750 if (t.lc_max > cnt->lc_max)
751 cnt->lc_max = t.lc_max;
752 cnt->lc_sumsquare += t.lc_sumsquare;
755 cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
756 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
760 * Append a space separated list of current set flags to str.
762 #define flag2str(flag) \
763 if (imp->imp_##flag && max - len > 0) \
764 len += snprintf(str + len, max - len, "%s" #flag, len ? ", " : "");
765 static int obd_import_flags2str(struct obd_import *imp, char *str, int max)
769 if (imp->imp_obd->obd_no_recov)
770 len += snprintf(str, max - len, "no_recov");
774 flag2str(replayable);
780 static const char *obd_connect_names[] = {
794 "join_file(obsolete)",
798 "remote_client_by_force",
807 "mds_mds_connection",
810 "alt_checksum_algorithm",
833 int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
838 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
840 ret += snprintf(page + ret, count - ret, "%s%s",
841 ret ? sep : "", obd_connect_names[i]);
843 if (flags & ~(mask - 1))
844 ret += snprintf(page + ret, count - ret,
845 "%sunknown flags "LPX64,
846 ret ? sep : "", flags & ~(mask - 1));
849 EXPORT_SYMBOL(obd_connect_flags2str);
851 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
852 int *eof, void *data)
854 struct lprocfs_counter ret;
855 struct obd_device *obd = (struct obd_device *)data;
856 struct obd_import *imp;
857 struct obd_import_conn *conn;
860 LASSERT(obd != NULL);
861 LPROCFS_CLIMP_CHECK(obd);
862 imp = obd->u.cli.cl_import;
865 i = snprintf(page, count,
873 ptlrpc_import_state_name(imp->imp_state));
874 i += obd_connect_flags2str(page + i, count - i,
875 imp->imp_connect_data.ocd_connect_flags,
877 i += snprintf(page + i, count - i,
880 i += obd_import_flags2str(imp, page + i, count - i);
882 i += snprintf(page + i, count - i,
885 " failover_nids: [");
886 cfs_spin_lock(&imp->imp_lock);
888 cfs_list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
889 i += snprintf(page + i, count - i, "%s%s", j ? ", " : "",
890 libcfs_nid2str(conn->oic_conn->c_peer.nid));
893 cfs_spin_unlock(&imp->imp_lock);
894 i += snprintf(page + i, count - i,
896 " current_connection: %s\n"
897 " connection_attempts: %u\n"
899 " in-progress_invalidations: %u\n",
900 libcfs_nid2str(imp->imp_connection->c_peer.nid),
903 cfs_atomic_read(&imp->imp_inval_count));
905 lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
906 if (ret.lc_count != 0) {
907 /* first argument to do_div MUST be __u64 */
908 __u64 sum = ret.lc_sum;
909 do_div(sum, ret.lc_count);
913 i += snprintf(page + i, count - i,
916 " unregistering: %u\n"
918 " avg_waittime: "LPU64" %s\n",
919 cfs_atomic_read(&imp->imp_inflight),
920 cfs_atomic_read(&imp->imp_unregistering),
921 cfs_atomic_read(&imp->imp_timeouts),
922 ret.lc_sum, ret.lc_units);
925 for(j = 0; j < IMP_AT_MAX_PORTALS; j++) {
926 if (imp->imp_at.iat_portal[j] == 0)
928 k = max_t(unsigned int, k,
929 at_get(&imp->imp_at.iat_service_estimate[j]));
931 i += snprintf(page + i, count - i,
932 " service_estimates:\n"
933 " services: %u sec\n"
934 " network: %u sec\n",
936 at_get(&imp->imp_at.iat_net_latency));
938 i += snprintf(page + i, count - i,
940 " last_replay: "LPU64"\n"
941 " peer_committed: "LPU64"\n"
942 " last_checked: "LPU64"\n",
943 imp->imp_last_replay_transno,
944 imp->imp_peer_committed_transno,
945 imp->imp_last_transno_checked);
948 for (rw = 0; rw <= 1; rw++) {
949 lprocfs_stats_collect(obd->obd_svc_stats,
950 PTLRPC_LAST_CNTR + BRW_READ_BYTES + rw,
952 if (ret.lc_sum > 0 && ret.lc_count > 0) {
953 /* first argument to do_div MUST be __u64 */
954 __u64 sum = ret.lc_sum;
955 do_div(sum, ret.lc_count);
957 i += snprintf(page + i, count - i,
958 " %s_data_averages:\n"
959 " bytes_per_rpc: "LPU64"\n",
960 rw ? "write" : "read",
964 j = opcode_offset(OST_READ + rw) + EXTRA_MAX_OPCODES;
965 lprocfs_stats_collect(obd->obd_svc_stats, j, &ret);
966 if (ret.lc_sum > 0 && ret.lc_count != 0) {
967 /* first argument to do_div MUST be __u64 */
968 __u64 sum = ret.lc_sum;
969 do_div(sum, ret.lc_count);
971 i += snprintf(page + i, count - i,
972 " %s_per_rpc: "LPU64"\n",
973 ret.lc_units, ret.lc_sum);
976 i += snprintf(page + i, count - i,
977 " MB_per_sec: %u.%.02u\n",
978 k / j, (100 * k / j) % 100);
982 LPROCFS_CLIMP_EXIT(obd);
986 int lprocfs_rd_state(char *page, char **start, off_t off, int count,
987 int *eof, void *data)
989 struct obd_device *obd = (struct obd_device *)data;
990 struct obd_import *imp;
993 LASSERT(obd != NULL);
994 LPROCFS_CLIMP_CHECK(obd);
995 imp = obd->u.cli.cl_import;
998 i = snprintf(page, count, "current_state: %s\n",
999 ptlrpc_import_state_name(imp->imp_state));
1000 i += snprintf(page + i, count - i,
1001 "state_history:\n");
1002 k = imp->imp_state_hist_idx;
1003 for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
1004 struct import_state_hist *ish =
1005 &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
1006 if (ish->ish_state == 0)
1008 i += snprintf(page + i, count - i, " - ["CFS_TIME_T", %s]\n",
1010 ptlrpc_import_state_name(ish->ish_state));
1013 LPROCFS_CLIMP_EXIT(obd);
1017 int lprocfs_at_hist_helper(char *page, int count, int rc,
1018 struct adaptive_timeout *at)
1021 for (i = 0; i < AT_BINS; i++)
1022 rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
1023 rc += snprintf(page + rc, count - rc, "\n");
1027 /* See also ptlrpc_lprocfs_rd_timeouts */
1028 int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
1029 int *eof, void *data)
1031 struct obd_device *obd = (struct obd_device *)data;
1032 struct obd_import *imp;
1033 unsigned int cur, worst;
1038 LASSERT(obd != NULL);
1039 LPROCFS_CLIMP_CHECK(obd);
1040 imp = obd->u.cli.cl_import;
1043 now = cfs_time_current_sec();
1045 /* Some network health info for kicks */
1046 s2dhms(&ts, now - imp->imp_last_reply_time);
1047 rc += snprintf(page + rc, count - rc,
1048 "%-10s : %ld, "DHMS_FMT" ago\n",
1049 "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
1051 cur = at_get(&imp->imp_at.iat_net_latency);
1052 worst = imp->imp_at.iat_net_latency.at_worst_ever;
1053 worstt = imp->imp_at.iat_net_latency.at_worst_time;
1054 s2dhms(&ts, now - worstt);
1055 rc += snprintf(page + rc, count - rc,
1056 "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
1057 "network", cur, worst, worstt, DHMS_VARS(&ts));
1058 rc = lprocfs_at_hist_helper(page, count, rc,
1059 &imp->imp_at.iat_net_latency);
1061 for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
1062 if (imp->imp_at.iat_portal[i] == 0)
1064 cur = at_get(&imp->imp_at.iat_service_estimate[i]);
1065 worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
1066 worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
1067 s2dhms(&ts, now - worstt);
1068 rc += snprintf(page + rc, count - rc,
1069 "portal %-2d : cur %3u worst %3u (at %ld, "
1070 DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
1071 cur, worst, worstt, DHMS_VARS(&ts));
1072 rc = lprocfs_at_hist_helper(page, count, rc,
1073 &imp->imp_at.iat_service_estimate[i]);
1076 LPROCFS_CLIMP_EXIT(obd);
1080 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
1081 int count, int *eof, void *data)
1083 struct obd_device *obd = data;
1087 LPROCFS_CLIMP_CHECK(obd);
1088 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
1089 ret = snprintf(page, count, "flags="LPX64"\n", flags);
1090 ret += obd_connect_flags2str(page + ret, count - ret, flags, "\n");
1091 ret += snprintf(page + ret, count - ret, "\n");
1092 LPROCFS_CLIMP_EXIT(obd);
1095 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
1097 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
1098 int *eof, void *data)
1100 struct obd_device *obd = data;
1102 LASSERT(obd != NULL);
1104 return snprintf(page, count, "%u\n", obd->obd_num_exports);
1107 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
1108 int *eof, void *data)
1110 struct obd_type *class = (struct obd_type*) data;
1112 LASSERT(class != NULL);
1114 return snprintf(page, count, "%d\n", class->typ_refcnt);
1117 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
1121 LASSERT(obd != NULL);
1122 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1123 LASSERT(obd->obd_type->typ_procroot != NULL);
1125 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1126 obd->obd_type->typ_procroot,
1128 if (IS_ERR(obd->obd_proc_entry)) {
1129 rc = PTR_ERR(obd->obd_proc_entry);
1130 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
1131 obd->obd_proc_entry = NULL;
1136 int lprocfs_obd_cleanup(struct obd_device *obd)
1140 if (obd->obd_proc_exports_entry) {
1141 /* Should be no exports left */
1142 LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
1143 lprocfs_remove(&obd->obd_proc_exports_entry);
1144 obd->obd_proc_exports_entry = NULL;
1146 if (obd->obd_proc_entry) {
1147 lprocfs_remove(&obd->obd_proc_entry);
1148 obd->obd_proc_entry = NULL;
1153 static void lprocfs_free_client_stats(struct nid_stat *client_stat)
1155 CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
1156 client_stat->nid_proc, client_stat->nid_stats,
1157 client_stat->nid_brw_stats);
1159 LASSERTF(cfs_atomic_read(&client_stat->nid_exp_ref_count) == 0,
1160 "nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
1161 atomic_read(&client_stat->nid_exp_ref_count));
1163 if (client_stat->nid_proc)
1164 lprocfs_remove(&client_stat->nid_proc);
1166 if (client_stat->nid_stats)
1167 lprocfs_free_stats(&client_stat->nid_stats);
1169 if (client_stat->nid_brw_stats)
1170 OBD_FREE_PTR(client_stat->nid_brw_stats);
1172 if (client_stat->nid_ldlm_stats)
1173 lprocfs_free_stats(&client_stat->nid_ldlm_stats);
1175 OBD_FREE_PTR(client_stat);
1180 void lprocfs_free_per_client_stats(struct obd_device *obd)
1182 cfs_hash_t *hash = obd->obd_nid_stats_hash;
1183 struct nid_stat *stat;
1186 /* we need extra list - because hash_exit called to early */
1187 /* not need locking because all clients is died */
1188 while (!cfs_list_empty(&obd->obd_nid_stats)) {
1189 stat = cfs_list_entry(obd->obd_nid_stats.next,
1190 struct nid_stat, nid_list);
1191 cfs_list_del_init(&stat->nid_list);
1192 cfs_hash_del(hash, &stat->nid, &stat->nid_hash);
1193 lprocfs_free_client_stats(stat);
1198 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
1199 enum lprocfs_stats_flags flags)
1201 struct lprocfs_stats *stats;
1202 unsigned int percpusize;
1203 unsigned int num_entry;
1208 if (lprocfs_no_percpu_stats != 0)
1209 flags |= LPROCFS_STATS_FLAG_NOPERCPU;
1211 if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
1214 num_entry = cfs_num_possible_cpus() + 1;
1216 /* alloc percpu pointers for all possible cpu slots */
1217 OBD_ALLOC(stats, offsetof(struct lprocfs_stats, ls_percpu[num_entry]));
1221 stats->ls_num = num;
1222 stats->ls_biggest_alloc_num = 1;
1223 stats->ls_flags = flags;
1224 cfs_spin_lock_init(&stats->ls_lock);
1226 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
1228 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1230 /* for no percpu area, the 0th entry is for real use,
1231 * for percpu area, the 0th entry is for intialized entry template */
1232 OBD_ALLOC(stats->ls_percpu[0], percpusize);
1233 if (stats->ls_percpu[0] == NULL) {
1235 offsetof(struct lprocfs_stats, ls_percpu[num_entry]));
1241 void lprocfs_free_stats(struct lprocfs_stats **statsh)
1243 struct lprocfs_stats *stats = *statsh;
1244 unsigned int num_entry;
1245 unsigned int percpusize;
1248 if (stats == NULL || stats->ls_num == 0)
1252 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
1255 num_entry = cfs_num_possible_cpus() + 1;
1257 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
1259 percpusize = CFS_L1_CACHE_ALIGN(percpusize);
1260 for (i = 0; i < num_entry; i++)
1261 if (stats->ls_percpu[i] != NULL)
1262 OBD_FREE(stats->ls_percpu[i], percpusize);
1263 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_entry]));
1266 void lprocfs_clear_stats(struct lprocfs_stats *stats)
1268 struct lprocfs_counter *percpu_cntr;
1271 unsigned int num_entry;
1272 unsigned long flags = 0;
1274 num_entry = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
1276 for (i = 0; i < num_entry; i++) {
1277 if (stats->ls_percpu[i] == NULL)
1279 for (j = 0; j < stats->ls_num; j++) {
1280 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
1281 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
1282 percpu_cntr->lc_count = 0;
1283 percpu_cntr->lc_sum = 0;
1284 percpu_cntr->lc_min = LC_MIN_INIT;
1285 percpu_cntr->lc_max = 0;
1286 percpu_cntr->lc_sumsquare = 0;
1287 cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
1291 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
1294 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
1295 size_t len, loff_t *off)
1297 struct seq_file *seq = file->private_data;
1298 struct lprocfs_stats *stats = seq->private;
1300 lprocfs_clear_stats(stats);
1305 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
1307 struct lprocfs_stats *stats = p->private;
1308 /* return 1st cpu location */
1309 return (*pos >= stats->ls_num) ? NULL :
1310 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1313 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
1317 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
1319 struct lprocfs_stats *stats = p->private;
1321 return (*pos >= stats->ls_num) ? NULL :
1322 &(stats->ls_percpu[0]->lp_cntr[*pos]);
1325 /* seq file export of one lprocfs counter */
1326 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
1328 struct lprocfs_stats *stats = p->private;
1329 struct lprocfs_counter *cntr = v;
1330 struct lprocfs_counter ret;
1333 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
1335 cfs_gettimeofday(&now);
1336 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
1337 "snapshot_time", now.tv_sec, now.tv_usec);
1341 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
1343 lprocfs_stats_collect(stats, idx, &ret);
1345 if (ret.lc_count == 0)
1348 rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
1349 ret.lc_count, cntr->lc_units);
1354 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
1355 rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
1356 ret.lc_min, ret.lc_max, ret.lc_sum);
1359 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
1360 rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
1364 rc = seq_printf(p, "\n");
1366 return (rc < 0) ? rc : 0;
1369 struct seq_operations lprocfs_stats_seq_sops = {
1370 start: lprocfs_stats_seq_start,
1371 stop: lprocfs_stats_seq_stop,
1372 next: lprocfs_stats_seq_next,
1373 show: lprocfs_stats_seq_show,
1376 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
1378 struct proc_dir_entry *dp = PDE(inode);
1379 struct seq_file *seq;
1382 if (LPROCFS_ENTRY_AND_CHECK(dp))
1385 rc = seq_open(file, &lprocfs_stats_seq_sops);
1390 seq = file->private_data;
1391 seq->private = dp->data;
1395 struct file_operations lprocfs_stats_seq_fops = {
1396 .owner = THIS_MODULE,
1397 .open = lprocfs_stats_seq_open,
1399 .write = lprocfs_stats_seq_write,
1400 .llseek = seq_lseek,
1401 .release = lprocfs_seq_release,
1404 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
1405 struct lprocfs_stats *stats)
1407 struct proc_dir_entry *entry;
1408 LASSERT(root != NULL);
1410 LPROCFS_WRITE_ENTRY();
1411 entry = create_proc_entry(name, 0644, root);
1413 entry->proc_fops = &lprocfs_stats_seq_fops;
1414 entry->data = stats;
1417 LPROCFS_WRITE_EXIT();
1425 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
1426 unsigned conf, const char *name, const char *units)
1428 struct lprocfs_counter *c = &(stats->ls_percpu[0]->lp_cntr[index]);
1429 unsigned long flags = 0;
1431 LASSERT(stats != NULL);
1432 LASSERT(stats->ls_percpu[0] != NULL);
1434 lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
1435 c->lc_config = conf;
1438 c->lc_min = LC_MIN_INIT;
1441 c->lc_units = units;
1442 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
1444 EXPORT_SYMBOL(lprocfs_counter_init);
1446 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
1448 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
1449 LASSERT(coffset < stats->ls_num); \
1450 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1453 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
1455 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
1456 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
1457 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
1458 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
1459 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
1460 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
1461 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
1462 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
1463 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
1464 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
1465 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
1466 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
1467 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
1468 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
1469 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
1470 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
1471 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
1472 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
1473 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
1474 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
1475 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
1476 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
1477 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
1478 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
1479 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
1480 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
1481 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create_async);
1482 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
1483 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
1484 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
1485 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
1486 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
1487 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
1488 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
1489 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
1490 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
1491 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
1492 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
1493 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
1494 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
1495 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
1496 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
1497 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
1498 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
1499 LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
1500 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
1501 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
1502 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
1503 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
1504 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
1505 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
1506 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
1507 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
1508 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
1509 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
1510 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
1511 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
1512 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
1513 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid);
1514 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
1515 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
1516 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
1517 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
1518 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new);
1519 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
1520 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
1521 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
1522 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
1523 LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
1526 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
1528 struct lprocfs_stats *stats;
1529 unsigned int num_stats;
1532 LASSERT(obd->obd_stats == NULL);
1533 LASSERT(obd->obd_proc_entry != NULL);
1534 LASSERT(obd->obd_cntr_base == 0);
1536 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
1537 num_private_stats - 1 /* o_owner */;
1538 stats = lprocfs_alloc_stats(num_stats, 0);
1542 lprocfs_init_ops_stats(num_private_stats, stats);
1544 for (i = num_private_stats; i < num_stats; i++) {
1545 /* If this LBUGs, it is likely that an obd
1546 * operation was added to struct obd_ops in
1547 * <obd.h>, and that the corresponding line item
1548 * LPROCFS_OBD_OP_INIT(.., .., opname)
1549 * is missing from the list above. */
1550 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1551 "Missing obd_stat initializer obd_op "
1552 "operation at offset %d.\n", i - num_private_stats);
1554 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1556 lprocfs_free_stats(&stats);
1558 obd->obd_stats = stats;
1559 obd->obd_cntr_base = num_private_stats;
1564 void lprocfs_free_obd_stats(struct obd_device *obd)
1567 lprocfs_free_stats(&obd->obd_stats);
1570 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1572 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1573 LASSERT(coffset < stats->ls_num); \
1574 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1577 void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
1579 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1580 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1581 LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
1582 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1583 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1584 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1585 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1586 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1587 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1588 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1589 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1590 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1591 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1592 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1593 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1594 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1595 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1596 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1597 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1598 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1599 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1600 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1601 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1602 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1603 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1604 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1605 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1606 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1607 LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
1608 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1609 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
1610 LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
1613 int lprocfs_alloc_md_stats(struct obd_device *obd,
1614 unsigned num_private_stats)
1616 struct lprocfs_stats *stats;
1617 unsigned int num_stats;
1620 LASSERT(obd->md_stats == NULL);
1621 LASSERT(obd->obd_proc_entry != NULL);
1622 LASSERT(obd->md_cntr_base == 0);
1624 num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
1626 stats = lprocfs_alloc_stats(num_stats, 0);
1630 lprocfs_init_mps_stats(num_private_stats, stats);
1632 for (i = num_private_stats; i < num_stats; i++) {
1633 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1634 CERROR("Missing md_stat initializer md_op "
1635 "operation at offset %d. Aborting.\n",
1636 i - num_private_stats);
1640 rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
1642 lprocfs_free_stats(&stats);
1644 obd->md_stats = stats;
1645 obd->md_cntr_base = num_private_stats;
1650 void lprocfs_free_md_stats(struct obd_device *obd)
1652 struct lprocfs_stats *stats = obd->md_stats;
1654 if (stats != NULL) {
1655 obd->md_stats = NULL;
1656 obd->md_cntr_base = 0;
1657 lprocfs_free_stats(&stats);
1661 void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
1663 lprocfs_counter_init(ldlm_stats,
1664 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1665 0, "ldlm_enqueue", "reqs");
1666 lprocfs_counter_init(ldlm_stats,
1667 LDLM_CONVERT - LDLM_FIRST_OPC,
1668 0, "ldlm_convert", "reqs");
1669 lprocfs_counter_init(ldlm_stats,
1670 LDLM_CANCEL - LDLM_FIRST_OPC,
1671 0, "ldlm_cancel", "reqs");
1672 lprocfs_counter_init(ldlm_stats,
1673 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1674 0, "ldlm_bl_callback", "reqs");
1675 lprocfs_counter_init(ldlm_stats,
1676 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1677 0, "ldlm_cp_callback", "reqs");
1678 lprocfs_counter_init(ldlm_stats,
1679 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1680 0, "ldlm_gl_callback", "reqs");
1683 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1684 int *eof, void *data)
1686 struct obd_export *exp = data;
1687 LASSERT(exp != NULL);
1689 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1692 struct exp_uuid_cb_data {
1700 lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
1701 int count, int *eof, int *len)
1703 cb_data->page = page;
1704 cb_data->count = count;
1709 int lprocfs_exp_print_uuid(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1710 cfs_hlist_node_t *hnode, void *cb_data)
1713 struct obd_export *exp = cfs_hash_object(hs, hnode);
1714 struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
1716 if (exp->exp_nid_stats)
1717 *data->len += snprintf((data->page + *data->len),
1718 data->count, "%s\n",
1719 obd_uuid2str(&exp->exp_client_uuid));
1723 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1724 int *eof, void *data)
1726 struct nid_stat *stats = (struct nid_stat *)data;
1727 struct exp_uuid_cb_data cb_data;
1728 struct obd_device *obd = stats->nid_obd;
1733 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1734 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1735 lprocfs_exp_print_uuid, &cb_data);
1736 return (*cb_data.len);
1739 int lprocfs_exp_print_hash(cfs_hash_t *hs, cfs_hash_bd_t *bd,
1740 cfs_hlist_node_t *hnode, void *cb_data)
1743 struct exp_uuid_cb_data *data = cb_data;
1744 struct obd_export *exp = cfs_hash_object(hs, hnode);
1746 if (exp->exp_lock_hash != NULL) {
1748 *data->len += cfs_hash_debug_header(data->page,
1751 *data->len += cfs_hash_debug_str(hs, data->page + *data->len,
1758 int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
1759 int *eof, void *data)
1761 struct nid_stat *stats = (struct nid_stat *)data;
1762 struct exp_uuid_cb_data cb_data;
1763 struct obd_device *obd = stats->nid_obd;
1768 lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
1770 cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
1771 lprocfs_exp_print_hash, &cb_data);
1772 return (*cb_data.len);
1775 int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
1776 int count, int *eof, void *data)
1779 return snprintf(page, count, "%s\n",
1780 "Write into this file to clear all nid stats and "
1781 "stale nid entries");
1783 EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
1785 static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
1787 struct nid_stat *stat = obj;
1791 CDEBUG(D_INFO,"refcnt %d\n", cfs_atomic_read(&stat->nid_exp_ref_count));
1792 if (cfs_atomic_read(&stat->nid_exp_ref_count) == 1) {
1793 /* object has only hash references. */
1794 cfs_spin_lock(&stat->nid_obd->obd_nid_lock);
1795 cfs_list_move(&stat->nid_list, data);
1796 cfs_spin_unlock(&stat->nid_obd->obd_nid_lock);
1799 /* we has reference to object - only clear data*/
1800 if (stat->nid_stats)
1801 lprocfs_clear_stats(stat->nid_stats);
1803 if (stat->nid_brw_stats) {
1804 for (i = 0; i < BRW_LAST; i++)
1805 lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
1810 int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
1811 unsigned long count, void *data)
1813 struct obd_device *obd = (struct obd_device *)data;
1814 struct nid_stat *client_stat;
1815 CFS_LIST_HEAD(free_list);
1817 cfs_hash_cond_del(obd->obd_nid_stats_hash,
1818 lprocfs_nid_stats_clear_write_cb, &free_list);
1820 while (!cfs_list_empty(&free_list)) {
1821 client_stat = cfs_list_entry(free_list.next, struct nid_stat,
1823 cfs_list_del_init(&client_stat->nid_list);
1824 lprocfs_free_client_stats(client_stat);
1829 EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
1831 int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
1833 struct nid_stat *new_stat, *old_stat;
1834 struct obd_device *obd = NULL;
1835 cfs_proc_dir_entry_t *entry;
1836 char *buffer = NULL;
1842 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
1843 !exp->exp_obd->obd_nid_stats_hash)
1846 /* not test against zero because eric say:
1847 * You may only test nid against another nid, or LNET_NID_ANY.
1848 * Anything else is nonsense.*/
1849 if (!nid || *nid == LNET_NID_ANY)
1854 CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
1856 OBD_ALLOC_PTR(new_stat);
1857 if (new_stat == NULL)
1860 new_stat->nid = *nid;
1861 new_stat->nid_obd = exp->exp_obd;
1862 /* we need set default refcount to 1 to balance obd_disconnect */
1863 cfs_atomic_set(&new_stat->nid_exp_ref_count, 1);
1865 old_stat = cfs_hash_findadd_unique(obd->obd_nid_stats_hash,
1866 nid, &new_stat->nid_hash);
1867 CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
1868 old_stat, libcfs_nid2str(*nid),
1869 cfs_atomic_read(&new_stat->nid_exp_ref_count));
1871 /* We need to release old stats because lprocfs_exp_cleanup() hasn't
1872 * been and will never be called. */
1873 if (exp->exp_nid_stats) {
1874 nidstat_putref(exp->exp_nid_stats);
1875 exp->exp_nid_stats = NULL;
1878 /* Return -EALREADY here so that we know that the /proc
1879 * entry already has been created */
1880 if (old_stat != new_stat) {
1881 exp->exp_nid_stats = old_stat;
1882 GOTO(destroy_new, rc = -EALREADY);
1884 /* not found - create */
1885 OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
1887 GOTO(destroy_new, rc = -ENOMEM);
1889 memcpy(buffer, libcfs_nid2str(*nid), LNET_NIDSTR_SIZE);
1890 new_stat->nid_proc = lprocfs_register(buffer,
1891 obd->obd_proc_exports_entry,
1893 OBD_FREE(buffer, LNET_NIDSTR_SIZE);
1895 if (new_stat->nid_proc == NULL) {
1896 CERROR("Error making export directory for nid %s\n",
1897 libcfs_nid2str(*nid));
1898 GOTO(destroy_new_ns, rc = -ENOMEM);
1901 entry = lprocfs_add_simple(new_stat->nid_proc, "uuid",
1902 lprocfs_exp_rd_uuid, NULL, new_stat, NULL);
1903 if (IS_ERR(entry)) {
1904 CWARN("Error adding the NID stats file\n");
1905 rc = PTR_ERR(entry);
1906 GOTO(destroy_new_ns, rc);
1909 entry = lprocfs_add_simple(new_stat->nid_proc, "hash",
1910 lprocfs_exp_rd_hash, NULL, new_stat, NULL);
1911 if (IS_ERR(entry)) {
1912 CWARN("Error adding the hash file\n");
1913 rc = PTR_ERR(entry);
1914 GOTO(destroy_new_ns, rc);
1917 exp->exp_nid_stats = new_stat;
1919 /* protect competitive add to list, not need locking on destroy */
1920 cfs_spin_lock(&obd->obd_nid_lock);
1921 cfs_list_add(&new_stat->nid_list, &obd->obd_nid_stats);
1922 cfs_spin_unlock(&obd->obd_nid_lock);
1927 if (new_stat->nid_proc != NULL)
1928 lprocfs_remove(&new_stat->nid_proc);
1929 cfs_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
1932 nidstat_putref(new_stat);
1933 OBD_FREE_PTR(new_stat);
1937 int lprocfs_exp_cleanup(struct obd_export *exp)
1939 struct nid_stat *stat = exp->exp_nid_stats;
1941 if(!stat || !exp->exp_obd)
1944 nidstat_putref(exp->exp_nid_stats);
1945 exp->exp_nid_stats = NULL;
1950 int lprocfs_write_helper(const char *buffer, unsigned long count,
1953 return lprocfs_write_frac_helper(buffer, count, val, 1);
1956 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1959 char kernbuf[20], *end, *pbuf;
1961 if (count > (sizeof(kernbuf) - 1))
1964 if (cfs_copy_from_user(kernbuf, buffer, count))
1967 kernbuf[count] = '\0';
1974 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1978 if (end != NULL && *end == '.') {
1979 int temp_val, pow = 1;
1983 if (strlen(pbuf) > 5)
1984 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1986 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1989 for (i = 0; i < (end - pbuf); i++)
1992 *val += temp_val / pow;
1998 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
2001 long decimal_val, frac_val;
2007 decimal_val = val / mult;
2008 prtn = snprintf(buffer, count, "%ld", decimal_val);
2009 frac_val = val % mult;
2011 if (prtn < (count - 4) && frac_val > 0) {
2013 int i, temp_mult = 1, frac_bits = 0;
2015 temp_frac = frac_val * 10;
2016 buffer[prtn++] = '.';
2017 while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
2018 /* only reserved 2 bits fraction */
2019 buffer[prtn++] ='0';
2024 * Need to think these cases :
2025 * 1. #echo x.00 > /proc/xxx output result : x
2026 * 2. #echo x.0x > /proc/xxx output result : x.0x
2027 * 3. #echo x.x0 > /proc/xxx output result : x.x
2028 * 4. #echo x.xx > /proc/xxx output result : x.xx
2029 * Only reserved 2 bits fraction.
2031 for (i = 0; i < (5 - prtn); i++)
2034 frac_bits = min((int)count - prtn, 3 - frac_bits);
2035 prtn += snprintf(buffer + prtn, frac_bits, "%ld",
2036 frac_val * temp_mult / mult);
2039 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
2041 if (buffer[prtn] == '.') {
2048 buffer[prtn++] ='\n';
2052 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
2054 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
2057 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
2058 __u64 *val, int mult)
2060 char kernbuf[22], *end, *pbuf;
2061 __u64 whole, frac = 0, units;
2062 unsigned frac_d = 1;
2064 if (count > (sizeof(kernbuf) - 1))
2067 if (cfs_copy_from_user(kernbuf, buffer, count))
2070 kernbuf[count] = '\0';
2077 whole = simple_strtoull(pbuf, &end, 10);
2081 if (end != NULL && *end == '.') {
2085 /* need to limit frac_d to a __u32 */
2086 if (strlen(pbuf) > 10)
2089 frac = simple_strtoull(pbuf, &end, 10);
2090 /* count decimal places */
2091 for (i = 0; i < (end - pbuf); i++)
2108 /* Specified units override the multiplier */
2110 mult = mult < 0 ? -units : units;
2113 do_div(frac, frac_d);
2114 *val = whole * mult + frac;
2118 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name, mode_t mode,
2119 struct file_operations *seq_fops, void *data)
2121 struct proc_dir_entry *entry;
2124 LPROCFS_WRITE_ENTRY();
2125 entry = create_proc_entry(name, mode, parent);
2127 entry->proc_fops = seq_fops;
2130 LPROCFS_WRITE_EXIT();
2137 EXPORT_SYMBOL(lprocfs_seq_create);
2139 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
2141 struct file_operations *seq_fops,
2144 return (lprocfs_seq_create(dev->obd_proc_entry, name,
2145 mode, seq_fops, data));
2147 EXPORT_SYMBOL(lprocfs_obd_seq_create);
2149 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
2151 if (value >= OBD_HIST_MAX)
2152 value = OBD_HIST_MAX - 1;
2154 cfs_spin_lock(&oh->oh_lock);
2155 oh->oh_buckets[value]++;
2156 cfs_spin_unlock(&oh->oh_lock);
2158 EXPORT_SYMBOL(lprocfs_oh_tally);
2160 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
2164 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
2167 lprocfs_oh_tally(oh, val);
2169 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
2171 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
2173 unsigned long ret = 0;
2176 for (i = 0; i < OBD_HIST_MAX; i++)
2177 ret += oh->oh_buckets[i];
2180 EXPORT_SYMBOL(lprocfs_oh_sum);
2182 void lprocfs_oh_clear(struct obd_histogram *oh)
2184 cfs_spin_lock(&oh->oh_lock);
2185 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
2186 cfs_spin_unlock(&oh->oh_lock);
2188 EXPORT_SYMBOL(lprocfs_oh_clear);
2190 int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
2191 int count, int *eof, void *data)
2193 struct obd_device *obd = data;
2199 c += cfs_hash_debug_header(page, count);
2200 c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
2201 c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
2202 c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
2203 #ifdef HAVE_QUOTA_SUPPORT
2204 if (obd->u.obt.obt_qctxt.lqc_lqs_hash)
2205 c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash,
2206 page + c, count - c);
2211 EXPORT_SYMBOL(lprocfs_obd_rd_hash);
2213 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
2214 int count, int *eof, void *data)
2216 struct obd_device *obd = data;
2219 LASSERT(obd != NULL);
2220 LASSERT(count >= 0);
2222 /* Set start of user data returned to
2223 page + off since the user may have
2224 requested to read much smaller than
2225 what we need to read */
2226 *start = page + off;
2228 /* We know we are allocated a page here.
2229 Also we know that this function will
2230 not need to write more than a page
2231 so we can truncate at CFS_PAGE_SIZE. */
2232 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
2234 /* Initialize the page */
2235 memset(page, 0, size);
2237 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
2239 if (obd->obd_max_recoverable_clients == 0) {
2240 if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
2246 /* sampled unlocked, but really... */
2247 if (obd->obd_recovering == 0) {
2248 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
2250 if (lprocfs_obd_snprintf(&page, size, &len,
2251 "recovery_start: %lu\n",
2252 obd->obd_recovery_start) <= 0)
2254 if (lprocfs_obd_snprintf(&page, size, &len,
2255 "recovery_duration: %lu\n",
2256 obd->obd_recovery_end -
2257 obd->obd_recovery_start) <= 0)
2259 /* Number of clients that have completed recovery */
2260 if (lprocfs_obd_snprintf(&page, size, &len,
2261 "completed_clients: %d/%d\n",
2262 obd->obd_max_recoverable_clients -
2263 obd->obd_stale_clients,
2264 obd->obd_max_recoverable_clients) <= 0)
2266 if (lprocfs_obd_snprintf(&page, size, &len,
2267 "replayed_requests: %d\n",
2268 obd->obd_replayed_requests) <= 0)
2270 if (lprocfs_obd_snprintf(&page, size, &len,
2271 "last_transno: "LPD64"\n",
2272 obd->obd_next_recovery_transno - 1)<=0)
2274 if (lprocfs_obd_snprintf(&page, size, &len, "VBR: %s\n",
2275 obd->obd_version_recov ? "ON" : "OFF")<=0)
2280 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
2282 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
2283 obd->obd_recovery_start) <= 0)
2285 if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
2286 cfs_time_current_sec() >=
2287 obd->obd_recovery_start +
2288 obd->obd_recovery_timeout ? 0 :
2289 obd->obd_recovery_start +
2290 obd->obd_recovery_timeout -
2291 cfs_time_current_sec()) <= 0)
2293 if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
2294 obd->obd_connected_clients,
2295 obd->obd_max_recoverable_clients) <= 0)
2297 /* Number of clients that have completed recovery */
2298 if (lprocfs_obd_snprintf(&page, size, &len,"req_replay_clients: %d\n",
2299 cfs_atomic_read(&obd->obd_req_replay_clients))
2302 if (lprocfs_obd_snprintf(&page, size, &len,"lock_repay_clients: %d\n",
2303 cfs_atomic_read(&obd->obd_lock_replay_clients))
2306 if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d\n",
2307 obd->obd_connected_clients -
2308 cfs_atomic_read(&obd->obd_lock_replay_clients))
2311 if (lprocfs_obd_snprintf(&page, size, &len,"evicted_clients: %d\n",
2312 obd->obd_stale_clients) <= 0)
2314 if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d\n",
2315 obd->obd_replayed_requests) <= 0)
2317 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
2318 obd->obd_requests_queued_for_recovery) <= 0)
2321 if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
2322 obd->obd_next_recovery_transno) <= 0)
2328 return min(count, len - (int)off);
2330 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
2332 int lprocfs_obd_rd_recovery_time_soft(char *page, char **start, off_t off,
2333 int count, int *eof, void *data)
2335 struct obd_device *obd = (struct obd_device *)data;
2336 LASSERT(obd != NULL);
2338 return snprintf(page, count, "%d\n",
2339 obd->obd_recovery_timeout);
2341 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_soft);
2343 int lprocfs_obd_wr_recovery_time_soft(struct file *file, const char *buffer,
2344 unsigned long count, void *data)
2346 struct obd_device *obd = (struct obd_device *)data;
2348 LASSERT(obd != NULL);
2350 rc = lprocfs_write_helper(buffer, count, &val);
2354 obd->obd_recovery_timeout = val;
2357 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_soft);
2359 int lprocfs_obd_rd_recovery_time_hard(char *page, char **start, off_t off,
2360 int count, int *eof, void *data)
2362 struct obd_device *obd = data;
2363 LASSERT(obd != NULL);
2365 return snprintf(page, count, "%lu\n", obd->obd_recovery_time_hard);
2367 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_time_hard);
2369 int lprocfs_obd_wr_recovery_time_hard(struct file *file, const char *buffer,
2370 unsigned long count, void *data)
2372 struct obd_device *obd = data;
2374 LASSERT(obd != NULL);
2376 rc = lprocfs_write_helper(buffer, count, &val);
2380 obd->obd_recovery_time_hard = val;
2383 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_time_hard);
2385 int lprocfs_obd_rd_mntdev(char *page, char **start, off_t off,
2386 int count, int *eof, void *data)
2388 struct obd_device *obd = (struct obd_device *)data;
2390 LASSERT(obd != NULL);
2391 LASSERT(obd->u.obt.obt_vfsmnt->mnt_devname);
2393 return snprintf(page, count, "%s\n",
2394 obd->u.obt.obt_vfsmnt->mnt_devname);
2396 EXPORT_SYMBOL(lprocfs_obd_rd_mntdev);
2398 int lprocfs_obd_rd_max_pages_per_rpc(char *page, char **start, off_t off,
2399 int count, int *eof, void *data)
2401 struct obd_device *dev = data;
2402 struct client_obd *cli = &dev->u.cli;
2405 client_obd_list_lock(&cli->cl_loi_list_lock);
2406 rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
2407 client_obd_list_unlock(&cli->cl_loi_list_lock);
2410 EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
2412 int lprocfs_obd_wr_max_pages_per_rpc(struct file *file, const char *buffer,
2413 unsigned long count, void *data)
2415 struct obd_device *dev = data;
2416 struct client_obd *cli = &dev->u.cli;
2417 struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
2420 rc = lprocfs_write_helper(buffer, count, &val);
2424 LPROCFS_CLIMP_CHECK(dev);
2425 if (val < 1 || val > ocd->ocd_brw_size >> CFS_PAGE_SHIFT) {
2426 LPROCFS_CLIMP_EXIT(dev);
2429 client_obd_list_lock(&cli->cl_loi_list_lock);
2430 cli->cl_max_pages_per_rpc = val;
2431 client_obd_list_unlock(&cli->cl_loi_list_lock);
2433 LPROCFS_CLIMP_EXIT(dev);
2436 EXPORT_SYMBOL(lprocfs_obd_wr_max_pages_per_rpc);
2438 EXPORT_SYMBOL(lprocfs_register);
2439 EXPORT_SYMBOL(lprocfs_srch);
2440 EXPORT_SYMBOL(lprocfs_remove);
2441 EXPORT_SYMBOL(lprocfs_remove_proc_entry);
2442 EXPORT_SYMBOL(lprocfs_add_vars);
2443 EXPORT_SYMBOL(lprocfs_obd_setup);
2444 EXPORT_SYMBOL(lprocfs_obd_cleanup);
2445 EXPORT_SYMBOL(lprocfs_add_simple);
2446 EXPORT_SYMBOL(lprocfs_add_symlink);
2447 EXPORT_SYMBOL(lprocfs_free_per_client_stats);
2448 EXPORT_SYMBOL(lprocfs_alloc_stats);
2449 EXPORT_SYMBOL(lprocfs_free_stats);
2450 EXPORT_SYMBOL(lprocfs_clear_stats);
2451 EXPORT_SYMBOL(lprocfs_register_stats);
2452 EXPORT_SYMBOL(lprocfs_init_ops_stats);
2453 EXPORT_SYMBOL(lprocfs_init_mps_stats);
2454 EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
2455 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
2456 EXPORT_SYMBOL(lprocfs_alloc_md_stats);
2457 EXPORT_SYMBOL(lprocfs_free_obd_stats);
2458 EXPORT_SYMBOL(lprocfs_free_md_stats);
2459 EXPORT_SYMBOL(lprocfs_exp_setup);
2460 EXPORT_SYMBOL(lprocfs_exp_cleanup);
2462 EXPORT_SYMBOL(lprocfs_rd_u64);
2463 EXPORT_SYMBOL(lprocfs_rd_atomic);
2464 EXPORT_SYMBOL(lprocfs_wr_atomic);
2465 EXPORT_SYMBOL(lprocfs_rd_uint);
2466 EXPORT_SYMBOL(lprocfs_wr_uint);
2467 EXPORT_SYMBOL(lprocfs_rd_uuid);
2468 EXPORT_SYMBOL(lprocfs_rd_name);
2469 EXPORT_SYMBOL(lprocfs_rd_fstype);
2470 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
2471 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
2472 EXPORT_SYMBOL(lprocfs_rd_num_exports);
2473 EXPORT_SYMBOL(lprocfs_rd_numrefs);
2474 EXPORT_SYMBOL(lprocfs_at_hist_helper);
2475 EXPORT_SYMBOL(lprocfs_rd_import);
2476 EXPORT_SYMBOL(lprocfs_rd_state);
2477 EXPORT_SYMBOL(lprocfs_rd_timeouts);
2478 EXPORT_SYMBOL(lprocfs_rd_blksize);
2479 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
2480 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
2481 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
2482 EXPORT_SYMBOL(lprocfs_rd_filestotal);
2483 EXPORT_SYMBOL(lprocfs_rd_filesfree);
2485 EXPORT_SYMBOL(lprocfs_write_helper);
2486 EXPORT_SYMBOL(lprocfs_write_frac_helper);
2487 EXPORT_SYMBOL(lprocfs_read_frac_helper);
2488 EXPORT_SYMBOL(lprocfs_write_u64_helper);
2489 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
2490 EXPORT_SYMBOL(lprocfs_stats_collect);