xref: /openbmc/linux/fs/xfs/xfs_sysfs.c (revision e3d786a3)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2014 Red Hat, Inc.
4  * All Rights Reserved.
5  */
6 
7 #include "xfs.h"
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_log_format.h"
11 #include "xfs_trans_resv.h"
12 #include "xfs_sysfs.h"
13 #include "xfs_log.h"
14 #include "xfs_log_priv.h"
15 #include "xfs_stats.h"
16 #include "xfs_mount.h"
17 
18 struct xfs_sysfs_attr {
19 	struct attribute attr;
20 	ssize_t (*show)(struct kobject *kobject, char *buf);
21 	ssize_t (*store)(struct kobject *kobject, const char *buf,
22 			 size_t count);
23 };
24 
25 static inline struct xfs_sysfs_attr *
26 to_attr(struct attribute *attr)
27 {
28 	return container_of(attr, struct xfs_sysfs_attr, attr);
29 }
30 
31 #define XFS_SYSFS_ATTR_RW(name) \
32 	static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RW(name)
33 #define XFS_SYSFS_ATTR_RO(name) \
34 	static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RO(name)
35 #define XFS_SYSFS_ATTR_WO(name) \
36 	static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_WO(name)
37 
38 #define ATTR_LIST(name) &xfs_sysfs_attr_##name.attr
39 
40 STATIC ssize_t
41 xfs_sysfs_object_show(
42 	struct kobject		*kobject,
43 	struct attribute	*attr,
44 	char			*buf)
45 {
46 	struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
47 
48 	return xfs_attr->show ? xfs_attr->show(kobject, buf) : 0;
49 }
50 
51 STATIC ssize_t
52 xfs_sysfs_object_store(
53 	struct kobject		*kobject,
54 	struct attribute	*attr,
55 	const char		*buf,
56 	size_t			count)
57 {
58 	struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
59 
60 	return xfs_attr->store ? xfs_attr->store(kobject, buf, count) : 0;
61 }
62 
63 static const struct sysfs_ops xfs_sysfs_ops = {
64 	.show = xfs_sysfs_object_show,
65 	.store = xfs_sysfs_object_store,
66 };
67 
68 /*
69  * xfs_mount kobject. The mp kobject also serves as the per-mount parent object
70  * that is identified by the fsname under sysfs.
71  */
72 
73 static inline struct xfs_mount *
74 to_mp(struct kobject *kobject)
75 {
76 	struct xfs_kobj *kobj = to_kobj(kobject);
77 
78 	return container_of(kobj, struct xfs_mount, m_kobj);
79 }
80 
81 static struct attribute *xfs_mp_attrs[] = {
82 	NULL,
83 };
84 
85 struct kobj_type xfs_mp_ktype = {
86 	.release = xfs_sysfs_release,
87 	.sysfs_ops = &xfs_sysfs_ops,
88 	.default_attrs = xfs_mp_attrs,
89 };
90 
91 #ifdef DEBUG
92 /* debug */
93 
94 STATIC ssize_t
95 bug_on_assert_store(
96 	struct kobject		*kobject,
97 	const char		*buf,
98 	size_t			count)
99 {
100 	int			ret;
101 	int			val;
102 
103 	ret = kstrtoint(buf, 0, &val);
104 	if (ret)
105 		return ret;
106 
107 	if (val == 1)
108 		xfs_globals.bug_on_assert = true;
109 	else if (val == 0)
110 		xfs_globals.bug_on_assert = false;
111 	else
112 		return -EINVAL;
113 
114 	return count;
115 }
116 
117 STATIC ssize_t
118 bug_on_assert_show(
119 	struct kobject		*kobject,
120 	char			*buf)
121 {
122 	return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.bug_on_assert ? 1 : 0);
123 }
124 XFS_SYSFS_ATTR_RW(bug_on_assert);
125 
126 STATIC ssize_t
127 log_recovery_delay_store(
128 	struct kobject	*kobject,
129 	const char	*buf,
130 	size_t		count)
131 {
132 	int		ret;
133 	int		val;
134 
135 	ret = kstrtoint(buf, 0, &val);
136 	if (ret)
137 		return ret;
138 
139 	if (val < 0 || val > 60)
140 		return -EINVAL;
141 
142 	xfs_globals.log_recovery_delay = val;
143 
144 	return count;
145 }
146 
147 STATIC ssize_t
148 log_recovery_delay_show(
149 	struct kobject	*kobject,
150 	char		*buf)
151 {
152 	return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.log_recovery_delay);
153 }
154 XFS_SYSFS_ATTR_RW(log_recovery_delay);
155 
156 STATIC ssize_t
157 mount_delay_store(
158 	struct kobject	*kobject,
159 	const char	*buf,
160 	size_t		count)
161 {
162 	int		ret;
163 	int		val;
164 
165 	ret = kstrtoint(buf, 0, &val);
166 	if (ret)
167 		return ret;
168 
169 	if (val < 0 || val > 60)
170 		return -EINVAL;
171 
172 	xfs_globals.mount_delay = val;
173 
174 	return count;
175 }
176 
177 STATIC ssize_t
178 mount_delay_show(
179 	struct kobject	*kobject,
180 	char		*buf)
181 {
182 	return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.mount_delay);
183 }
184 XFS_SYSFS_ATTR_RW(mount_delay);
185 
186 static struct attribute *xfs_dbg_attrs[] = {
187 	ATTR_LIST(bug_on_assert),
188 	ATTR_LIST(log_recovery_delay),
189 	ATTR_LIST(mount_delay),
190 	NULL,
191 };
192 
193 struct kobj_type xfs_dbg_ktype = {
194 	.release = xfs_sysfs_release,
195 	.sysfs_ops = &xfs_sysfs_ops,
196 	.default_attrs = xfs_dbg_attrs,
197 };
198 
199 #endif /* DEBUG */
200 
201 /* stats */
202 
203 static inline struct xstats *
204 to_xstats(struct kobject *kobject)
205 {
206 	struct xfs_kobj *kobj = to_kobj(kobject);
207 
208 	return container_of(kobj, struct xstats, xs_kobj);
209 }
210 
211 STATIC ssize_t
212 stats_show(
213 	struct kobject	*kobject,
214 	char		*buf)
215 {
216 	struct xstats	*stats = to_xstats(kobject);
217 
218 	return xfs_stats_format(stats->xs_stats, buf);
219 }
220 XFS_SYSFS_ATTR_RO(stats);
221 
222 STATIC ssize_t
223 stats_clear_store(
224 	struct kobject	*kobject,
225 	const char	*buf,
226 	size_t		count)
227 {
228 	int		ret;
229 	int		val;
230 	struct xstats	*stats = to_xstats(kobject);
231 
232 	ret = kstrtoint(buf, 0, &val);
233 	if (ret)
234 		return ret;
235 
236 	if (val != 1)
237 		return -EINVAL;
238 
239 	xfs_stats_clearall(stats->xs_stats);
240 	return count;
241 }
242 XFS_SYSFS_ATTR_WO(stats_clear);
243 
244 static struct attribute *xfs_stats_attrs[] = {
245 	ATTR_LIST(stats),
246 	ATTR_LIST(stats_clear),
247 	NULL,
248 };
249 
250 struct kobj_type xfs_stats_ktype = {
251 	.release = xfs_sysfs_release,
252 	.sysfs_ops = &xfs_sysfs_ops,
253 	.default_attrs = xfs_stats_attrs,
254 };
255 
256 /* xlog */
257 
258 static inline struct xlog *
259 to_xlog(struct kobject *kobject)
260 {
261 	struct xfs_kobj *kobj = to_kobj(kobject);
262 
263 	return container_of(kobj, struct xlog, l_kobj);
264 }
265 
266 STATIC ssize_t
267 log_head_lsn_show(
268 	struct kobject	*kobject,
269 	char		*buf)
270 {
271 	int cycle;
272 	int block;
273 	struct xlog *log = to_xlog(kobject);
274 
275 	spin_lock(&log->l_icloglock);
276 	cycle = log->l_curr_cycle;
277 	block = log->l_curr_block;
278 	spin_unlock(&log->l_icloglock);
279 
280 	return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block);
281 }
282 XFS_SYSFS_ATTR_RO(log_head_lsn);
283 
284 STATIC ssize_t
285 log_tail_lsn_show(
286 	struct kobject	*kobject,
287 	char		*buf)
288 {
289 	int cycle;
290 	int block;
291 	struct xlog *log = to_xlog(kobject);
292 
293 	xlog_crack_atomic_lsn(&log->l_tail_lsn, &cycle, &block);
294 	return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block);
295 }
296 XFS_SYSFS_ATTR_RO(log_tail_lsn);
297 
298 STATIC ssize_t
299 reserve_grant_head_show(
300 	struct kobject	*kobject,
301 	char		*buf)
302 
303 {
304 	int cycle;
305 	int bytes;
306 	struct xlog *log = to_xlog(kobject);
307 
308 	xlog_crack_grant_head(&log->l_reserve_head.grant, &cycle, &bytes);
309 	return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes);
310 }
311 XFS_SYSFS_ATTR_RO(reserve_grant_head);
312 
313 STATIC ssize_t
314 write_grant_head_show(
315 	struct kobject	*kobject,
316 	char		*buf)
317 {
318 	int cycle;
319 	int bytes;
320 	struct xlog *log = to_xlog(kobject);
321 
322 	xlog_crack_grant_head(&log->l_write_head.grant, &cycle, &bytes);
323 	return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes);
324 }
325 XFS_SYSFS_ATTR_RO(write_grant_head);
326 
327 static struct attribute *xfs_log_attrs[] = {
328 	ATTR_LIST(log_head_lsn),
329 	ATTR_LIST(log_tail_lsn),
330 	ATTR_LIST(reserve_grant_head),
331 	ATTR_LIST(write_grant_head),
332 	NULL,
333 };
334 
335 struct kobj_type xfs_log_ktype = {
336 	.release = xfs_sysfs_release,
337 	.sysfs_ops = &xfs_sysfs_ops,
338 	.default_attrs = xfs_log_attrs,
339 };
340 
341 /*
342  * Metadata IO error configuration
343  *
344  * The sysfs structure here is:
345  *	...xfs/<dev>/error/<class>/<errno>/<error_attrs>
346  *
347  * where <class> allows us to discriminate between data IO and metadata IO,
348  * and any other future type of IO (e.g. special inode or directory error
349  * handling) we care to support.
350  */
351 static inline struct xfs_error_cfg *
352 to_error_cfg(struct kobject *kobject)
353 {
354 	struct xfs_kobj *kobj = to_kobj(kobject);
355 	return container_of(kobj, struct xfs_error_cfg, kobj);
356 }
357 
358 static inline struct xfs_mount *
359 err_to_mp(struct kobject *kobject)
360 {
361 	struct xfs_kobj *kobj = to_kobj(kobject);
362 	return container_of(kobj, struct xfs_mount, m_error_kobj);
363 }
364 
365 static ssize_t
366 max_retries_show(
367 	struct kobject	*kobject,
368 	char		*buf)
369 {
370 	int		retries;
371 	struct xfs_error_cfg *cfg = to_error_cfg(kobject);
372 
373 	if (cfg->max_retries == XFS_ERR_RETRY_FOREVER)
374 		retries = -1;
375 	else
376 		retries = cfg->max_retries;
377 
378 	return snprintf(buf, PAGE_SIZE, "%d\n", retries);
379 }
380 
381 static ssize_t
382 max_retries_store(
383 	struct kobject	*kobject,
384 	const char	*buf,
385 	size_t		count)
386 {
387 	struct xfs_error_cfg *cfg = to_error_cfg(kobject);
388 	int		ret;
389 	int		val;
390 
391 	ret = kstrtoint(buf, 0, &val);
392 	if (ret)
393 		return ret;
394 
395 	if (val < -1)
396 		return -EINVAL;
397 
398 	if (val == -1)
399 		cfg->max_retries = XFS_ERR_RETRY_FOREVER;
400 	else
401 		cfg->max_retries = val;
402 	return count;
403 }
404 XFS_SYSFS_ATTR_RW(max_retries);
405 
406 static ssize_t
407 retry_timeout_seconds_show(
408 	struct kobject	*kobject,
409 	char		*buf)
410 {
411 	int		timeout;
412 	struct xfs_error_cfg *cfg = to_error_cfg(kobject);
413 
414 	if (cfg->retry_timeout == XFS_ERR_RETRY_FOREVER)
415 		timeout = -1;
416 	else
417 		timeout = jiffies_to_msecs(cfg->retry_timeout) / MSEC_PER_SEC;
418 
419 	return snprintf(buf, PAGE_SIZE, "%d\n", timeout);
420 }
421 
422 static ssize_t
423 retry_timeout_seconds_store(
424 	struct kobject	*kobject,
425 	const char	*buf,
426 	size_t		count)
427 {
428 	struct xfs_error_cfg *cfg = to_error_cfg(kobject);
429 	int		ret;
430 	int		val;
431 
432 	ret = kstrtoint(buf, 0, &val);
433 	if (ret)
434 		return ret;
435 
436 	/* 1 day timeout maximum, -1 means infinite */
437 	if (val < -1 || val > 86400)
438 		return -EINVAL;
439 
440 	if (val == -1)
441 		cfg->retry_timeout = XFS_ERR_RETRY_FOREVER;
442 	else {
443 		cfg->retry_timeout = msecs_to_jiffies(val * MSEC_PER_SEC);
444 		ASSERT(msecs_to_jiffies(val * MSEC_PER_SEC) < LONG_MAX);
445 	}
446 	return count;
447 }
448 XFS_SYSFS_ATTR_RW(retry_timeout_seconds);
449 
450 static ssize_t
451 fail_at_unmount_show(
452 	struct kobject	*kobject,
453 	char		*buf)
454 {
455 	struct xfs_mount	*mp = err_to_mp(kobject);
456 
457 	return snprintf(buf, PAGE_SIZE, "%d\n", mp->m_fail_unmount);
458 }
459 
460 static ssize_t
461 fail_at_unmount_store(
462 	struct kobject	*kobject,
463 	const char	*buf,
464 	size_t		count)
465 {
466 	struct xfs_mount	*mp = err_to_mp(kobject);
467 	int		ret;
468 	int		val;
469 
470 	ret = kstrtoint(buf, 0, &val);
471 	if (ret)
472 		return ret;
473 
474 	if (val < 0 || val > 1)
475 		return -EINVAL;
476 
477 	mp->m_fail_unmount = val;
478 	return count;
479 }
480 XFS_SYSFS_ATTR_RW(fail_at_unmount);
481 
482 static struct attribute *xfs_error_attrs[] = {
483 	ATTR_LIST(max_retries),
484 	ATTR_LIST(retry_timeout_seconds),
485 	NULL,
486 };
487 
488 
489 static struct kobj_type xfs_error_cfg_ktype = {
490 	.release = xfs_sysfs_release,
491 	.sysfs_ops = &xfs_sysfs_ops,
492 	.default_attrs = xfs_error_attrs,
493 };
494 
495 static struct kobj_type xfs_error_ktype = {
496 	.release = xfs_sysfs_release,
497 	.sysfs_ops = &xfs_sysfs_ops,
498 };
499 
500 /*
501  * Error initialization tables. These need to be ordered in the same
502  * order as the enums used to index the array. All class init tables need to
503  * define a "default" behaviour as the first entry, all other entries can be
504  * empty.
505  */
506 struct xfs_error_init {
507 	char		*name;
508 	int		max_retries;
509 	int		retry_timeout;	/* in seconds */
510 };
511 
512 static const struct xfs_error_init xfs_error_meta_init[XFS_ERR_ERRNO_MAX] = {
513 	{ .name = "default",
514 	  .max_retries = XFS_ERR_RETRY_FOREVER,
515 	  .retry_timeout = XFS_ERR_RETRY_FOREVER,
516 	},
517 	{ .name = "EIO",
518 	  .max_retries = XFS_ERR_RETRY_FOREVER,
519 	  .retry_timeout = XFS_ERR_RETRY_FOREVER,
520 	},
521 	{ .name = "ENOSPC",
522 	  .max_retries = XFS_ERR_RETRY_FOREVER,
523 	  .retry_timeout = XFS_ERR_RETRY_FOREVER,
524 	},
525 	{ .name = "ENODEV",
526 	  .max_retries = 0,	/* We can't recover from devices disappearing */
527 	  .retry_timeout = 0,
528 	},
529 };
530 
531 static int
532 xfs_error_sysfs_init_class(
533 	struct xfs_mount	*mp,
534 	int			class,
535 	const char		*parent_name,
536 	struct xfs_kobj		*parent_kobj,
537 	const struct xfs_error_init init[])
538 {
539 	struct xfs_error_cfg	*cfg;
540 	int			error;
541 	int			i;
542 
543 	ASSERT(class < XFS_ERR_CLASS_MAX);
544 
545 	error = xfs_sysfs_init(parent_kobj, &xfs_error_ktype,
546 				&mp->m_error_kobj, parent_name);
547 	if (error)
548 		return error;
549 
550 	for (i = 0; i < XFS_ERR_ERRNO_MAX; i++) {
551 		cfg = &mp->m_error_cfg[class][i];
552 		error = xfs_sysfs_init(&cfg->kobj, &xfs_error_cfg_ktype,
553 					parent_kobj, init[i].name);
554 		if (error)
555 			goto out_error;
556 
557 		cfg->max_retries = init[i].max_retries;
558 		if (init[i].retry_timeout == XFS_ERR_RETRY_FOREVER)
559 			cfg->retry_timeout = XFS_ERR_RETRY_FOREVER;
560 		else
561 			cfg->retry_timeout = msecs_to_jiffies(
562 					init[i].retry_timeout * MSEC_PER_SEC);
563 	}
564 	return 0;
565 
566 out_error:
567 	/* unwind the entries that succeeded */
568 	for (i--; i >= 0; i--) {
569 		cfg = &mp->m_error_cfg[class][i];
570 		xfs_sysfs_del(&cfg->kobj);
571 	}
572 	xfs_sysfs_del(parent_kobj);
573 	return error;
574 }
575 
576 int
577 xfs_error_sysfs_init(
578 	struct xfs_mount	*mp)
579 {
580 	int			error;
581 
582 	/* .../xfs/<dev>/error/ */
583 	error = xfs_sysfs_init(&mp->m_error_kobj, &xfs_error_ktype,
584 				&mp->m_kobj, "error");
585 	if (error)
586 		return error;
587 
588 	error = sysfs_create_file(&mp->m_error_kobj.kobject,
589 				  ATTR_LIST(fail_at_unmount));
590 
591 	if (error)
592 		goto out_error;
593 
594 	/* .../xfs/<dev>/error/metadata/ */
595 	error = xfs_error_sysfs_init_class(mp, XFS_ERR_METADATA,
596 				"metadata", &mp->m_error_meta_kobj,
597 				xfs_error_meta_init);
598 	if (error)
599 		goto out_error;
600 
601 	return 0;
602 
603 out_error:
604 	xfs_sysfs_del(&mp->m_error_kobj);
605 	return error;
606 }
607 
608 void
609 xfs_error_sysfs_del(
610 	struct xfs_mount	*mp)
611 {
612 	struct xfs_error_cfg	*cfg;
613 	int			i, j;
614 
615 	for (i = 0; i < XFS_ERR_CLASS_MAX; i++) {
616 		for (j = 0; j < XFS_ERR_ERRNO_MAX; j++) {
617 			cfg = &mp->m_error_cfg[i][j];
618 
619 			xfs_sysfs_del(&cfg->kobj);
620 		}
621 	}
622 	xfs_sysfs_del(&mp->m_error_meta_kobj);
623 	xfs_sysfs_del(&mp->m_error_kobj);
624 }
625 
626 struct xfs_error_cfg *
627 xfs_error_get_cfg(
628 	struct xfs_mount	*mp,
629 	int			error_class,
630 	int			error)
631 {
632 	struct xfs_error_cfg	*cfg;
633 
634 	if (error < 0)
635 		error = -error;
636 
637 	switch (error) {
638 	case EIO:
639 		cfg = &mp->m_error_cfg[error_class][XFS_ERR_EIO];
640 		break;
641 	case ENOSPC:
642 		cfg = &mp->m_error_cfg[error_class][XFS_ERR_ENOSPC];
643 		break;
644 	case ENODEV:
645 		cfg = &mp->m_error_cfg[error_class][XFS_ERR_ENODEV];
646 		break;
647 	default:
648 		cfg = &mp->m_error_cfg[error_class][XFS_ERR_DEFAULT];
649 		break;
650 	}
651 
652 	return cfg;
653 }
654