xfs: create global stats and stats_clear in sysfs
[firefly-linux-kernel-4.4.55.git] / fs / xfs / xfs_sysfs.c
1 /*
2  * Copyright (c) 2014 Red Hat, 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
19 #include "xfs.h"
20 #include "xfs_sysfs.h"
21 #include "xfs_log_format.h"
22 #include "xfs_log.h"
23 #include "xfs_log_priv.h"
24 #include "xfs_stats.h"
25
26 struct xfs_sysfs_attr {
27         struct attribute attr;
28         ssize_t (*show)(char *buf, void *data);
29         ssize_t (*store)(const char *buf, size_t count, void *data);
30 };
31
32 static inline struct xfs_sysfs_attr *
33 to_attr(struct attribute *attr)
34 {
35         return container_of(attr, struct xfs_sysfs_attr, attr);
36 }
37
38 #define XFS_SYSFS_ATTR_RW(name) \
39         static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RW(name)
40 #define XFS_SYSFS_ATTR_RO(name) \
41         static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RO(name)
42 #define XFS_SYSFS_ATTR_WO(name) \
43         static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_WO(name)
44
45 #define ATTR_LIST(name) &xfs_sysfs_attr_##name.attr
46
47 /*
48  * xfs_mount kobject. This currently has no attributes and thus no need for show
49  * and store helpers. The mp kobject serves as the per-mount parent object that
50  * is identified by the fsname under sysfs.
51  */
52
53 struct kobj_type xfs_mp_ktype = {
54         .release = xfs_sysfs_release,
55 };
56
57 #ifdef DEBUG
58 /* debug */
59
60 STATIC ssize_t
61 log_recovery_delay_store(
62         const char      *buf,
63         size_t          count,
64         void            *data)
65 {
66         int             ret;
67         int             val;
68
69         ret = kstrtoint(buf, 0, &val);
70         if (ret)
71                 return ret;
72
73         if (val < 0 || val > 60)
74                 return -EINVAL;
75
76         xfs_globals.log_recovery_delay = val;
77
78         return count;
79 }
80
81 STATIC ssize_t
82 log_recovery_delay_show(
83         char    *buf,
84         void    *data)
85 {
86         return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.log_recovery_delay);
87 }
88 XFS_SYSFS_ATTR_RW(log_recovery_delay);
89
90 static struct attribute *xfs_dbg_attrs[] = {
91         ATTR_LIST(log_recovery_delay),
92         NULL,
93 };
94
95 STATIC ssize_t
96 xfs_dbg_show(
97         struct kobject          *kobject,
98         struct attribute        *attr,
99         char                    *buf)
100 {
101         struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
102
103         return xfs_attr->show ? xfs_attr->show(buf, NULL) : 0;
104 }
105
106 STATIC ssize_t
107 xfs_dbg_store(
108         struct kobject          *kobject,
109         struct attribute        *attr,
110         const char              *buf,
111         size_t                  count)
112 {
113         struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
114
115         return xfs_attr->store ? xfs_attr->store(buf, count, NULL) : 0;
116 }
117
118 static struct sysfs_ops xfs_dbg_ops = {
119         .show = xfs_dbg_show,
120         .store = xfs_dbg_store,
121 };
122
123 struct kobj_type xfs_dbg_ktype = {
124         .release = xfs_sysfs_release,
125         .sysfs_ops = &xfs_dbg_ops,
126         .default_attrs = xfs_dbg_attrs,
127 };
128
129 #endif /* DEBUG */
130
131
132 /* stats */
133
134 STATIC ssize_t
135 stats_show(
136         char    *buf,
137         void    *data)
138 {
139         return xfs_stats_format(buf);
140 }
141 XFS_SYSFS_ATTR_RO(stats);
142
143 STATIC ssize_t
144 stats_clear_store(
145         const char      *buf,
146         size_t          count,
147         void            *data)
148 {
149         int             ret;
150         int             val;
151
152         ret = kstrtoint(buf, 0, &val);
153         if (ret)
154                 return ret;
155
156         if (val != 1)
157                 return -EINVAL;
158         xfs_stats_clearall();
159         return count;
160 }
161 XFS_SYSFS_ATTR_WO(stats_clear);
162
163 static struct attribute *xfs_stats_attrs[] = {
164         ATTR_LIST(stats),
165         ATTR_LIST(stats_clear),
166         NULL,
167 };
168
169 STATIC ssize_t
170 xfs_stats_show(
171         struct kobject          *kobject,
172         struct attribute        *attr,
173         char                    *buf)
174 {
175         struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
176
177         return xfs_attr->show ? xfs_attr->show(buf, NULL) : 0;
178 }
179
180 STATIC ssize_t
181 xfs_stats_store(
182         struct kobject          *kobject,
183         struct attribute        *attr,
184         const char              *buf,
185         size_t                  count)
186 {
187         struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
188
189         return xfs_attr->store ? xfs_attr->store(buf, count, NULL) : 0;
190 }
191
192 static struct sysfs_ops xfs_stats_ops = {
193         .show = xfs_stats_show,
194         .store = xfs_stats_store,
195 };
196
197 struct kobj_type xfs_stats_ktype = {
198         .release = xfs_sysfs_release,
199         .sysfs_ops = &xfs_stats_ops,
200         .default_attrs = xfs_stats_attrs,
201 };
202
203 /* xlog */
204
205 STATIC ssize_t
206 log_head_lsn_show(
207         char    *buf,
208         void    *data)
209 {
210         struct xlog *log = data;
211         int cycle;
212         int block;
213
214         spin_lock(&log->l_icloglock);
215         cycle = log->l_curr_cycle;
216         block = log->l_curr_block;
217         spin_unlock(&log->l_icloglock);
218
219         return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block);
220 }
221 XFS_SYSFS_ATTR_RO(log_head_lsn);
222
223 STATIC ssize_t
224 log_tail_lsn_show(
225         char    *buf,
226         void    *data)
227 {
228         struct xlog *log = data;
229         int cycle;
230         int block;
231
232         xlog_crack_atomic_lsn(&log->l_tail_lsn, &cycle, &block);
233         return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block);
234 }
235 XFS_SYSFS_ATTR_RO(log_tail_lsn);
236
237 STATIC ssize_t
238 reserve_grant_head_show(
239         char    *buf,
240         void    *data)
241 {
242         struct xlog *log = data;
243         int cycle;
244         int bytes;
245
246         xlog_crack_grant_head(&log->l_reserve_head.grant, &cycle, &bytes);
247         return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes);
248 }
249 XFS_SYSFS_ATTR_RO(reserve_grant_head);
250
251 STATIC ssize_t
252 write_grant_head_show(
253         char    *buf,
254         void    *data)
255 {
256         struct xlog *log = data;
257         int cycle;
258         int bytes;
259
260         xlog_crack_grant_head(&log->l_write_head.grant, &cycle, &bytes);
261         return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes);
262 }
263 XFS_SYSFS_ATTR_RO(write_grant_head);
264
265 static struct attribute *xfs_log_attrs[] = {
266         ATTR_LIST(log_head_lsn),
267         ATTR_LIST(log_tail_lsn),
268         ATTR_LIST(reserve_grant_head),
269         ATTR_LIST(write_grant_head),
270         NULL,
271 };
272
273 static inline struct xlog *
274 to_xlog(struct kobject *kobject)
275 {
276         struct xfs_kobj *kobj = to_kobj(kobject);
277         return container_of(kobj, struct xlog, l_kobj);
278 }
279
280 STATIC ssize_t
281 xfs_log_show(
282         struct kobject          *kobject,
283         struct attribute        *attr,
284         char                    *buf)
285 {
286         struct xlog *log = to_xlog(kobject);
287         struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
288
289         return xfs_attr->show ? xfs_attr->show(buf, log) : 0;
290 }
291
292 STATIC ssize_t
293 xfs_log_store(
294         struct kobject          *kobject,
295         struct attribute        *attr,
296         const char              *buf,
297         size_t                  count)
298 {
299         struct xlog *log = to_xlog(kobject);
300         struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
301
302         return xfs_attr->store ? xfs_attr->store(buf, count, log) : 0;
303 }
304
305 static struct sysfs_ops xfs_log_ops = {
306         .show = xfs_log_show,
307         .store = xfs_log_store,
308 };
309
310 struct kobj_type xfs_log_ktype = {
311         .release = xfs_sysfs_release,
312         .sysfs_ops = &xfs_log_ops,
313         .default_attrs = xfs_log_attrs,
314 };