blob: a094e20f567b36339fba12851ef3b424092489c7 [file] [log] [blame]
Brian Fostera31b1d32014-07-15 08:07:01 +10001/*
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"
Brian Fosterbaff4e42014-07-15 08:07:29 +100021#include "xfs_log_format.h"
22#include "xfs_log.h"
23#include "xfs_log_priv.h"
Bill O'Donnellbb230c12015-10-12 05:15:45 +110024#include "xfs_stats.h"
Brian Fostera31b1d32014-07-15 08:07:01 +100025
26struct 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
32static inline struct xfs_sysfs_attr *
33to_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)
Bill O'Donnellbb230c12015-10-12 05:15:45 +110042#define XFS_SYSFS_ATTR_WO(name) \
43 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_WO(name)
Brian Fostera31b1d32014-07-15 08:07:01 +100044
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
53struct kobj_type xfs_mp_ktype = {
54 .release = xfs_sysfs_release,
55};
Brian Fosterbaff4e42014-07-15 08:07:29 +100056
Brian Foster65b65732014-09-09 11:52:42 +100057#ifdef DEBUG
58/* debug */
59
Brian Foster2e227172014-09-09 11:56:13 +100060STATIC ssize_t
61log_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
81STATIC ssize_t
82log_recovery_delay_show(
83 char *buf,
84 void *data)
85{
86 return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.log_recovery_delay);
87}
88XFS_SYSFS_ATTR_RW(log_recovery_delay);
89
Brian Foster65b65732014-09-09 11:52:42 +100090static struct attribute *xfs_dbg_attrs[] = {
Brian Foster2e227172014-09-09 11:56:13 +100091 ATTR_LIST(log_recovery_delay),
Brian Foster65b65732014-09-09 11:52:42 +100092 NULL,
93};
94
95STATIC ssize_t
96xfs_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
106STATIC ssize_t
107xfs_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
118static struct sysfs_ops xfs_dbg_ops = {
119 .show = xfs_dbg_show,
120 .store = xfs_dbg_store,
121};
122
123struct 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
Bill O'Donnellbb230c12015-10-12 05:15:45 +1100131
132/* stats */
133
134STATIC ssize_t
135stats_show(
136 char *buf,
137 void *data)
138{
139 return xfs_stats_format(buf);
140}
141XFS_SYSFS_ATTR_RO(stats);
142
143STATIC ssize_t
144stats_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}
161XFS_SYSFS_ATTR_WO(stats_clear);
162
163static struct attribute *xfs_stats_attrs[] = {
164 ATTR_LIST(stats),
165 ATTR_LIST(stats_clear),
166 NULL,
167};
168
169STATIC ssize_t
170xfs_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
180STATIC ssize_t
181xfs_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
192static struct sysfs_ops xfs_stats_ops = {
193 .show = xfs_stats_show,
194 .store = xfs_stats_store,
195};
196
197struct kobj_type xfs_stats_ktype = {
198 .release = xfs_sysfs_release,
199 .sysfs_ops = &xfs_stats_ops,
200 .default_attrs = xfs_stats_attrs,
201};
202
Brian Fosterbaff4e42014-07-15 08:07:29 +1000203/* xlog */
204
Brian Foster80d6d692014-07-15 08:07:48 +1000205STATIC ssize_t
206log_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}
221XFS_SYSFS_ATTR_RO(log_head_lsn);
222
223STATIC ssize_t
224log_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}
235XFS_SYSFS_ATTR_RO(log_tail_lsn);
236
237STATIC ssize_t
238reserve_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}
249XFS_SYSFS_ATTR_RO(reserve_grant_head);
250
251STATIC ssize_t
252write_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}
263XFS_SYSFS_ATTR_RO(write_grant_head);
264
Brian Fosterbaff4e42014-07-15 08:07:29 +1000265static struct attribute *xfs_log_attrs[] = {
Brian Foster80d6d692014-07-15 08:07:48 +1000266 ATTR_LIST(log_head_lsn),
267 ATTR_LIST(log_tail_lsn),
268 ATTR_LIST(reserve_grant_head),
269 ATTR_LIST(write_grant_head),
Brian Fosterbaff4e42014-07-15 08:07:29 +1000270 NULL,
271};
272
273static inline struct xlog *
274to_xlog(struct kobject *kobject)
275{
276 struct xfs_kobj *kobj = to_kobj(kobject);
277 return container_of(kobj, struct xlog, l_kobj);
278}
279
280STATIC ssize_t
281xfs_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
292STATIC ssize_t
293xfs_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
305static struct sysfs_ops xfs_log_ops = {
306 .show = xfs_log_show,
307 .store = xfs_log_store,
308};
309
310struct kobj_type xfs_log_ktype = {
311 .release = xfs_sysfs_release,
312 .sysfs_ops = &xfs_log_ops,
313 .default_attrs = xfs_log_attrs,
314};