1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002, 2003 Cluster File Systems, Inc.
5 * Author: Hariharan Thantry <thantry@users.sourceforge.net>
7 * This file is part of the Lustre file system, http://www.lustre.org
8 * Lustre is a trademark of Cluster File Systems, Inc.
10 * You may have signed or agreed to another license before downloading
11 * this software. If so, you are bound by the terms and conditions
12 * of that agreement, and the following does not apply to you. See the
13 * LICENSE file included with this distribution for more information.
15 * If you did not agree to a different license, then this copy of Lustre
16 * is open source software; you can redistribute it and/or modify it
17 * under the terms of version 2 of the GNU General Public License as
18 * published by the Free Software Foundation.
20 * In either case, Lustre is distributed in the hope that it will be
21 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
22 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * license text for more details.
27 # define EXPORT_SYMTAB
29 #define DEBUG_SUBSYSTEM S_CLASS
32 # include <liblustre.h>
35 #include <obd_class.h>
36 #include <lprocfs_status.h>
37 #include <lustre_fsfilt.h>
41 /* for bug 10866, global variable */
42 DECLARE_RWSEM(_lprocfs_lock);
43 EXPORT_SYMBOL(_lprocfs_lock);
45 int lprocfs_seq_release(struct inode *inode, struct file *file)
48 return seq_release(inode, file);
50 EXPORT_SYMBOL(lprocfs_seq_release);
52 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
55 struct proc_dir_entry *temp;
61 while (temp != NULL) {
62 if (strcmp(temp->name, name) == 0)
70 /* lprocfs API calls */
72 /* Function that emulates snprintf but also has the side effect of advancing
73 the page pointer for the next write into the buffer, incrementing the total
74 length written to the buffer, and decrementing the size left in the
76 static int lprocfs_obd_snprintf(char **page, int end, int *len,
77 const char *format, ...)
85 va_start(list, format);
86 n = vsnprintf(*page, end - *len, format, list);
89 *page += n; *len += n;
93 int lprocfs_add_simple(struct proc_dir_entry *root, char *name,
94 read_proc_t *read_proc, write_proc_t *write_proc,
97 struct proc_dir_entry *proc;
100 if (root == NULL || name == NULL)
106 proc = create_proc_entry(name, mode, root);
108 CERROR("LprocFS: No memory to create /proc entry %s", name);
111 proc->read_proc = read_proc;
112 proc->write_proc = write_proc;
117 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
118 size_t size, loff_t *ppos)
120 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
121 char *page, *start = NULL;
122 int rc = 0, eof = 1, count;
124 if (*ppos >= CFS_PAGE_SIZE)
127 page = (char *)__get_free_page(GFP_KERNEL);
132 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
133 if (!dp->deleted && dp->read_proc)
134 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
140 /* for lustre proc read, the read count must be less than PAGE_SIZE */
149 start = page + *ppos;
150 } else if (start < page) {
154 count = (rc < size) ? rc : size;
155 if (copy_to_user(buf, start, count)) {
162 free_page((unsigned long)page);
166 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf, size_t size, loff_t *ppos)
168 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
172 if (!dp->deleted && dp->write_proc)
173 rc = dp->write_proc(f, buf, size, dp->data);
178 static struct file_operations lprocfs_generic_fops = {
179 .owner = THIS_MODULE,
180 .read = lprocfs_fops_read,
181 .write = lprocfs_fops_write,
184 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
186 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
187 struct obd_device *obd = dp->data;
189 atomic_inc(&obd->obd_evict_inprogress);
194 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
196 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
197 struct obd_device *obd = dp->data;
199 atomic_dec(&obd->obd_evict_inprogress);
200 wake_up(&obd->obd_evict_inprogress_waitq);
205 struct file_operations lprocfs_evict_client_fops = {
206 .owner = THIS_MODULE,
207 .read = lprocfs_fops_read,
208 .write = lprocfs_fops_write,
209 .open = lprocfs_evict_client_open,
210 .release = lprocfs_evict_client_release,
212 EXPORT_SYMBOL(lprocfs_evict_client_fops);
214 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
217 if (root == NULL || list == NULL)
220 while (list->name != NULL) {
221 struct proc_dir_entry *cur_root, *proc;
222 char *pathcopy, *cur, *next, pathbuf[64];
223 int pathsize = strlen(list->name) + 1;
228 /* need copy of path for strsep */
229 if (strlen(list->name) > sizeof(pathbuf) - 1) {
230 OBD_ALLOC(pathcopy, pathsize);
231 if (pathcopy == NULL)
238 strcpy(pathcopy, list->name);
240 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
241 if (*cur =='\0') /* skip double/trailing "/" */
244 proc = lprocfs_srch(cur_root, cur);
245 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
246 cur_root->name, cur, next,
247 (proc ? "exists" : "new"));
249 cur_root = (proc ? proc :
250 proc_mkdir(cur, cur_root));
251 } else if (proc == NULL) {
255 if (list->write_fptr)
257 proc = create_proc_entry(cur, mode, cur_root);
261 if (pathcopy != pathbuf)
262 OBD_FREE(pathcopy, pathsize);
264 if (cur_root == NULL || proc == NULL) {
265 CERROR("LprocFS: No memory to create /proc entry %s",
271 proc->proc_fops = list->fops;
273 proc->proc_fops = &lprocfs_generic_fops;
274 proc->read_proc = list->read_fptr;
275 proc->write_proc = list->write_fptr;
276 proc->data = (list->data ? list->data : data);
282 void lprocfs_remove(struct proc_dir_entry **rooth)
284 struct proc_dir_entry *root = *rooth;
285 struct proc_dir_entry *temp = root;
286 struct proc_dir_entry *rm_entry;
287 struct proc_dir_entry *parent;
293 parent = root->parent;
294 LASSERT(parent != NULL);
297 while (temp->subdir != NULL)
303 /* Memory corruption once caused this to fail, and
304 without this LASSERT we would loop here forever. */
305 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
306 "0x%p %s/%s len %d\n", rm_entry, temp->name,
307 rm_entry->name, (int)strlen(rm_entry->name));
309 /* Now, the rm_entry->deleted flags is protected
310 * by _lprocfs_lock. */
311 down_write(&_lprocfs_lock);
312 rm_entry->data = NULL;
313 remove_proc_entry(rm_entry->name, rm_entry->parent);
314 up_write(&_lprocfs_lock);
320 struct proc_dir_entry *lprocfs_register(const char *name,
321 struct proc_dir_entry *parent,
322 struct lprocfs_vars *list, void *data)
324 struct proc_dir_entry *newchild;
326 newchild = lprocfs_srch(parent, name);
327 if (newchild != NULL) {
328 CERROR(" Lproc: Attempting to register %s more than once \n",
330 return ERR_PTR(-EALREADY);
333 newchild = proc_mkdir(name, parent);
334 if (newchild != NULL && list != NULL) {
335 int rc = lprocfs_add_vars(newchild, list, data);
337 lprocfs_remove(&newchild);
344 /* Generic callbacks */
346 int lprocfs_rd_u64(char *page, char **start, off_t off,
347 int count, int *eof, void *data)
349 LASSERT(data != NULL);
351 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
354 int lprocfs_rd_atomic(char *page, char **start, off_t off,
355 int count, int *eof, void *data)
357 atomic_t *atom = (atomic_t *)data;
358 LASSERT(atom != NULL);
360 return snprintf(page, count, "%d\n", atomic_read(atom));
363 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
364 int *eof, void *data)
366 struct obd_device *obd = (struct obd_device*)data;
368 LASSERT(obd != NULL);
370 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
373 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
374 int *eof, void* data)
376 struct obd_device *dev = (struct obd_device *)data;
378 LASSERT(dev != NULL);
379 LASSERT(dev->obd_name != NULL);
381 return snprintf(page, count, "%s\n", dev->obd_name);
384 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
387 struct obd_device *obd = (struct obd_device *)data;
389 LASSERT(obd != NULL);
390 LASSERT(obd->obd_fsops != NULL);
391 LASSERT(obd->obd_fsops->fs_type != NULL);
392 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
395 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
396 int *eof, void *data)
398 struct obd_statfs osfs;
399 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ);
402 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
407 int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
408 int *eof, void *data)
410 struct obd_statfs osfs;
411 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ);
413 __u32 blk_size = osfs.os_bsize >> 10;
414 __u64 result = osfs.os_blocks;
416 while (blk_size >>= 1)
420 rc = snprintf(page, count, LPU64"\n", result);
425 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
426 int *eof, void *data)
428 struct obd_statfs osfs;
429 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ);
431 __u32 blk_size = osfs.os_bsize >> 10;
432 __u64 result = osfs.os_bfree;
434 while (blk_size >>= 1)
438 rc = snprintf(page, count, LPU64"\n", result);
443 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
444 int *eof, void *data)
446 struct obd_statfs osfs;
447 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ);
449 __u32 blk_size = osfs.os_bsize >> 10;
450 __u64 result = osfs.os_bavail;
452 while (blk_size >>= 1)
456 rc = snprintf(page, count, LPU64"\n", result);
461 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
462 int *eof, void *data)
464 struct obd_statfs osfs;
465 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ);
468 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
474 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
475 int *eof, void *data)
477 struct obd_statfs osfs;
478 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ);
481 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
486 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
487 int *eof, void *data)
489 struct obd_device *obd = (struct obd_device *)data;
490 struct obd_import *imp;
491 char *imp_state_name = NULL;
494 LASSERT(obd != NULL);
495 LPROCFS_CLIMP_CHECK(obd);
496 imp = obd->u.cli.cl_import;
497 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
499 rc = snprintf(page, count, "%s\t%s%s\n",
500 obd2cli_tgt(obd), imp_state_name,
501 imp->imp_deactive ? "\tDEACTIVATED" : "");
503 LPROCFS_CLIMP_EXIT(obd);
507 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
508 int *eof, void *data)
510 struct obd_device *obd = (struct obd_device*)data;
511 struct ptlrpc_connection *conn;
514 LASSERT(obd != NULL);
516 LPROCFS_CLIMP_CHECK(obd);
517 conn = obd->u.cli.cl_import->imp_connection;
518 LASSERT(conn != NULL);
520 if (obd->u.cli.cl_import) {
521 rc = snprintf(page, count, "%s\n",
522 conn->c_remote_uuid.uuid);
524 rc = snprintf(page, count, "%s\n", "<none>");
527 LPROCFS_CLIMP_EXIT(obd);
531 static const char *obd_connect_names[] = {
554 "mds_mds_connection",
559 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
560 int count, int *eof, void *data)
562 struct obd_device *obd = data;
563 __u64 mask = 1, flags;
566 LPROCFS_CLIMP_CHECK(obd);
567 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
568 ret = snprintf(page, count, "flags="LPX64"\n", flags);
569 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
571 ret += snprintf(page + ret, count - ret, "%s\n",
572 obd_connect_names[i]);
574 if (flags & ~(mask - 1))
575 ret += snprintf(page + ret, count - ret,
576 "unknown flags "LPX64"\n", flags & ~(mask - 1));
578 LPROCFS_CLIMP_EXIT(obd);
581 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
583 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
584 int *eof, void *data)
586 struct obd_device *obd = (struct obd_device*)data;
588 LASSERT(obd != NULL);
590 return snprintf(page, count, "%u\n", obd->obd_num_exports);
593 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
594 int *eof, void *data)
596 struct obd_type *class = (struct obd_type*) data;
598 LASSERT(class != NULL);
600 return snprintf(page, count, "%d\n", class->typ_refcnt);
603 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
607 LASSERT(obd != NULL);
608 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
609 LASSERT(obd->obd_type->typ_procroot != NULL);
611 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
612 obd->obd_type->typ_procroot,
614 if (IS_ERR(obd->obd_proc_entry)) {
615 rc = PTR_ERR(obd->obd_proc_entry);
616 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
617 obd->obd_proc_entry = NULL;
622 int lprocfs_obd_cleanup(struct obd_device *obd)
626 if (obd->obd_proc_exports) {
627 /* Should be no exports left */
628 LASSERT(obd->obd_proc_exports->subdir == NULL);
629 lprocfs_remove(&obd->obd_proc_exports);
631 lprocfs_remove(&obd->obd_proc_entry);
635 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num)
637 struct lprocfs_stats *stats;
638 struct lprocfs_percpu *percpu;
639 unsigned int percpusize;
645 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_online_cpus()]));
649 percpusize = L1_CACHE_ALIGN(offsetof(typeof(*percpu), lp_cntr[num]));
650 stats->ls_percpu_size = num_online_cpus() * percpusize;
651 OBD_ALLOC(stats->ls_percpu[0], stats->ls_percpu_size);
652 if (stats->ls_percpu[0] == NULL) {
653 OBD_FREE(stats, offsetof(typeof(*stats),
654 ls_percpu[num_online_cpus()]));
659 for (i = 1; i < num_online_cpus(); i++)
660 stats->ls_percpu[i] = (void *)(stats->ls_percpu[i - 1]) +
666 void lprocfs_free_stats(struct lprocfs_stats **statsh)
668 struct lprocfs_stats *stats = *statsh;
670 if (stats == NULL || stats->ls_num == 0)
674 OBD_FREE(stats->ls_percpu[0], stats->ls_percpu_size);
675 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_online_cpus()]));
678 void lprocfs_clear_stats(struct lprocfs_stats *stats)
680 struct lprocfs_counter *percpu_cntr;
683 for (i = 0; i < num_online_cpus(); i++) {
684 for (j = 0; j < stats->ls_num; j++) {
685 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
686 atomic_inc(&percpu_cntr->lc_cntl.la_entry);
687 percpu_cntr->lc_count = 0;
688 percpu_cntr->lc_sum = 0;
689 percpu_cntr->lc_min = ~(__u64)0;
690 percpu_cntr->lc_max = 0;
691 percpu_cntr->lc_sumsquare = 0;
692 atomic_inc(&percpu_cntr->lc_cntl.la_exit);
697 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
698 size_t len, loff_t *off)
700 struct seq_file *seq = file->private_data;
701 struct lprocfs_stats *stats = seq->private;
703 lprocfs_clear_stats(stats);
708 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
710 struct lprocfs_stats *stats = p->private;
711 /* return 1st cpu location */
712 return (*pos >= stats->ls_num) ? NULL :
713 &(stats->ls_percpu[0]->lp_cntr[*pos]);
716 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
720 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
722 struct lprocfs_stats *stats = p->private;
724 return (*pos >= stats->ls_num) ? NULL :
725 &(stats->ls_percpu[0]->lp_cntr[*pos]);
728 /* seq file export of one lprocfs counter */
729 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
731 struct lprocfs_stats *stats = p->private;
732 struct lprocfs_counter *cntr = v;
733 struct lprocfs_counter t, ret = { .lc_min = ~(__u64)0 };
736 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
738 do_gettimeofday(&now);
739 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
740 "snapshot_time", now.tv_sec, now.tv_usec);
744 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
746 for (i = 0; i < num_online_cpus(); i++) {
747 struct lprocfs_counter *percpu_cntr =
748 &(stats->ls_percpu[i])->lp_cntr[idx];
752 centry = atomic_read(&percpu_cntr->lc_cntl.la_entry);
753 t.lc_count = percpu_cntr->lc_count;
754 t.lc_sum = percpu_cntr->lc_sum;
755 t.lc_min = percpu_cntr->lc_min;
756 t.lc_max = percpu_cntr->lc_max;
757 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
758 } while (centry != atomic_read(&percpu_cntr->lc_cntl.la_entry) &&
759 centry != atomic_read(&percpu_cntr->lc_cntl.la_exit));
760 ret.lc_count += t.lc_count;
761 ret.lc_sum += t.lc_sum;
762 if (t.lc_min < ret.lc_min)
763 ret.lc_min = t.lc_min;
764 if (t.lc_max > ret.lc_max)
765 ret.lc_max = t.lc_max;
766 ret.lc_sumsquare += t.lc_sumsquare;
769 rc = seq_printf(p, "%-25s "LPU64" samples [%s]", cntr->lc_name,
770 ret.lc_count, cntr->lc_units);
774 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
775 rc = seq_printf(p, " "LPU64" "LPU64" "LPU64,
776 ret.lc_min, ret.lc_max, ret.lc_sum);
779 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
780 rc = seq_printf(p, " "LPU64, ret.lc_sumsquare);
784 rc = seq_printf(p, "\n");
786 return (rc < 0) ? rc : 0;
789 struct seq_operations lprocfs_stats_seq_sops = {
790 start: lprocfs_stats_seq_start,
791 stop: lprocfs_stats_seq_stop,
792 next: lprocfs_stats_seq_next,
793 show: lprocfs_stats_seq_show,
796 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
798 struct proc_dir_entry *dp = PDE(inode);
799 struct seq_file *seq;
802 LPROCFS_ENTRY_AND_CHECK(dp);
803 rc = seq_open(file, &lprocfs_stats_seq_sops);
808 seq = file->private_data;
809 seq->private = dp->data;
813 struct file_operations lprocfs_stats_seq_fops = {
814 .owner = THIS_MODULE,
815 .open = lprocfs_stats_seq_open,
817 .write = lprocfs_stats_seq_write,
819 .release = lprocfs_seq_release,
822 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
823 struct lprocfs_stats *stats)
825 struct proc_dir_entry *entry;
826 LASSERT(root != NULL);
828 entry = create_proc_entry(name, 0644, root);
831 entry->proc_fops = &lprocfs_stats_seq_fops;
832 entry->data = (void *)stats;
836 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
837 unsigned conf, const char *name, const char *units)
839 struct lprocfs_counter *c;
842 LASSERT(stats != NULL);
843 for (i = 0; i < num_online_cpus(); i++) {
844 c = &(stats->ls_percpu[i]->lp_cntr[index]);
848 c->lc_min = ~(__u64)0;
854 EXPORT_SYMBOL(lprocfs_counter_init);
856 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
858 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
859 LASSERT(coffset < stats->ls_num); \
860 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
863 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
865 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
866 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
867 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
868 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
869 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
870 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
871 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
872 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
873 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
874 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
875 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
876 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
877 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
878 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
879 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
880 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
881 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
882 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
883 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
884 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
885 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
886 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
887 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
888 LPROCFS_OBD_OP_INIT(num_private_stats, stats, checkmd);
889 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
890 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
891 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
892 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
893 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
894 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
895 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
896 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
897 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
898 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw_async);
899 LPROCFS_OBD_OP_INIT(num_private_stats, stats, prep_async_page);
900 LPROCFS_OBD_OP_INIT(num_private_stats, stats, queue_async_io);
901 LPROCFS_OBD_OP_INIT(num_private_stats, stats, queue_group_io);
902 LPROCFS_OBD_OP_INIT(num_private_stats, stats, trigger_group_io);
903 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_async_flags);
904 LPROCFS_OBD_OP_INIT(num_private_stats, stats, teardown_async_page);
905 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
906 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
907 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
908 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
909 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
910 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
911 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
912 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
913 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
914 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
915 LPROCFS_OBD_OP_INIT(num_private_stats, stats, match);
916 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
917 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
918 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
919 LPROCFS_OBD_OP_INIT(num_private_stats, stats, join_lru);
920 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
921 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
922 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
923 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
924 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
925 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
926 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
927 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
928 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
929 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
930 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
931 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
932 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
933 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
936 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
938 struct lprocfs_stats *stats;
939 unsigned int num_stats;
942 LASSERT(obd->obd_stats == NULL);
943 LASSERT(obd->obd_proc_entry != NULL);
944 LASSERT(obd->obd_cntr_base == 0);
946 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
947 num_private_stats - 1 /* o_owner */;
948 stats = lprocfs_alloc_stats(num_stats);
952 lprocfs_init_ops_stats(num_private_stats, stats);
954 for (i = num_private_stats; i < num_stats; i++) {
955 /* If this LBUGs, it is likely that an obd
956 * operation was added to struct obd_ops in
957 * <obd.h>, and that the corresponding line item
958 * LPROCFS_OBD_OP_INIT(.., .., opname)
959 * is missing from the list above. */
960 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
961 "Missing obd_stat initializer obd_op "
962 "operation at offset %d.\n", i - num_private_stats);
964 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
966 lprocfs_free_stats(&stats);
968 obd->obd_stats = stats;
969 obd->obd_cntr_base = num_private_stats;
974 void lprocfs_free_obd_stats(struct obd_device *obd)
977 lprocfs_free_stats(&obd->obd_stats);
980 #define LPROCFS_MD_OP_INIT(base, stats, op) \
982 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
983 LASSERT(coffset < stats->ls_num); \
984 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
987 int lprocfs_alloc_md_stats(struct obd_device *obd,
988 unsigned num_private_stats)
990 struct lprocfs_stats *stats;
991 unsigned int num_stats;
994 LASSERT(obd->md_stats == NULL);
995 LASSERT(obd->obd_proc_entry != NULL);
996 LASSERT(obd->md_cntr_base == 0);
998 num_stats = 1 + MD_COUNTER_OFFSET(get_remote_perm) +
1000 stats = lprocfs_alloc_stats(num_stats);
1004 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1005 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1006 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1007 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1008 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1009 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1010 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1011 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1012 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1013 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1014 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1015 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1016 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1017 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1018 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1019 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1020 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1021 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1022 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1023 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1024 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1025 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1026 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1027 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1028 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1029 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1030 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1031 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1033 for (i = num_private_stats; i < num_stats; i++) {
1034 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1035 CERROR("Missing md_stat initializer md_op "
1036 "operation at offset %d. Aborting.\n",
1037 i - num_private_stats);
1041 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1043 lprocfs_free_stats(&stats);
1045 obd->md_stats = stats;
1046 obd->md_cntr_base = num_private_stats;
1051 void lprocfs_free_md_stats(struct obd_device *obd)
1053 struct lprocfs_stats *stats = obd->md_stats;
1055 if (stats != NULL) {
1056 obd->md_stats = NULL;
1057 lprocfs_free_stats(&stats);
1061 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1062 int *eof, void *data)
1064 struct obd_export *exp = (struct obd_export*)data;
1065 LASSERT(exp != NULL);
1067 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1070 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1071 int *eof, void *data)
1073 struct obd_export *exp = (struct obd_export*)data;
1074 LASSERT(exp != NULL);
1076 return snprintf(page, count, "%s\n",
1077 obd_uuid2str(&exp->exp_client_uuid));
1080 int lprocfs_exp_setup(struct obd_export *exp)
1082 char name[sizeof (exp->exp_client_uuid.uuid) + 3];
1085 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports)
1087 mutex_down(&exp->exp_obd->obd_proc_exp_sem);
1088 sprintf(name, "%s", (char *)exp->exp_client_uuid.uuid);
1089 while (lprocfs_srch(exp->exp_obd->obd_proc_exports, name)) {
1090 /* We might add a new export before deleting the old one during
1091 an eviction (recovery-small 19a). Suckage. We
1092 could block, or come up with a new name, or just give up. */
1094 GOTO(out, rc = -EEXIST);
1095 sprintf(name, "%s:%d", (char *)exp->exp_client_uuid.uuid, i);
1098 /* Create a proc entry for this export */
1099 exp->exp_proc = proc_mkdir(name, exp->exp_obd->obd_proc_exports);
1100 if (!exp->exp_proc) {
1101 CERROR("Error making export directory for %s\n", name);
1102 GOTO(out, rc = -ENOMEM);
1105 /* Always add nid and uuid */
1106 rc = lprocfs_add_simple(exp->exp_proc, "nid",
1107 lprocfs_exp_rd_nid, NULL, exp);
1110 rc = lprocfs_add_simple(exp->exp_proc, "uuid",
1111 lprocfs_exp_rd_uuid, NULL, exp);
1114 /* Always add ldlm stats */
1115 exp->exp_ldlm_stats = lprocfs_alloc_stats(LDLM_LAST_OPC
1117 if (exp->exp_ldlm_stats == NULL) {
1118 lprocfs_remove(&exp->exp_proc);
1119 GOTO(out, rc = -ENOMEM);
1122 lprocfs_counter_init(exp->exp_ldlm_stats,
1123 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1124 0, "ldlm_enqueue", "reqs");
1125 lprocfs_counter_init(exp->exp_ldlm_stats,
1126 LDLM_CONVERT - LDLM_FIRST_OPC,
1127 0, "ldlm_convert", "reqs");
1128 lprocfs_counter_init(exp->exp_ldlm_stats,
1129 LDLM_CANCEL - LDLM_FIRST_OPC,
1130 0, "ldlm_cancel", "reqs");
1131 lprocfs_counter_init(exp->exp_ldlm_stats,
1132 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1133 0, "ldlm_bl_callback", "reqs");
1134 lprocfs_counter_init(exp->exp_ldlm_stats,
1135 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1136 0, "ldlm_cp_callback", "reqs");
1137 lprocfs_counter_init(exp->exp_ldlm_stats,
1138 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1139 0, "ldlm_gl_callback", "reqs");
1140 lprocfs_register_stats(exp->exp_proc, "ldlm_stats",
1141 exp->exp_ldlm_stats);
1143 mutex_up(&exp->exp_obd->obd_proc_exp_sem);
1147 int lprocfs_exp_cleanup(struct obd_export *exp)
1149 mutex_down(&exp->exp_obd->obd_proc_exp_sem);
1150 lprocfs_remove(&exp->exp_proc);
1151 lprocfs_free_stats(&exp->exp_ops_stats);
1152 lprocfs_free_stats(&exp->exp_ldlm_stats);
1153 mutex_up(&exp->exp_obd->obd_proc_exp_sem);
1157 int lprocfs_write_helper(const char *buffer, unsigned long count,
1160 return lprocfs_write_frac_helper(buffer, count, val, 1);
1163 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1166 char kernbuf[20], *end, *pbuf;
1168 if (count > (sizeof(kernbuf) - 1))
1171 if (copy_from_user(kernbuf, buffer, count))
1174 kernbuf[count] = '\0';
1181 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1185 if (end != NULL && *end == '.') {
1186 int temp_val, pow = 1;
1190 if (strlen(pbuf) > 5)
1191 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1193 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1196 for (i = 0; i < (end - pbuf); i++)
1199 *val += temp_val / pow;
1205 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val, int mult)
1207 long decimal_val, frac_val;
1213 decimal_val = val / mult;
1214 prtn = snprintf(buffer, count, "%ld", decimal_val);
1215 frac_val = val % mult;
1217 if (prtn < (count - 4) && frac_val > 0) {
1219 int i, temp_mult = 1, frac_bits = 0;
1221 temp_frac = frac_val * 10;
1222 buffer[prtn++] = '.';
1223 while (frac_bits < 2 && (temp_frac / mult) < 1 ) { /*only reserved 2bits fraction*/
1224 buffer[prtn++] ='0';
1229 Need to think these cases :
1230 1. #echo x.00 > /proc/xxx output result : x
1231 2. #echo x.0x > /proc/xxx output result : x.0x
1232 3. #echo x.x0 > /proc/xxx output result : x.x
1233 4. #echo x.xx > /proc/xxx output result : x.xx
1234 Only reserved 2bits fraction.
1236 for (i = 0; i < (5 - prtn); i++)
1239 frac_bits = min((int)count - prtn, 3 - frac_bits);
1240 prtn += snprintf(buffer + prtn, frac_bits, "%ld", frac_val * temp_mult / mult);
1243 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
1245 if (buffer[prtn] == '.') {
1252 buffer[prtn++] ='\n';
1256 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
1258 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
1261 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
1262 __u64 *val, int mult)
1264 char kernbuf[22], *end, *pbuf;
1265 __u64 whole, frac = 0, units;
1266 unsigned frac_d = 1;
1268 if (count > (sizeof(kernbuf) - 1) )
1271 if (copy_from_user(kernbuf, buffer, count))
1274 kernbuf[count] = '\0';
1281 whole = simple_strtoull(pbuf, &end, 10);
1285 if (end != NULL && *end == '.') {
1289 /* need to limit frac_d to a __u32 */
1290 if (strlen(pbuf) > 10)
1293 frac = simple_strtoull(pbuf, &end, 10);
1294 /* count decimal places */
1295 for (i = 0; i < (end - pbuf); i++)
1312 /* Specified units override the multiplier */
1314 mult = mult < 0 ? -units : units;
1317 do_div(frac, frac_d);
1318 *val = whole * mult + frac;
1322 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent,
1323 char *name, mode_t mode,
1324 struct file_operations *seq_fops, void *data)
1326 struct proc_dir_entry *entry;
1329 entry = create_proc_entry(name, mode, parent);
1332 entry->proc_fops = seq_fops;
1337 EXPORT_SYMBOL(lprocfs_seq_create);
1339 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
1341 struct file_operations *seq_fops,
1344 return (lprocfs_seq_create(dev->obd_proc_entry, name,
1345 mode, seq_fops, data));
1347 EXPORT_SYMBOL(lprocfs_obd_seq_create);
1349 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
1351 if (value >= OBD_HIST_MAX)
1352 value = OBD_HIST_MAX - 1;
1354 spin_lock(&oh->oh_lock);
1355 oh->oh_buckets[value]++;
1356 spin_unlock(&oh->oh_lock);
1358 EXPORT_SYMBOL(lprocfs_oh_tally);
1360 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
1364 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
1367 lprocfs_oh_tally(oh, val);
1369 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
1371 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
1373 unsigned long ret = 0;
1376 for (i = 0; i < OBD_HIST_MAX; i++)
1377 ret += oh->oh_buckets[i];
1380 EXPORT_SYMBOL(lprocfs_oh_sum);
1382 void lprocfs_oh_clear(struct obd_histogram *oh)
1384 spin_lock(&oh->oh_lock);
1385 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
1386 spin_unlock(&oh->oh_lock);
1388 EXPORT_SYMBOL(lprocfs_oh_clear);
1390 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
1391 int count, int *eof, void *data)
1393 struct obd_device *obd = data;
1396 LASSERT(obd != NULL);
1397 LASSERT(count >= 0);
1399 /* Set start of user data returned to
1400 page + off since the user may have
1401 requested to read much smaller than
1402 what we need to read */
1403 *start = page + off;
1405 /* We know we are allocated a page here.
1406 Also we know that this function will
1407 not need to write more than a page
1408 so we can truncate at CFS_PAGE_SIZE. */
1409 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
1411 /* Initialize the page */
1412 memset(page, 0, size);
1414 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
1417 if (obd->obd_max_recoverable_clients == 0) {
1418 lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n");
1422 /* sampled unlocked, but really... */
1423 if (obd->obd_recovering == 0) {
1424 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
1427 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
1428 obd->obd_recovery_start) <= 0)
1431 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_end: %lu\n",
1432 obd->obd_recovery_end) <= 0)
1435 /* Number of clients have have completed recovery */
1436 if (lprocfs_obd_snprintf(&page, size, &len, "recovered_clients: %d\n",
1437 obd->obd_max_recoverable_clients - obd->obd_recoverable_clients) <= 0)
1440 if (lprocfs_obd_snprintf(&page, size, &len, "unrecovered_clients: %d\n",
1441 obd->obd_recoverable_clients) <= 0)
1444 if (lprocfs_obd_snprintf(&page, size, &len, "last_transno: "LPD64"\n",
1445 obd->obd_next_recovery_transno - 1) <= 0)
1448 lprocfs_obd_snprintf(&page, size, &len, "replayed_requests: %d\n", obd->obd_replayed_requests);
1452 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
1455 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
1456 obd->obd_recovery_start) <= 0)
1459 if (lprocfs_obd_snprintf(&page, size, &len, "time remaining: %lu\n",
1460 CURRENT_SECONDS >= obd->obd_recovery_end ? 0 :
1461 obd->obd_recovery_end - CURRENT_SECONDS) <= 0)
1464 if(lprocfs_obd_snprintf(&page, size, &len, "connected_clients: %d/%d\n",
1465 obd->obd_connected_clients,
1466 obd->obd_max_recoverable_clients) <= 0)
1469 /* Number of clients have have completed recovery */
1470 if (lprocfs_obd_snprintf(&page, size, &len, "completed_clients: %d/%d\n",
1471 obd->obd_max_recoverable_clients - obd->obd_recoverable_clients,
1472 obd->obd_max_recoverable_clients) <= 0)
1475 if (lprocfs_obd_snprintf(&page, size, &len, "replayed_requests: %d/??\n",
1476 obd->obd_replayed_requests) <= 0)
1479 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
1480 obd->obd_requests_queued_for_recovery) <= 0)
1483 lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n", obd->obd_next_recovery_transno);
1488 return min(count, len - (int)off);
1490 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
1492 EXPORT_SYMBOL(lprocfs_register);
1493 EXPORT_SYMBOL(lprocfs_srch);
1494 EXPORT_SYMBOL(lprocfs_remove);
1495 EXPORT_SYMBOL(lprocfs_add_vars);
1496 EXPORT_SYMBOL(lprocfs_obd_setup);
1497 EXPORT_SYMBOL(lprocfs_obd_cleanup);
1498 EXPORT_SYMBOL(lprocfs_alloc_stats);
1499 EXPORT_SYMBOL(lprocfs_free_stats);
1500 EXPORT_SYMBOL(lprocfs_clear_stats);
1501 EXPORT_SYMBOL(lprocfs_register_stats);
1502 EXPORT_SYMBOL(lprocfs_init_ops_stats);
1503 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
1504 EXPORT_SYMBOL(lprocfs_free_obd_stats);
1505 EXPORT_SYMBOL(lprocfs_exp_setup);
1506 EXPORT_SYMBOL(lprocfs_exp_cleanup);
1508 EXPORT_SYMBOL(lprocfs_rd_u64);
1509 EXPORT_SYMBOL(lprocfs_rd_atomic);
1510 EXPORT_SYMBOL(lprocfs_rd_uuid);
1511 EXPORT_SYMBOL(lprocfs_rd_name);
1512 EXPORT_SYMBOL(lprocfs_rd_fstype);
1513 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
1514 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
1515 EXPORT_SYMBOL(lprocfs_rd_num_exports);
1516 EXPORT_SYMBOL(lprocfs_rd_numrefs);
1518 EXPORT_SYMBOL(lprocfs_rd_blksize);
1519 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
1520 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
1521 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
1522 EXPORT_SYMBOL(lprocfs_rd_filestotal);
1523 EXPORT_SYMBOL(lprocfs_rd_filesfree);
1525 EXPORT_SYMBOL(lprocfs_write_helper);
1526 EXPORT_SYMBOL(lprocfs_write_frac_helper);
1527 EXPORT_SYMBOL(lprocfs_read_frac_helper);
1528 EXPORT_SYMBOL(lprocfs_write_u64_helper);
1529 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);