Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
[linux-2.6] / fs / xfs / linux-2.6 / xfs_stats.c
1 /*
2  * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #include "xfs.h"
19 #include <linux/proc_fs.h>
20
21 DEFINE_PER_CPU(struct xfsstats, xfsstats);
22
23 STATIC int
24 xfs_read_xfsstats(
25         char            *buffer,
26         char            **start,
27         off_t           offset,
28         int             count,
29         int             *eof,
30         void            *data)
31 {
32         int             c, i, j, len, val;
33         __uint64_t      xs_xstrat_bytes = 0;
34         __uint64_t      xs_write_bytes = 0;
35         __uint64_t      xs_read_bytes = 0;
36
37         static const struct xstats_entry {
38                 char    *desc;
39                 int     endpoint;
40         } xstats[] = {
41                 { "extent_alloc",       XFSSTAT_END_EXTENT_ALLOC        },
42                 { "abt",                XFSSTAT_END_ALLOC_BTREE         },
43                 { "blk_map",            XFSSTAT_END_BLOCK_MAPPING       },
44                 { "bmbt",               XFSSTAT_END_BLOCK_MAP_BTREE     },
45                 { "dir",                XFSSTAT_END_DIRECTORY_OPS       },
46                 { "trans",              XFSSTAT_END_TRANSACTIONS        },
47                 { "ig",                 XFSSTAT_END_INODE_OPS           },
48                 { "log",                XFSSTAT_END_LOG_OPS             },
49                 { "push_ail",           XFSSTAT_END_TAIL_PUSHING        },
50                 { "xstrat",             XFSSTAT_END_WRITE_CONVERT       },
51                 { "rw",                 XFSSTAT_END_READ_WRITE_OPS      },
52                 { "attr",               XFSSTAT_END_ATTRIBUTE_OPS       },
53                 { "icluster",           XFSSTAT_END_INODE_CLUSTER       },
54                 { "vnodes",             XFSSTAT_END_VNODE_OPS           },
55                 { "buf",                XFSSTAT_END_BUF                 },
56                 { "abtb2",              XFSSTAT_END_ABTB_V2             },
57                 { "abtc2",              XFSSTAT_END_ABTC_V2             },
58                 { "bmbt2",              XFSSTAT_END_BMBT_V2             },
59                 { "ibt2",               XFSSTAT_END_IBT_V2              },
60         };
61
62         /* Loop over all stats groups */
63         for (i=j=len = 0; i < ARRAY_SIZE(xstats); i++) {
64                 len += sprintf(buffer + len, "%s", xstats[i].desc);
65                 /* inner loop does each group */
66                 while (j < xstats[i].endpoint) {
67                         val = 0;
68                         /* sum over all cpus */
69                         for_each_possible_cpu(c)
70                                 val += *(((__u32*)&per_cpu(xfsstats, c) + j));
71                         len += sprintf(buffer + len, " %u", val);
72                         j++;
73                 }
74                 buffer[len++] = '\n';
75         }
76         /* extra precision counters */
77         for_each_possible_cpu(i) {
78                 xs_xstrat_bytes += per_cpu(xfsstats, i).xs_xstrat_bytes;
79                 xs_write_bytes += per_cpu(xfsstats, i).xs_write_bytes;
80                 xs_read_bytes += per_cpu(xfsstats, i).xs_read_bytes;
81         }
82
83         len += sprintf(buffer + len, "xpc %Lu %Lu %Lu\n",
84                         xs_xstrat_bytes, xs_write_bytes, xs_read_bytes);
85         len += sprintf(buffer + len, "debug %u\n",
86 #if defined(DEBUG)
87                 1);
88 #else
89                 0);
90 #endif
91
92         if (offset >= len) {
93                 *start = buffer;
94                 *eof = 1;
95                 return 0;
96         }
97         *start = buffer + offset;
98         if ((len -= offset) > count)
99                 return count;
100         *eof = 1;
101
102         return len;
103 }
104
105 int
106 xfs_init_procfs(void)
107 {
108         if (!proc_mkdir("fs/xfs", NULL))
109                 goto out;
110
111         if (!create_proc_read_entry("fs/xfs/stat", 0, NULL,
112                         xfs_read_xfsstats, NULL))
113                 goto out_remove_entry;
114         return 0;
115
116  out_remove_entry:
117         remove_proc_entry("fs/xfs", NULL);
118  out:
119         return -ENOMEM;
120 }
121
122 void
123 xfs_cleanup_procfs(void)
124 {
125         remove_proc_entry("fs/xfs/stat", NULL);
126         remove_proc_entry("fs/xfs", NULL);
127 }