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