xref: /linux/fs/xfs/xfs_sysfs.c (revision b7019ac550eb3916f34d79db583e9b7ea2524afa)
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 ssize_t
187 always_cow_store(
188 	struct kobject	*kobject,
189 	const char	*buf,
190 	size_t		count)
191 {
192 	ssize_t		ret;
193 
194 	ret = kstrtobool(buf, &xfs_globals.always_cow);
195 	if (ret < 0)
196 		return ret;
197 	return count;
198 }
199 
200 static ssize_t
201 always_cow_show(
202 	struct kobject	*kobject,
203 	char		*buf)
204 {
205 	return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.always_cow);
206 }
207 XFS_SYSFS_ATTR_RW(always_cow);
208 
209 static struct attribute *xfs_dbg_attrs[] = {
210 	ATTR_LIST(bug_on_assert),
211 	ATTR_LIST(log_recovery_delay),
212 	ATTR_LIST(mount_delay),
213 	ATTR_LIST(always_cow),
214 	NULL,
215 };
216 
217 struct kobj_type xfs_dbg_ktype = {
218 	.release = xfs_sysfs_release,
219 	.sysfs_ops = &xfs_sysfs_ops,
220 	.default_attrs = xfs_dbg_attrs,
221 };
222 
223 #endif /* DEBUG */
224 
225 /* stats */
226 
227 static inline struct xstats *
228 to_xstats(struct kobject *kobject)
229 {
230 	struct xfs_kobj *kobj = to_kobj(kobject);
231 
232 	return container_of(kobj, struct xstats, xs_kobj);
233 }
234 
235 STATIC ssize_t
236 stats_show(
237 	struct kobject	*kobject,
238 	char		*buf)
239 {
240 	struct xstats	*stats = to_xstats(kobject);
241 
242 	return xfs_stats_format(stats->xs_stats, buf);
243 }
244 XFS_SYSFS_ATTR_RO(stats);
245 
246 STATIC ssize_t
247 stats_clear_store(
248 	struct kobject	*kobject,
249 	const char	*buf,
250 	size_t		count)
251 {
252 	int		ret;
253 	int		val;
254 	struct xstats	*stats = to_xstats(kobject);
255 
256 	ret = kstrtoint(buf, 0, &val);
257 	if (ret)
258 		return ret;
259 
260 	if (val != 1)
261 		return -EINVAL;
262 
263 	xfs_stats_clearall(stats->xs_stats);
264 	return count;
265 }
266 XFS_SYSFS_ATTR_WO(stats_clear);
267 
268 static struct attribute *xfs_stats_attrs[] = {
269 	ATTR_LIST(stats),
270 	ATTR_LIST(stats_clear),
271 	NULL,
272 };
273 
274 struct kobj_type xfs_stats_ktype = {
275 	.release = xfs_sysfs_release,
276 	.sysfs_ops = &xfs_sysfs_ops,
277 	.default_attrs = xfs_stats_attrs,
278 };
279 
280 /* xlog */
281 
282 static inline struct xlog *
283 to_xlog(struct kobject *kobject)
284 {
285 	struct xfs_kobj *kobj = to_kobj(kobject);
286 
287 	return container_of(kobj, struct xlog, l_kobj);
288 }
289 
290 STATIC ssize_t
291 log_head_lsn_show(
292 	struct kobject	*kobject,
293 	char		*buf)
294 {
295 	int cycle;
296 	int block;
297 	struct xlog *log = to_xlog(kobject);
298 
299 	spin_lock(&log->l_icloglock);
300 	cycle = log->l_curr_cycle;
301 	block = log->l_curr_block;
302 	spin_unlock(&log->l_icloglock);
303 
304 	return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block);
305 }
306 XFS_SYSFS_ATTR_RO(log_head_lsn);
307 
308 STATIC ssize_t
309 log_tail_lsn_show(
310 	struct kobject	*kobject,
311 	char		*buf)
312 {
313 	int cycle;
314 	int block;
315 	struct xlog *log = to_xlog(kobject);
316 
317 	xlog_crack_atomic_lsn(&log->l_tail_lsn, &cycle, &block);
318 	return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block);
319 }
320 XFS_SYSFS_ATTR_RO(log_tail_lsn);
321 
322 STATIC ssize_t
323 reserve_grant_head_show(
324 	struct kobject	*kobject,
325 	char		*buf)
326 
327 {
328 	int cycle;
329 	int bytes;
330 	struct xlog *log = to_xlog(kobject);
331 
332 	xlog_crack_grant_head(&log->l_reserve_head.grant, &cycle, &bytes);
333 	return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes);
334 }
335 XFS_SYSFS_ATTR_RO(reserve_grant_head);
336 
337 STATIC ssize_t
338 write_grant_head_show(
339 	struct kobject	*kobject,
340 	char		*buf)
341 {
342 	int cycle;
343 	int bytes;
344 	struct xlog *log = to_xlog(kobject);
345 
346 	xlog_crack_grant_head(&log->l_write_head.grant, &cycle, &bytes);
347 	return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes);
348 }
349 XFS_SYSFS_ATTR_RO(write_grant_head);
350 
351 static struct attribute *xfs_log_attrs[] = {
352 	ATTR_LIST(log_head_lsn),
353 	ATTR_LIST(log_tail_lsn),
354 	ATTR_LIST(reserve_grant_head),
355 	ATTR_LIST(write_grant_head),
356 	NULL,
357 };
358 
359 struct kobj_type xfs_log_ktype = {
360 	.release = xfs_sysfs_release,
361 	.sysfs_ops = &xfs_sysfs_ops,
362 	.default_attrs = xfs_log_attrs,
363 };
364 
365 /*
366  * Metadata IO error configuration
367  *
368  * The sysfs structure here is:
369  *	...xfs/<dev>/error/<class>/<errno>/<error_attrs>
370  *
371  * where <class> allows us to discriminate between data IO and metadata IO,
372  * and any other future type of IO (e.g. special inode or directory error
373  * handling) we care to support.
374  */
375 static inline struct xfs_error_cfg *
376 to_error_cfg(struct kobject *kobject)
377 {
378 	struct xfs_kobj *kobj = to_kobj(kobject);
379 	return container_of(kobj, struct xfs_error_cfg, kobj);
380 }
381 
382 static inline struct xfs_mount *
383 err_to_mp(struct kobject *kobject)
384 {
385 	struct xfs_kobj *kobj = to_kobj(kobject);
386 	return container_of(kobj, struct xfs_mount, m_error_kobj);
387 }
388 
389 static ssize_t
390 max_retries_show(
391 	struct kobject	*kobject,
392 	char		*buf)
393 {
394 	int		retries;
395 	struct xfs_error_cfg *cfg = to_error_cfg(kobject);
396 
397 	if (cfg->max_retries == XFS_ERR_RETRY_FOREVER)
398 		retries = -1;
399 	else
400 		retries = cfg->max_retries;
401 
402 	return snprintf(buf, PAGE_SIZE, "%d\n", retries);
403 }
404 
405 static ssize_t
406 max_retries_store(
407 	struct kobject	*kobject,
408 	const char	*buf,
409 	size_t		count)
410 {
411 	struct xfs_error_cfg *cfg = to_error_cfg(kobject);
412 	int		ret;
413 	int		val;
414 
415 	ret = kstrtoint(buf, 0, &val);
416 	if (ret)
417 		return ret;
418 
419 	if (val < -1)
420 		return -EINVAL;
421 
422 	if (val == -1)
423 		cfg->max_retries = XFS_ERR_RETRY_FOREVER;
424 	else
425 		cfg->max_retries = val;
426 	return count;
427 }
428 XFS_SYSFS_ATTR_RW(max_retries);
429 
430 static ssize_t
431 retry_timeout_seconds_show(
432 	struct kobject	*kobject,
433 	char		*buf)
434 {
435 	int		timeout;
436 	struct xfs_error_cfg *cfg = to_error_cfg(kobject);
437 
438 	if (cfg->retry_timeout == XFS_ERR_RETRY_FOREVER)
439 		timeout = -1;
440 	else
441 		timeout = jiffies_to_msecs(cfg->retry_timeout) / MSEC_PER_SEC;
442 
443 	return snprintf(buf, PAGE_SIZE, "%d\n", timeout);
444 }
445 
446 static ssize_t
447 retry_timeout_seconds_store(
448 	struct kobject	*kobject,
449 	const char	*buf,
450 	size_t		count)
451 {
452 	struct xfs_error_cfg *cfg = to_error_cfg(kobject);
453 	int		ret;
454 	int		val;
455 
456 	ret = kstrtoint(buf, 0, &val);
457 	if (ret)
458 		return ret;
459 
460 	/* 1 day timeout maximum, -1 means infinite */
461 	if (val < -1 || val > 86400)
462 		return -EINVAL;
463 
464 	if (val == -1)
465 		cfg->retry_timeout = XFS_ERR_RETRY_FOREVER;
466 	else {
467 		cfg->retry_timeout = msecs_to_jiffies(val * MSEC_PER_SEC);
468 		ASSERT(msecs_to_jiffies(val * MSEC_PER_SEC) < LONG_MAX);
469 	}
470 	return count;
471 }
472 XFS_SYSFS_ATTR_RW(retry_timeout_seconds);
473 
474 static ssize_t
475 fail_at_unmount_show(
476 	struct kobject	*kobject,
477 	char		*buf)
478 {
479 	struct xfs_mount	*mp = err_to_mp(kobject);
480 
481 	return snprintf(buf, PAGE_SIZE, "%d\n", mp->m_fail_unmount);
482 }
483 
484 static ssize_t
485 fail_at_unmount_store(
486 	struct kobject	*kobject,
487 	const char	*buf,
488 	size_t		count)
489 {
490 	struct xfs_mount	*mp = err_to_mp(kobject);
491 	int		ret;
492 	int		val;
493 
494 	ret = kstrtoint(buf, 0, &val);
495 	if (ret)
496 		return ret;
497 
498 	if (val < 0 || val > 1)
499 		return -EINVAL;
500 
501 	mp->m_fail_unmount = val;
502 	return count;
503 }
504 XFS_SYSFS_ATTR_RW(fail_at_unmount);
505 
506 static struct attribute *xfs_error_attrs[] = {
507 	ATTR_LIST(max_retries),
508 	ATTR_LIST(retry_timeout_seconds),
509 	NULL,
510 };
511 
512 
513 static struct kobj_type xfs_error_cfg_ktype = {
514 	.release = xfs_sysfs_release,
515 	.sysfs_ops = &xfs_sysfs_ops,
516 	.default_attrs = xfs_error_attrs,
517 };
518 
519 static struct kobj_type xfs_error_ktype = {
520 	.release = xfs_sysfs_release,
521 	.sysfs_ops = &xfs_sysfs_ops,
522 };
523 
524 /*
525  * Error initialization tables. These need to be ordered in the same
526  * order as the enums used to index the array. All class init tables need to
527  * define a "default" behaviour as the first entry, all other entries can be
528  * empty.
529  */
530 struct xfs_error_init {
531 	char		*name;
532 	int		max_retries;
533 	int		retry_timeout;	/* in seconds */
534 };
535 
536 static const struct xfs_error_init xfs_error_meta_init[XFS_ERR_ERRNO_MAX] = {
537 	{ .name = "default",
538 	  .max_retries = XFS_ERR_RETRY_FOREVER,
539 	  .retry_timeout = XFS_ERR_RETRY_FOREVER,
540 	},
541 	{ .name = "EIO",
542 	  .max_retries = XFS_ERR_RETRY_FOREVER,
543 	  .retry_timeout = XFS_ERR_RETRY_FOREVER,
544 	},
545 	{ .name = "ENOSPC",
546 	  .max_retries = XFS_ERR_RETRY_FOREVER,
547 	  .retry_timeout = XFS_ERR_RETRY_FOREVER,
548 	},
549 	{ .name = "ENODEV",
550 	  .max_retries = 0,	/* We can't recover from devices disappearing */
551 	  .retry_timeout = 0,
552 	},
553 };
554 
555 static int
556 xfs_error_sysfs_init_class(
557 	struct xfs_mount	*mp,
558 	int			class,
559 	const char		*parent_name,
560 	struct xfs_kobj		*parent_kobj,
561 	const struct xfs_error_init init[])
562 {
563 	struct xfs_error_cfg	*cfg;
564 	int			error;
565 	int			i;
566 
567 	ASSERT(class < XFS_ERR_CLASS_MAX);
568 
569 	error = xfs_sysfs_init(parent_kobj, &xfs_error_ktype,
570 				&mp->m_error_kobj, parent_name);
571 	if (error)
572 		return error;
573 
574 	for (i = 0; i < XFS_ERR_ERRNO_MAX; i++) {
575 		cfg = &mp->m_error_cfg[class][i];
576 		error = xfs_sysfs_init(&cfg->kobj, &xfs_error_cfg_ktype,
577 					parent_kobj, init[i].name);
578 		if (error)
579 			goto out_error;
580 
581 		cfg->max_retries = init[i].max_retries;
582 		if (init[i].retry_timeout == XFS_ERR_RETRY_FOREVER)
583 			cfg->retry_timeout = XFS_ERR_RETRY_FOREVER;
584 		else
585 			cfg->retry_timeout = msecs_to_jiffies(
586 					init[i].retry_timeout * MSEC_PER_SEC);
587 	}
588 	return 0;
589 
590 out_error:
591 	/* unwind the entries that succeeded */
592 	for (i--; i >= 0; i--) {
593 		cfg = &mp->m_error_cfg[class][i];
594 		xfs_sysfs_del(&cfg->kobj);
595 	}
596 	xfs_sysfs_del(parent_kobj);
597 	return error;
598 }
599 
600 int
601 xfs_error_sysfs_init(
602 	struct xfs_mount	*mp)
603 {
604 	int			error;
605 
606 	/* .../xfs/<dev>/error/ */
607 	error = xfs_sysfs_init(&mp->m_error_kobj, &xfs_error_ktype,
608 				&mp->m_kobj, "error");
609 	if (error)
610 		return error;
611 
612 	error = sysfs_create_file(&mp->m_error_kobj.kobject,
613 				  ATTR_LIST(fail_at_unmount));
614 
615 	if (error)
616 		goto out_error;
617 
618 	/* .../xfs/<dev>/error/metadata/ */
619 	error = xfs_error_sysfs_init_class(mp, XFS_ERR_METADATA,
620 				"metadata", &mp->m_error_meta_kobj,
621 				xfs_error_meta_init);
622 	if (error)
623 		goto out_error;
624 
625 	return 0;
626 
627 out_error:
628 	xfs_sysfs_del(&mp->m_error_kobj);
629 	return error;
630 }
631 
632 void
633 xfs_error_sysfs_del(
634 	struct xfs_mount	*mp)
635 {
636 	struct xfs_error_cfg	*cfg;
637 	int			i, j;
638 
639 	for (i = 0; i < XFS_ERR_CLASS_MAX; i++) {
640 		for (j = 0; j < XFS_ERR_ERRNO_MAX; j++) {
641 			cfg = &mp->m_error_cfg[i][j];
642 
643 			xfs_sysfs_del(&cfg->kobj);
644 		}
645 	}
646 	xfs_sysfs_del(&mp->m_error_meta_kobj);
647 	xfs_sysfs_del(&mp->m_error_kobj);
648 }
649 
650 struct xfs_error_cfg *
651 xfs_error_get_cfg(
652 	struct xfs_mount	*mp,
653 	int			error_class,
654 	int			error)
655 {
656 	struct xfs_error_cfg	*cfg;
657 
658 	if (error < 0)
659 		error = -error;
660 
661 	switch (error) {
662 	case EIO:
663 		cfg = &mp->m_error_cfg[error_class][XFS_ERR_EIO];
664 		break;
665 	case ENOSPC:
666 		cfg = &mp->m_error_cfg[error_class][XFS_ERR_ENOSPC];
667 		break;
668 	case ENODEV:
669 		cfg = &mp->m_error_cfg[error_class][XFS_ERR_ENODEV];
670 		break;
671 	default:
672 		cfg = &mp->m_error_cfg[error_class][XFS_ERR_DEFAULT];
673 		break;
674 	}
675 
676 	return cfg;
677 }
678