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 #define MAX_STRING_SIZE 128
43 /* for bug 10866, global variable */
44 DECLARE_RWSEM(_lprocfs_lock);
45 EXPORT_SYMBOL(_lprocfs_lock);
47 int lprocfs_seq_release(struct inode *inode, struct file *file)
50 return seq_release(inode, file);
52 EXPORT_SYMBOL(lprocfs_seq_release);
54 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
57 struct proc_dir_entry *temp;
63 while (temp != NULL) {
64 if (strcmp(temp->name, name) == 0)
72 /* lprocfs API calls */
74 /* Function that emulates snprintf but also has the side effect of advancing
75 the page pointer for the next write into the buffer, incrementing the total
76 length written to the buffer, and decrementing the size left in the
78 static int lprocfs_obd_snprintf(char **page, int end, int *len,
79 const char *format, ...)
87 va_start(list, format);
88 n = vsnprintf(*page, end - *len, format, list);
91 *page += n; *len += n;
95 int lprocfs_add_simple(struct proc_dir_entry *root, char *name,
96 read_proc_t *read_proc, write_proc_t *write_proc,
99 struct proc_dir_entry *proc;
102 if (root == NULL || name == NULL)
108 proc = create_proc_entry(name, mode, root);
110 CERROR("LprocFS: No memory to create /proc entry %s", name);
113 proc->read_proc = read_proc;
114 proc->write_proc = write_proc;
119 static ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
120 size_t size, loff_t *ppos)
122 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
123 char *page, *start = NULL;
124 int rc = 0, eof = 1, count;
126 if (*ppos >= CFS_PAGE_SIZE)
129 page = (char *)__get_free_page(GFP_KERNEL);
134 OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
135 if (!dp->deleted && dp->read_proc)
136 rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
142 /* for lustre proc read, the read count must be less than PAGE_SIZE */
151 start = page + *ppos;
152 } else if (start < page) {
156 count = (rc < size) ? rc : size;
157 if (copy_to_user(buf, start, count)) {
164 free_page((unsigned long)page);
168 static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf, size_t size, loff_t *ppos)
170 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
174 if (!dp->deleted && dp->write_proc)
175 rc = dp->write_proc(f, buf, size, dp->data);
180 static struct file_operations lprocfs_generic_fops = {
181 .owner = THIS_MODULE,
182 .read = lprocfs_fops_read,
183 .write = lprocfs_fops_write,
186 int lprocfs_evict_client_open(struct inode *inode, struct file *f)
188 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
189 struct obd_device *obd = dp->data;
191 atomic_inc(&obd->obd_evict_inprogress);
196 int lprocfs_evict_client_release(struct inode *inode, struct file *f)
198 struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
199 struct obd_device *obd = dp->data;
201 atomic_dec(&obd->obd_evict_inprogress);
202 wake_up(&obd->obd_evict_inprogress_waitq);
207 struct file_operations lprocfs_evict_client_fops = {
208 .owner = THIS_MODULE,
209 .read = lprocfs_fops_read,
210 .write = lprocfs_fops_write,
211 .open = lprocfs_evict_client_open,
212 .release = lprocfs_evict_client_release,
214 EXPORT_SYMBOL(lprocfs_evict_client_fops);
216 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
219 if (root == NULL || list == NULL)
222 while (list->name != NULL) {
223 struct proc_dir_entry *cur_root, *proc;
224 char *pathcopy, *cur, *next, pathbuf[64];
225 int pathsize = strlen(list->name) + 1;
230 /* need copy of path for strsep */
231 if (strlen(list->name) > sizeof(pathbuf) - 1) {
232 OBD_ALLOC(pathcopy, pathsize);
233 if (pathcopy == NULL)
240 strcpy(pathcopy, list->name);
242 while (cur_root != NULL && (cur = strsep(&next, "/"))) {
243 if (*cur =='\0') /* skip double/trailing "/" */
246 proc = lprocfs_srch(cur_root, cur);
247 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
248 cur_root->name, cur, next,
249 (proc ? "exists" : "new"));
251 cur_root = (proc ? proc :
252 proc_mkdir(cur, cur_root));
253 } else if (proc == NULL) {
257 if (list->write_fptr)
259 proc = create_proc_entry(cur, mode, cur_root);
263 if (pathcopy != pathbuf)
264 OBD_FREE(pathcopy, pathsize);
266 if (cur_root == NULL || proc == NULL) {
267 CERROR("LprocFS: No memory to create /proc entry %s",
273 proc->proc_fops = list->fops;
275 proc->proc_fops = &lprocfs_generic_fops;
276 proc->read_proc = list->read_fptr;
277 proc->write_proc = list->write_fptr;
278 proc->data = (list->data ? list->data : data);
284 void lprocfs_remove(struct proc_dir_entry **rooth)
286 struct proc_dir_entry *root = *rooth;
287 struct proc_dir_entry *temp = root;
288 struct proc_dir_entry *rm_entry;
289 struct proc_dir_entry *parent;
295 parent = root->parent;
296 LASSERT(parent != NULL);
299 while (temp->subdir != NULL)
305 /* Memory corruption once caused this to fail, and
306 without this LASSERT we would loop here forever. */
307 LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
308 "0x%p %s/%s len %d\n", rm_entry, temp->name,
309 rm_entry->name, (int)strlen(rm_entry->name));
311 /* Now, the rm_entry->deleted flags is protected
312 * by _lprocfs_lock. */
313 down_write(&_lprocfs_lock);
314 rm_entry->data = NULL;
315 remove_proc_entry(rm_entry->name, rm_entry->parent);
316 up_write(&_lprocfs_lock);
322 struct proc_dir_entry *lprocfs_register(const char *name,
323 struct proc_dir_entry *parent,
324 struct lprocfs_vars *list, void *data)
326 struct proc_dir_entry *newchild;
328 newchild = lprocfs_srch(parent, name);
329 if (newchild != NULL) {
330 CERROR(" Lproc: Attempting to register %s more than once \n",
332 return ERR_PTR(-EALREADY);
335 newchild = proc_mkdir(name, parent);
336 if (newchild != NULL && list != NULL) {
337 int rc = lprocfs_add_vars(newchild, list, data);
339 lprocfs_remove(&newchild);
346 /* Generic callbacks */
347 int lprocfs_rd_uint(char *page, char **start, off_t off,
348 int count, int *eof, void *data)
350 unsigned int *temp = (unsigned int *)data;
351 return snprintf(page, count, "%u\n", *temp);
354 int lprocfs_wr_uint(struct file *file, const char *buffer,
355 unsigned long count, void *data)
358 char dummy[MAX_STRING_SIZE + 1], *end;
361 dummy[MAX_STRING_SIZE] = '\0';
362 if (copy_from_user(dummy, buffer, MAX_STRING_SIZE))
365 tmp = simple_strtoul(dummy, &end, 0);
369 *p = (unsigned int)tmp;
373 int lprocfs_rd_u64(char *page, char **start, off_t off,
374 int count, int *eof, void *data)
376 LASSERT(data != NULL);
378 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
381 int lprocfs_rd_atomic(char *page, char **start, off_t off,
382 int count, int *eof, void *data)
384 atomic_t *atom = (atomic_t *)data;
385 LASSERT(atom != NULL);
387 return snprintf(page, count, "%d\n", atomic_read(atom));
390 int lprocfs_wr_atomic(struct file *file, const char *buffer,
391 unsigned long count, void *data)
393 atomic_t *atm = data;
397 rc = lprocfs_write_helper(buffer, count, &val);
404 atomic_set(atm, val);
408 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
409 int *eof, void *data)
411 struct obd_device *obd = (struct obd_device*)data;
413 LASSERT(obd != NULL);
415 return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
418 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
419 int *eof, void* data)
421 struct obd_device *dev = (struct obd_device *)data;
423 LASSERT(dev != NULL);
424 LASSERT(dev->obd_name != NULL);
426 return snprintf(page, count, "%s\n", dev->obd_name);
429 int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
432 struct obd_device *obd = (struct obd_device *)data;
434 LASSERT(obd != NULL);
435 LASSERT(obd->obd_fsops != NULL);
436 LASSERT(obd->obd_fsops->fs_type != NULL);
437 return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
440 int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
441 int *eof, void *data)
443 struct obd_statfs osfs;
444 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ);
447 rc = snprintf(page, count, "%u\n", osfs.os_bsize);
452 int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
453 int *eof, void *data)
455 struct obd_statfs osfs;
456 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ);
458 __u32 blk_size = osfs.os_bsize >> 10;
459 __u64 result = osfs.os_blocks;
461 while (blk_size >>= 1)
465 rc = snprintf(page, count, LPU64"\n", result);
470 int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
471 int *eof, void *data)
473 struct obd_statfs osfs;
474 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ);
476 __u32 blk_size = osfs.os_bsize >> 10;
477 __u64 result = osfs.os_bfree;
479 while (blk_size >>= 1)
483 rc = snprintf(page, count, LPU64"\n", result);
488 int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
489 int *eof, void *data)
491 struct obd_statfs osfs;
492 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ);
494 __u32 blk_size = osfs.os_bsize >> 10;
495 __u64 result = osfs.os_bavail;
497 while (blk_size >>= 1)
501 rc = snprintf(page, count, LPU64"\n", result);
506 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
507 int *eof, void *data)
509 struct obd_statfs osfs;
510 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ);
513 rc = snprintf(page, count, LPU64"\n", osfs.os_files);
519 int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
520 int *eof, void *data)
522 struct obd_statfs osfs;
523 int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ);
526 rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
531 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
532 int *eof, void *data)
534 struct obd_device *obd = (struct obd_device *)data;
535 struct obd_import *imp;
536 char *imp_state_name = NULL;
539 LASSERT(obd != NULL);
540 LPROCFS_CLIMP_CHECK(obd);
541 imp = obd->u.cli.cl_import;
542 imp_state_name = ptlrpc_import_state_name(imp->imp_state);
544 rc = snprintf(page, count, "%s\t%s%s\n",
545 obd2cli_tgt(obd), imp_state_name,
546 imp->imp_deactive ? "\tDEACTIVATED" : "");
548 LPROCFS_CLIMP_EXIT(obd);
552 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
553 int *eof, void *data)
555 struct obd_device *obd = (struct obd_device*)data;
556 struct ptlrpc_connection *conn;
559 LASSERT(obd != NULL);
561 LPROCFS_CLIMP_CHECK(obd);
562 conn = obd->u.cli.cl_import->imp_connection;
563 LASSERT(conn != NULL);
565 if (obd->u.cli.cl_import) {
566 rc = snprintf(page, count, "%s\n",
567 conn->c_remote_uuid.uuid);
569 rc = snprintf(page, count, "%s\n", "<none>");
572 LPROCFS_CLIMP_EXIT(obd);
576 static const char *obd_connect_names[] = {
601 "mds_mds_connection",
606 int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
607 int count, int *eof, void *data)
609 struct obd_device *obd = data;
610 __u64 mask = 1, flags;
613 LPROCFS_CLIMP_CHECK(obd);
614 flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
615 ret = snprintf(page, count, "flags="LPX64"\n", flags);
616 for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
618 ret += snprintf(page + ret, count - ret, "%s\n",
619 obd_connect_names[i]);
621 if (flags & ~(mask - 1))
622 ret += snprintf(page + ret, count - ret,
623 "unknown flags "LPX64"\n", flags & ~(mask - 1));
625 LPROCFS_CLIMP_EXIT(obd);
628 EXPORT_SYMBOL(lprocfs_rd_connect_flags);
630 int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
631 int *eof, void *data)
633 struct obd_device *obd = (struct obd_device*)data;
635 LASSERT(obd != NULL);
637 return snprintf(page, count, "%u\n", obd->obd_num_exports);
640 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
641 int *eof, void *data)
643 struct obd_type *class = (struct obd_type*) data;
645 LASSERT(class != NULL);
647 return snprintf(page, count, "%d\n", class->typ_refcnt);
650 int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
654 LASSERT(obd != NULL);
655 LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
656 LASSERT(obd->obd_type->typ_procroot != NULL);
658 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
659 obd->obd_type->typ_procroot,
661 if (IS_ERR(obd->obd_proc_entry)) {
662 rc = PTR_ERR(obd->obd_proc_entry);
663 CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
664 obd->obd_proc_entry = NULL;
669 int lprocfs_obd_cleanup(struct obd_device *obd)
673 if (obd->obd_proc_exports) {
674 /* Should be no exports left */
675 LASSERT(obd->obd_proc_exports->subdir == NULL);
676 lprocfs_remove(&obd->obd_proc_exports);
678 lprocfs_remove(&obd->obd_proc_entry);
682 struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num)
684 struct lprocfs_stats *stats;
685 struct lprocfs_percpu *percpu;
686 unsigned int percpusize;
692 OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_online_cpus()]));
696 percpusize = L1_CACHE_ALIGN(offsetof(typeof(*percpu), lp_cntr[num]));
697 stats->ls_percpu_size = num_online_cpus() * percpusize;
698 OBD_ALLOC(stats->ls_percpu[0], stats->ls_percpu_size);
699 if (stats->ls_percpu[0] == NULL) {
700 OBD_FREE(stats, offsetof(typeof(*stats),
701 ls_percpu[num_online_cpus()]));
706 for (i = 1; i < num_online_cpus(); i++)
707 stats->ls_percpu[i] = (void *)(stats->ls_percpu[i - 1]) +
713 void lprocfs_free_stats(struct lprocfs_stats **statsh)
715 struct lprocfs_stats *stats = *statsh;
717 if (stats == NULL || stats->ls_num == 0)
721 OBD_FREE(stats->ls_percpu[0], stats->ls_percpu_size);
722 OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_online_cpus()]));
725 void lprocfs_clear_stats(struct lprocfs_stats *stats)
727 struct lprocfs_counter *percpu_cntr;
730 for (i = 0; i < num_online_cpus(); i++) {
731 for (j = 0; j < stats->ls_num; j++) {
732 percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
733 atomic_inc(&percpu_cntr->lc_cntl.la_entry);
734 percpu_cntr->lc_count = 0;
735 percpu_cntr->lc_sum = 0;
736 percpu_cntr->lc_min = ~(__u64)0;
737 percpu_cntr->lc_max = 0;
738 percpu_cntr->lc_sumsquare = 0;
739 atomic_inc(&percpu_cntr->lc_cntl.la_exit);
744 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
745 size_t len, loff_t *off)
747 struct seq_file *seq = file->private_data;
748 struct lprocfs_stats *stats = seq->private;
750 lprocfs_clear_stats(stats);
755 static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
757 struct lprocfs_stats *stats = p->private;
758 /* return 1st cpu location */
759 return (*pos >= stats->ls_num) ? NULL :
760 &(stats->ls_percpu[0]->lp_cntr[*pos]);
763 static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
767 static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
769 struct lprocfs_stats *stats = p->private;
771 return (*pos >= stats->ls_num) ? NULL :
772 &(stats->ls_percpu[0]->lp_cntr[*pos]);
775 /* seq file export of one lprocfs counter */
776 static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
778 struct lprocfs_stats *stats = p->private;
779 struct lprocfs_counter *cntr = v;
780 struct lprocfs_counter t, ret = { .lc_min = ~(__u64)0 };
783 if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
785 do_gettimeofday(&now);
786 rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
787 "snapshot_time", now.tv_sec, now.tv_usec);
791 idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
793 for (i = 0; i < num_online_cpus(); i++) {
794 struct lprocfs_counter *percpu_cntr =
795 &(stats->ls_percpu[i])->lp_cntr[idx];
799 centry = atomic_read(&percpu_cntr->lc_cntl.la_entry);
800 t.lc_count = percpu_cntr->lc_count;
801 t.lc_sum = percpu_cntr->lc_sum;
802 t.lc_min = percpu_cntr->lc_min;
803 t.lc_max = percpu_cntr->lc_max;
804 t.lc_sumsquare = percpu_cntr->lc_sumsquare;
805 } while (centry != atomic_read(&percpu_cntr->lc_cntl.la_entry) &&
806 centry != atomic_read(&percpu_cntr->lc_cntl.la_exit));
807 ret.lc_count += t.lc_count;
808 ret.lc_sum += t.lc_sum;
809 if (t.lc_min < ret.lc_min)
810 ret.lc_min = t.lc_min;
811 if (t.lc_max > ret.lc_max)
812 ret.lc_max = t.lc_max;
813 ret.lc_sumsquare += t.lc_sumsquare;
816 rc = seq_printf(p, "%-25s "LPU64" samples [%s]", cntr->lc_name,
817 ret.lc_count, cntr->lc_units);
821 if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
822 rc = seq_printf(p, " "LPU64" "LPU64" "LPU64,
823 ret.lc_min, ret.lc_max, ret.lc_sum);
826 if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
827 rc = seq_printf(p, " "LPU64, ret.lc_sumsquare);
831 rc = seq_printf(p, "\n");
833 return (rc < 0) ? rc : 0;
836 struct seq_operations lprocfs_stats_seq_sops = {
837 start: lprocfs_stats_seq_start,
838 stop: lprocfs_stats_seq_stop,
839 next: lprocfs_stats_seq_next,
840 show: lprocfs_stats_seq_show,
843 static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
845 struct proc_dir_entry *dp = PDE(inode);
846 struct seq_file *seq;
849 LPROCFS_ENTRY_AND_CHECK(dp);
850 rc = seq_open(file, &lprocfs_stats_seq_sops);
855 seq = file->private_data;
856 seq->private = dp->data;
860 struct file_operations lprocfs_stats_seq_fops = {
861 .owner = THIS_MODULE,
862 .open = lprocfs_stats_seq_open,
864 .write = lprocfs_stats_seq_write,
866 .release = lprocfs_seq_release,
869 int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
870 struct lprocfs_stats *stats)
872 struct proc_dir_entry *entry;
873 LASSERT(root != NULL);
875 entry = create_proc_entry(name, 0644, root);
878 entry->proc_fops = &lprocfs_stats_seq_fops;
879 entry->data = (void *)stats;
883 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
884 unsigned conf, const char *name, const char *units)
886 struct lprocfs_counter *c;
889 LASSERT(stats != NULL);
890 for (i = 0; i < num_online_cpus(); i++) {
891 c = &(stats->ls_percpu[i]->lp_cntr[index]);
895 c->lc_min = ~(__u64)0;
901 EXPORT_SYMBOL(lprocfs_counter_init);
903 #define LPROCFS_OBD_OP_INIT(base, stats, op) \
905 unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
906 LASSERT(coffset < stats->ls_num); \
907 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
910 void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
912 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
913 LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
914 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
915 LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
916 LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
917 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
918 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
919 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
920 LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
921 LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
922 LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
923 LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
924 LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
925 LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
926 LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
927 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_init);
928 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_fini);
929 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_alloc);
930 LPROCFS_OBD_OP_INIT(num_private_stats, stats, fid_delete);
931 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
932 LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
933 LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
934 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
935 LPROCFS_OBD_OP_INIT(num_private_stats, stats, checkmd);
936 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
937 LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
938 LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
939 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
940 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
941 LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
942 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
943 LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
944 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
945 LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw_async);
946 LPROCFS_OBD_OP_INIT(num_private_stats, stats, prep_async_page);
947 LPROCFS_OBD_OP_INIT(num_private_stats, stats, queue_async_io);
948 LPROCFS_OBD_OP_INIT(num_private_stats, stats, queue_group_io);
949 LPROCFS_OBD_OP_INIT(num_private_stats, stats, trigger_group_io);
950 LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_async_flags);
951 LPROCFS_OBD_OP_INIT(num_private_stats, stats, teardown_async_page);
952 LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
953 LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
954 LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
955 LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
956 LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
957 LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
958 LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
959 LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
960 LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
961 LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
962 LPROCFS_OBD_OP_INIT(num_private_stats, stats, match);
963 LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
964 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
965 LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
966 LPROCFS_OBD_OP_INIT(num_private_stats, stats, join_lru);
967 LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
968 LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
969 LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
970 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
971 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect);
972 LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
973 LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
974 LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
975 LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
976 LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
977 LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
978 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
979 LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
980 LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
983 int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
985 struct lprocfs_stats *stats;
986 unsigned int num_stats;
989 LASSERT(obd->obd_stats == NULL);
990 LASSERT(obd->obd_proc_entry != NULL);
991 LASSERT(obd->obd_cntr_base == 0);
993 num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
994 num_private_stats - 1 /* o_owner */;
995 stats = lprocfs_alloc_stats(num_stats);
999 lprocfs_init_ops_stats(num_private_stats, stats);
1001 for (i = num_private_stats; i < num_stats; i++) {
1002 /* If this LBUGs, it is likely that an obd
1003 * operation was added to struct obd_ops in
1004 * <obd.h>, and that the corresponding line item
1005 * LPROCFS_OBD_OP_INIT(.., .., opname)
1006 * is missing from the list above. */
1007 LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
1008 "Missing obd_stat initializer obd_op "
1009 "operation at offset %d.\n", i - num_private_stats);
1011 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1013 lprocfs_free_stats(&stats);
1015 obd->obd_stats = stats;
1016 obd->obd_cntr_base = num_private_stats;
1021 void lprocfs_free_obd_stats(struct obd_device *obd)
1024 lprocfs_free_stats(&obd->obd_stats);
1027 #define LPROCFS_MD_OP_INIT(base, stats, op) \
1029 unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
1030 LASSERT(coffset < stats->ls_num); \
1031 lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
1034 int lprocfs_alloc_md_stats(struct obd_device *obd,
1035 unsigned num_private_stats)
1037 struct lprocfs_stats *stats;
1038 unsigned int num_stats;
1041 LASSERT(obd->md_stats == NULL);
1042 LASSERT(obd->obd_proc_entry != NULL);
1043 LASSERT(obd->md_cntr_base == 0);
1045 num_stats = 1 + MD_COUNTER_OFFSET(get_remote_perm) +
1047 stats = lprocfs_alloc_stats(num_stats);
1051 LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
1052 LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
1053 LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
1054 LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
1055 LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
1056 LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
1057 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
1058 LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
1059 LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
1060 LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
1061 LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
1062 LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
1063 LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
1064 LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
1065 LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
1066 LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
1067 LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
1068 LPROCFS_MD_OP_INIT(num_private_stats, stats, getxattr);
1069 LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
1070 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
1071 LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
1072 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
1073 LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
1074 LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
1075 LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
1076 LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
1077 LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
1078 LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
1080 for (i = num_private_stats; i < num_stats; i++) {
1081 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
1082 CERROR("Missing md_stat initializer md_op "
1083 "operation at offset %d. Aborting.\n",
1084 i - num_private_stats);
1088 rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
1090 lprocfs_free_stats(&stats);
1092 obd->md_stats = stats;
1093 obd->md_cntr_base = num_private_stats;
1098 void lprocfs_free_md_stats(struct obd_device *obd)
1100 struct lprocfs_stats *stats = obd->md_stats;
1102 if (stats != NULL) {
1103 obd->md_stats = NULL;
1104 lprocfs_free_stats(&stats);
1108 int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
1109 int *eof, void *data)
1111 struct obd_export *exp = (struct obd_export*)data;
1112 LASSERT(exp != NULL);
1114 return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
1117 int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
1118 int *eof, void *data)
1120 struct obd_export *exp = (struct obd_export*)data;
1121 LASSERT(exp != NULL);
1123 return snprintf(page, count, "%s\n",
1124 obd_uuid2str(&exp->exp_client_uuid));
1127 int lprocfs_exp_setup(struct obd_export *exp)
1129 char name[sizeof (exp->exp_client_uuid.uuid) + 3];
1132 if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports)
1134 mutex_down(&exp->exp_obd->obd_proc_exp_sem);
1135 sprintf(name, "%s", (char *)exp->exp_client_uuid.uuid);
1136 while (lprocfs_srch(exp->exp_obd->obd_proc_exports, name)) {
1137 /* We might add a new export before deleting the old one during
1138 an eviction (recovery-small 19a). Suckage. We
1139 could block, or come up with a new name, or just give up. */
1141 GOTO(out, rc = -EEXIST);
1142 sprintf(name, "%s:%d", (char *)exp->exp_client_uuid.uuid, i);
1145 /* Create a proc entry for this export */
1146 exp->exp_proc = proc_mkdir(name, exp->exp_obd->obd_proc_exports);
1147 if (!exp->exp_proc) {
1148 CERROR("Error making export directory for %s\n", name);
1149 GOTO(out, rc = -ENOMEM);
1152 /* Always add nid and uuid */
1153 rc = lprocfs_add_simple(exp->exp_proc, "nid",
1154 lprocfs_exp_rd_nid, NULL, exp);
1157 rc = lprocfs_add_simple(exp->exp_proc, "uuid",
1158 lprocfs_exp_rd_uuid, NULL, exp);
1161 /* Always add ldlm stats */
1162 exp->exp_ldlm_stats = lprocfs_alloc_stats(LDLM_LAST_OPC
1164 if (exp->exp_ldlm_stats == NULL) {
1165 lprocfs_remove(&exp->exp_proc);
1166 GOTO(out, rc = -ENOMEM);
1169 lprocfs_counter_init(exp->exp_ldlm_stats,
1170 LDLM_ENQUEUE - LDLM_FIRST_OPC,
1171 0, "ldlm_enqueue", "reqs");
1172 lprocfs_counter_init(exp->exp_ldlm_stats,
1173 LDLM_CONVERT - LDLM_FIRST_OPC,
1174 0, "ldlm_convert", "reqs");
1175 lprocfs_counter_init(exp->exp_ldlm_stats,
1176 LDLM_CANCEL - LDLM_FIRST_OPC,
1177 0, "ldlm_cancel", "reqs");
1178 lprocfs_counter_init(exp->exp_ldlm_stats,
1179 LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
1180 0, "ldlm_bl_callback", "reqs");
1181 lprocfs_counter_init(exp->exp_ldlm_stats,
1182 LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
1183 0, "ldlm_cp_callback", "reqs");
1184 lprocfs_counter_init(exp->exp_ldlm_stats,
1185 LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
1186 0, "ldlm_gl_callback", "reqs");
1187 lprocfs_register_stats(exp->exp_proc, "ldlm_stats",
1188 exp->exp_ldlm_stats);
1190 mutex_up(&exp->exp_obd->obd_proc_exp_sem);
1194 int lprocfs_exp_cleanup(struct obd_export *exp)
1196 mutex_down(&exp->exp_obd->obd_proc_exp_sem);
1197 lprocfs_remove(&exp->exp_proc);
1198 lprocfs_free_stats(&exp->exp_ops_stats);
1199 lprocfs_free_stats(&exp->exp_ldlm_stats);
1200 mutex_up(&exp->exp_obd->obd_proc_exp_sem);
1204 int lprocfs_write_helper(const char *buffer, unsigned long count,
1207 return lprocfs_write_frac_helper(buffer, count, val, 1);
1210 int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
1213 char kernbuf[20], *end, *pbuf;
1215 if (count > (sizeof(kernbuf) - 1))
1218 if (copy_from_user(kernbuf, buffer, count))
1221 kernbuf[count] = '\0';
1228 *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1232 if (end != NULL && *end == '.') {
1233 int temp_val, pow = 1;
1237 if (strlen(pbuf) > 5)
1238 pbuf[5] = '\0'; /*only allow 5bits fractional*/
1240 temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
1243 for (i = 0; i < (end - pbuf); i++)
1246 *val += temp_val / pow;
1252 int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val, int mult)
1254 long decimal_val, frac_val;
1260 decimal_val = val / mult;
1261 prtn = snprintf(buffer, count, "%ld", decimal_val);
1262 frac_val = val % mult;
1264 if (prtn < (count - 4) && frac_val > 0) {
1266 int i, temp_mult = 1, frac_bits = 0;
1268 temp_frac = frac_val * 10;
1269 buffer[prtn++] = '.';
1270 while (frac_bits < 2 && (temp_frac / mult) < 1 ) { /*only reserved 2bits fraction*/
1271 buffer[prtn++] ='0';
1276 Need to think these cases :
1277 1. #echo x.00 > /proc/xxx output result : x
1278 2. #echo x.0x > /proc/xxx output result : x.0x
1279 3. #echo x.x0 > /proc/xxx output result : x.x
1280 4. #echo x.xx > /proc/xxx output result : x.xx
1281 Only reserved 2bits fraction.
1283 for (i = 0; i < (5 - prtn); i++)
1286 frac_bits = min((int)count - prtn, 3 - frac_bits);
1287 prtn += snprintf(buffer + prtn, frac_bits, "%ld", frac_val * temp_mult / mult);
1290 while(buffer[prtn] < '1' || buffer[prtn] > '9') {
1292 if (buffer[prtn] == '.') {
1299 buffer[prtn++] ='\n';
1303 int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
1305 return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
1308 int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
1309 __u64 *val, int mult)
1311 char kernbuf[22], *end, *pbuf;
1312 __u64 whole, frac = 0, units;
1313 unsigned frac_d = 1;
1315 if (count > (sizeof(kernbuf) - 1) )
1318 if (copy_from_user(kernbuf, buffer, count))
1321 kernbuf[count] = '\0';
1328 whole = simple_strtoull(pbuf, &end, 10);
1332 if (end != NULL && *end == '.') {
1336 /* need to limit frac_d to a __u32 */
1337 if (strlen(pbuf) > 10)
1340 frac = simple_strtoull(pbuf, &end, 10);
1341 /* count decimal places */
1342 for (i = 0; i < (end - pbuf); i++)
1359 /* Specified units override the multiplier */
1361 mult = mult < 0 ? -units : units;
1364 do_div(frac, frac_d);
1365 *val = whole * mult + frac;
1369 int lprocfs_seq_create(cfs_proc_dir_entry_t *parent,
1370 char *name, mode_t mode,
1371 struct file_operations *seq_fops, void *data)
1373 struct proc_dir_entry *entry;
1376 entry = create_proc_entry(name, mode, parent);
1379 entry->proc_fops = seq_fops;
1384 EXPORT_SYMBOL(lprocfs_seq_create);
1386 __inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
1388 struct file_operations *seq_fops,
1391 return (lprocfs_seq_create(dev->obd_proc_entry, name,
1392 mode, seq_fops, data));
1394 EXPORT_SYMBOL(lprocfs_obd_seq_create);
1396 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
1398 if (value >= OBD_HIST_MAX)
1399 value = OBD_HIST_MAX - 1;
1401 spin_lock(&oh->oh_lock);
1402 oh->oh_buckets[value]++;
1403 spin_unlock(&oh->oh_lock);
1405 EXPORT_SYMBOL(lprocfs_oh_tally);
1407 void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
1411 for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
1414 lprocfs_oh_tally(oh, val);
1416 EXPORT_SYMBOL(lprocfs_oh_tally_log2);
1418 unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
1420 unsigned long ret = 0;
1423 for (i = 0; i < OBD_HIST_MAX; i++)
1424 ret += oh->oh_buckets[i];
1427 EXPORT_SYMBOL(lprocfs_oh_sum);
1429 void lprocfs_oh_clear(struct obd_histogram *oh)
1431 spin_lock(&oh->oh_lock);
1432 memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
1433 spin_unlock(&oh->oh_lock);
1435 EXPORT_SYMBOL(lprocfs_oh_clear);
1437 int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
1438 int count, int *eof, void *data)
1440 struct obd_device *obd = data;
1443 LASSERT(obd != NULL);
1444 LASSERT(count >= 0);
1446 /* Set start of user data returned to
1447 page + off since the user may have
1448 requested to read much smaller than
1449 what we need to read */
1450 *start = page + off;
1452 /* We know we are allocated a page here.
1453 Also we know that this function will
1454 not need to write more than a page
1455 so we can truncate at CFS_PAGE_SIZE. */
1456 size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
1458 /* Initialize the page */
1459 memset(page, 0, size);
1461 if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
1464 if (obd->obd_max_recoverable_clients == 0) {
1465 lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n");
1469 /* sampled unlocked, but really... */
1470 if (obd->obd_recovering == 0) {
1471 if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
1474 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
1475 obd->obd_recovery_start) <= 0)
1478 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_end: %lu\n",
1479 obd->obd_recovery_end) <= 0)
1482 /* Number of clients have have completed recovery */
1483 if (lprocfs_obd_snprintf(&page, size, &len, "recovered_clients: %d\n",
1484 obd->obd_max_recoverable_clients - obd->obd_recoverable_clients) <= 0)
1487 if (lprocfs_obd_snprintf(&page, size, &len, "unrecovered_clients: %d\n",
1488 obd->obd_recoverable_clients) <= 0)
1491 if (lprocfs_obd_snprintf(&page, size, &len, "last_transno: "LPD64"\n",
1492 obd->obd_next_recovery_transno - 1) <= 0)
1495 lprocfs_obd_snprintf(&page, size, &len, "replayed_requests: %d\n", obd->obd_replayed_requests);
1499 if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
1502 if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
1503 obd->obd_recovery_start) <= 0)
1506 if (lprocfs_obd_snprintf(&page, size, &len, "time remaining: %lu\n",
1507 CURRENT_SECONDS >= obd->obd_recovery_end ? 0 :
1508 obd->obd_recovery_end - CURRENT_SECONDS) <= 0)
1511 if(lprocfs_obd_snprintf(&page, size, &len, "connected_clients: %d/%d\n",
1512 obd->obd_connected_clients,
1513 obd->obd_max_recoverable_clients) <= 0)
1516 /* Number of clients have have completed recovery */
1517 if (lprocfs_obd_snprintf(&page, size, &len, "completed_clients: %d/%d\n",
1518 obd->obd_max_recoverable_clients - obd->obd_recoverable_clients,
1519 obd->obd_max_recoverable_clients) <= 0)
1522 if (lprocfs_obd_snprintf(&page, size, &len, "replayed_requests: %d/??\n",
1523 obd->obd_replayed_requests) <= 0)
1526 if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
1527 obd->obd_requests_queued_for_recovery) <= 0)
1530 lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n", obd->obd_next_recovery_transno);
1535 return min(count, len - (int)off);
1537 EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
1539 EXPORT_SYMBOL(lprocfs_register);
1540 EXPORT_SYMBOL(lprocfs_srch);
1541 EXPORT_SYMBOL(lprocfs_remove);
1542 EXPORT_SYMBOL(lprocfs_add_vars);
1543 EXPORT_SYMBOL(lprocfs_obd_setup);
1544 EXPORT_SYMBOL(lprocfs_obd_cleanup);
1545 EXPORT_SYMBOL(lprocfs_alloc_stats);
1546 EXPORT_SYMBOL(lprocfs_free_stats);
1547 EXPORT_SYMBOL(lprocfs_clear_stats);
1548 EXPORT_SYMBOL(lprocfs_register_stats);
1549 EXPORT_SYMBOL(lprocfs_init_ops_stats);
1550 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
1551 EXPORT_SYMBOL(lprocfs_free_obd_stats);
1552 EXPORT_SYMBOL(lprocfs_exp_setup);
1553 EXPORT_SYMBOL(lprocfs_exp_cleanup);
1555 EXPORT_SYMBOL(lprocfs_rd_u64);
1556 EXPORT_SYMBOL(lprocfs_rd_atomic);
1557 EXPORT_SYMBOL(lprocfs_wr_atomic);
1558 EXPORT_SYMBOL(lprocfs_rd_uint);
1559 EXPORT_SYMBOL(lprocfs_wr_uint);
1560 EXPORT_SYMBOL(lprocfs_rd_uuid);
1561 EXPORT_SYMBOL(lprocfs_rd_name);
1562 EXPORT_SYMBOL(lprocfs_rd_fstype);
1563 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
1564 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
1565 EXPORT_SYMBOL(lprocfs_rd_num_exports);
1566 EXPORT_SYMBOL(lprocfs_rd_numrefs);
1568 EXPORT_SYMBOL(lprocfs_rd_blksize);
1569 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
1570 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
1571 EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
1572 EXPORT_SYMBOL(lprocfs_rd_filestotal);
1573 EXPORT_SYMBOL(lprocfs_rd_filesfree);
1575 EXPORT_SYMBOL(lprocfs_write_helper);
1576 EXPORT_SYMBOL(lprocfs_write_frac_helper);
1577 EXPORT_SYMBOL(lprocfs_read_frac_helper);
1578 EXPORT_SYMBOL(lprocfs_write_u64_helper);
1579 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);