1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2014 Red Hat, Inc.
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_priv.h"
14 #include "xfs_mount.h"
16 struct xfs_sysfs_attr
{
17 struct attribute attr
;
18 ssize_t (*show
)(struct kobject
*kobject
, char *buf
);
19 ssize_t (*store
)(struct kobject
*kobject
, const char *buf
,
23 static inline struct xfs_sysfs_attr
*
24 to_attr(struct attribute
*attr
)
26 return container_of(attr
, struct xfs_sysfs_attr
, attr
);
29 #define XFS_SYSFS_ATTR_RW(name) \
30 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RW(name)
31 #define XFS_SYSFS_ATTR_RO(name) \
32 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RO(name)
33 #define XFS_SYSFS_ATTR_WO(name) \
34 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_WO(name)
36 #define ATTR_LIST(name) &xfs_sysfs_attr_##name.attr
39 xfs_sysfs_object_show(
40 struct kobject
*kobject
,
41 struct attribute
*attr
,
44 struct xfs_sysfs_attr
*xfs_attr
= to_attr(attr
);
46 return xfs_attr
->show
? xfs_attr
->show(kobject
, buf
) : 0;
50 xfs_sysfs_object_store(
51 struct kobject
*kobject
,
52 struct attribute
*attr
,
56 struct xfs_sysfs_attr
*xfs_attr
= to_attr(attr
);
58 return xfs_attr
->store
? xfs_attr
->store(kobject
, buf
, count
) : 0;
61 static const struct sysfs_ops xfs_sysfs_ops
= {
62 .show
= xfs_sysfs_object_show
,
63 .store
= xfs_sysfs_object_store
,
66 static struct attribute
*xfs_mp_attrs
[] = {
70 struct kobj_type xfs_mp_ktype
= {
71 .release
= xfs_sysfs_release
,
72 .sysfs_ops
= &xfs_sysfs_ops
,
73 .default_attrs
= xfs_mp_attrs
,
81 struct kobject
*kobject
,
88 ret
= kstrtoint(buf
, 0, &val
);
93 xfs_globals
.bug_on_assert
= true;
95 xfs_globals
.bug_on_assert
= false;
104 struct kobject
*kobject
,
107 return snprintf(buf
, PAGE_SIZE
, "%d\n", xfs_globals
.bug_on_assert
? 1 : 0);
109 XFS_SYSFS_ATTR_RW(bug_on_assert
);
112 log_recovery_delay_store(
113 struct kobject
*kobject
,
120 ret
= kstrtoint(buf
, 0, &val
);
124 if (val
< 0 || val
> 60)
127 xfs_globals
.log_recovery_delay
= val
;
133 log_recovery_delay_show(
134 struct kobject
*kobject
,
137 return snprintf(buf
, PAGE_SIZE
, "%d\n", xfs_globals
.log_recovery_delay
);
139 XFS_SYSFS_ATTR_RW(log_recovery_delay
);
143 struct kobject
*kobject
,
150 ret
= kstrtoint(buf
, 0, &val
);
154 if (val
< 0 || val
> 60)
157 xfs_globals
.mount_delay
= val
;
164 struct kobject
*kobject
,
167 return snprintf(buf
, PAGE_SIZE
, "%d\n", xfs_globals
.mount_delay
);
169 XFS_SYSFS_ATTR_RW(mount_delay
);
173 struct kobject
*kobject
,
179 ret
= kstrtobool(buf
, &xfs_globals
.always_cow
);
187 struct kobject
*kobject
,
190 return snprintf(buf
, PAGE_SIZE
, "%d\n", xfs_globals
.always_cow
);
192 XFS_SYSFS_ATTR_RW(always_cow
);
196 * Override how many threads the parallel work queue is allowed to create.
197 * This has to be a debug-only global (instead of an errortag) because one of
198 * the main users of parallel workqueues is mount time quotacheck.
202 struct kobject
*kobject
,
209 ret
= kstrtoint(buf
, 0, &val
);
213 if (val
< -1 || val
> num_possible_cpus())
216 xfs_globals
.pwork_threads
= val
;
223 struct kobject
*kobject
,
226 return snprintf(buf
, PAGE_SIZE
, "%d\n", xfs_globals
.pwork_threads
);
228 XFS_SYSFS_ATTR_RW(pwork_threads
);
231 static struct attribute
*xfs_dbg_attrs
[] = {
232 ATTR_LIST(bug_on_assert
),
233 ATTR_LIST(log_recovery_delay
),
234 ATTR_LIST(mount_delay
),
235 ATTR_LIST(always_cow
),
237 ATTR_LIST(pwork_threads
),
242 struct kobj_type xfs_dbg_ktype
= {
243 .release
= xfs_sysfs_release
,
244 .sysfs_ops
= &xfs_sysfs_ops
,
245 .default_attrs
= xfs_dbg_attrs
,
252 static inline struct xstats
*
253 to_xstats(struct kobject
*kobject
)
255 struct xfs_kobj
*kobj
= to_kobj(kobject
);
257 return container_of(kobj
, struct xstats
, xs_kobj
);
262 struct kobject
*kobject
,
265 struct xstats
*stats
= to_xstats(kobject
);
267 return xfs_stats_format(stats
->xs_stats
, buf
);
269 XFS_SYSFS_ATTR_RO(stats
);
273 struct kobject
*kobject
,
279 struct xstats
*stats
= to_xstats(kobject
);
281 ret
= kstrtoint(buf
, 0, &val
);
288 xfs_stats_clearall(stats
->xs_stats
);
291 XFS_SYSFS_ATTR_WO(stats_clear
);
293 static struct attribute
*xfs_stats_attrs
[] = {
295 ATTR_LIST(stats_clear
),
299 struct kobj_type xfs_stats_ktype
= {
300 .release
= xfs_sysfs_release
,
301 .sysfs_ops
= &xfs_sysfs_ops
,
302 .default_attrs
= xfs_stats_attrs
,
307 static inline struct xlog
*
308 to_xlog(struct kobject
*kobject
)
310 struct xfs_kobj
*kobj
= to_kobj(kobject
);
312 return container_of(kobj
, struct xlog
, l_kobj
);
317 struct kobject
*kobject
,
322 struct xlog
*log
= to_xlog(kobject
);
324 spin_lock(&log
->l_icloglock
);
325 cycle
= log
->l_curr_cycle
;
326 block
= log
->l_curr_block
;
327 spin_unlock(&log
->l_icloglock
);
329 return snprintf(buf
, PAGE_SIZE
, "%d:%d\n", cycle
, block
);
331 XFS_SYSFS_ATTR_RO(log_head_lsn
);
335 struct kobject
*kobject
,
340 struct xlog
*log
= to_xlog(kobject
);
342 xlog_crack_atomic_lsn(&log
->l_tail_lsn
, &cycle
, &block
);
343 return snprintf(buf
, PAGE_SIZE
, "%d:%d\n", cycle
, block
);
345 XFS_SYSFS_ATTR_RO(log_tail_lsn
);
348 reserve_grant_head_show(
349 struct kobject
*kobject
,
355 struct xlog
*log
= to_xlog(kobject
);
357 xlog_crack_grant_head(&log
->l_reserve_head
.grant
, &cycle
, &bytes
);
358 return snprintf(buf
, PAGE_SIZE
, "%d:%d\n", cycle
, bytes
);
360 XFS_SYSFS_ATTR_RO(reserve_grant_head
);
363 write_grant_head_show(
364 struct kobject
*kobject
,
369 struct xlog
*log
= to_xlog(kobject
);
371 xlog_crack_grant_head(&log
->l_write_head
.grant
, &cycle
, &bytes
);
372 return snprintf(buf
, PAGE_SIZE
, "%d:%d\n", cycle
, bytes
);
374 XFS_SYSFS_ATTR_RO(write_grant_head
);
376 static struct attribute
*xfs_log_attrs
[] = {
377 ATTR_LIST(log_head_lsn
),
378 ATTR_LIST(log_tail_lsn
),
379 ATTR_LIST(reserve_grant_head
),
380 ATTR_LIST(write_grant_head
),
384 struct kobj_type xfs_log_ktype
= {
385 .release
= xfs_sysfs_release
,
386 .sysfs_ops
= &xfs_sysfs_ops
,
387 .default_attrs
= xfs_log_attrs
,
391 * Metadata IO error configuration
393 * The sysfs structure here is:
394 * ...xfs/<dev>/error/<class>/<errno>/<error_attrs>
396 * where <class> allows us to discriminate between data IO and metadata IO,
397 * and any other future type of IO (e.g. special inode or directory error
398 * handling) we care to support.
400 static inline struct xfs_error_cfg
*
401 to_error_cfg(struct kobject
*kobject
)
403 struct xfs_kobj
*kobj
= to_kobj(kobject
);
404 return container_of(kobj
, struct xfs_error_cfg
, kobj
);
407 static inline struct xfs_mount
*
408 err_to_mp(struct kobject
*kobject
)
410 struct xfs_kobj
*kobj
= to_kobj(kobject
);
411 return container_of(kobj
, struct xfs_mount
, m_error_kobj
);
416 struct kobject
*kobject
,
420 struct xfs_error_cfg
*cfg
= to_error_cfg(kobject
);
422 if (cfg
->max_retries
== XFS_ERR_RETRY_FOREVER
)
425 retries
= cfg
->max_retries
;
427 return snprintf(buf
, PAGE_SIZE
, "%d\n", retries
);
432 struct kobject
*kobject
,
436 struct xfs_error_cfg
*cfg
= to_error_cfg(kobject
);
440 ret
= kstrtoint(buf
, 0, &val
);
448 cfg
->max_retries
= XFS_ERR_RETRY_FOREVER
;
450 cfg
->max_retries
= val
;
453 XFS_SYSFS_ATTR_RW(max_retries
);
456 retry_timeout_seconds_show(
457 struct kobject
*kobject
,
461 struct xfs_error_cfg
*cfg
= to_error_cfg(kobject
);
463 if (cfg
->retry_timeout
== XFS_ERR_RETRY_FOREVER
)
466 timeout
= jiffies_to_msecs(cfg
->retry_timeout
) / MSEC_PER_SEC
;
468 return snprintf(buf
, PAGE_SIZE
, "%d\n", timeout
);
472 retry_timeout_seconds_store(
473 struct kobject
*kobject
,
477 struct xfs_error_cfg
*cfg
= to_error_cfg(kobject
);
481 ret
= kstrtoint(buf
, 0, &val
);
485 /* 1 day timeout maximum, -1 means infinite */
486 if (val
< -1 || val
> 86400)
490 cfg
->retry_timeout
= XFS_ERR_RETRY_FOREVER
;
492 cfg
->retry_timeout
= msecs_to_jiffies(val
* MSEC_PER_SEC
);
493 ASSERT(msecs_to_jiffies(val
* MSEC_PER_SEC
) < LONG_MAX
);
497 XFS_SYSFS_ATTR_RW(retry_timeout_seconds
);
500 fail_at_unmount_show(
501 struct kobject
*kobject
,
504 struct xfs_mount
*mp
= err_to_mp(kobject
);
506 return snprintf(buf
, PAGE_SIZE
, "%d\n", mp
->m_fail_unmount
);
510 fail_at_unmount_store(
511 struct kobject
*kobject
,
515 struct xfs_mount
*mp
= err_to_mp(kobject
);
519 ret
= kstrtoint(buf
, 0, &val
);
523 if (val
< 0 || val
> 1)
526 mp
->m_fail_unmount
= val
;
529 XFS_SYSFS_ATTR_RW(fail_at_unmount
);
531 static struct attribute
*xfs_error_attrs
[] = {
532 ATTR_LIST(max_retries
),
533 ATTR_LIST(retry_timeout_seconds
),
538 static struct kobj_type xfs_error_cfg_ktype
= {
539 .release
= xfs_sysfs_release
,
540 .sysfs_ops
= &xfs_sysfs_ops
,
541 .default_attrs
= xfs_error_attrs
,
544 static struct kobj_type xfs_error_ktype
= {
545 .release
= xfs_sysfs_release
,
546 .sysfs_ops
= &xfs_sysfs_ops
,
550 * Error initialization tables. These need to be ordered in the same
551 * order as the enums used to index the array. All class init tables need to
552 * define a "default" behaviour as the first entry, all other entries can be
555 struct xfs_error_init
{
558 int retry_timeout
; /* in seconds */
561 static const struct xfs_error_init xfs_error_meta_init
[XFS_ERR_ERRNO_MAX
] = {
563 .max_retries
= XFS_ERR_RETRY_FOREVER
,
564 .retry_timeout
= XFS_ERR_RETRY_FOREVER
,
567 .max_retries
= XFS_ERR_RETRY_FOREVER
,
568 .retry_timeout
= XFS_ERR_RETRY_FOREVER
,
571 .max_retries
= XFS_ERR_RETRY_FOREVER
,
572 .retry_timeout
= XFS_ERR_RETRY_FOREVER
,
575 .max_retries
= 0, /* We can't recover from devices disappearing */
581 xfs_error_sysfs_init_class(
582 struct xfs_mount
*mp
,
584 const char *parent_name
,
585 struct xfs_kobj
*parent_kobj
,
586 const struct xfs_error_init init
[])
588 struct xfs_error_cfg
*cfg
;
592 ASSERT(class < XFS_ERR_CLASS_MAX
);
594 error
= xfs_sysfs_init(parent_kobj
, &xfs_error_ktype
,
595 &mp
->m_error_kobj
, parent_name
);
599 for (i
= 0; i
< XFS_ERR_ERRNO_MAX
; i
++) {
600 cfg
= &mp
->m_error_cfg
[class][i
];
601 error
= xfs_sysfs_init(&cfg
->kobj
, &xfs_error_cfg_ktype
,
602 parent_kobj
, init
[i
].name
);
606 cfg
->max_retries
= init
[i
].max_retries
;
607 if (init
[i
].retry_timeout
== XFS_ERR_RETRY_FOREVER
)
608 cfg
->retry_timeout
= XFS_ERR_RETRY_FOREVER
;
610 cfg
->retry_timeout
= msecs_to_jiffies(
611 init
[i
].retry_timeout
* MSEC_PER_SEC
);
616 /* unwind the entries that succeeded */
617 for (i
--; i
>= 0; i
--) {
618 cfg
= &mp
->m_error_cfg
[class][i
];
619 xfs_sysfs_del(&cfg
->kobj
);
621 xfs_sysfs_del(parent_kobj
);
626 xfs_error_sysfs_init(
627 struct xfs_mount
*mp
)
631 /* .../xfs/<dev>/error/ */
632 error
= xfs_sysfs_init(&mp
->m_error_kobj
, &xfs_error_ktype
,
633 &mp
->m_kobj
, "error");
637 error
= sysfs_create_file(&mp
->m_error_kobj
.kobject
,
638 ATTR_LIST(fail_at_unmount
));
643 /* .../xfs/<dev>/error/metadata/ */
644 error
= xfs_error_sysfs_init_class(mp
, XFS_ERR_METADATA
,
645 "metadata", &mp
->m_error_meta_kobj
,
646 xfs_error_meta_init
);
653 xfs_sysfs_del(&mp
->m_error_kobj
);
659 struct xfs_mount
*mp
)
661 struct xfs_error_cfg
*cfg
;
664 for (i
= 0; i
< XFS_ERR_CLASS_MAX
; i
++) {
665 for (j
= 0; j
< XFS_ERR_ERRNO_MAX
; j
++) {
666 cfg
= &mp
->m_error_cfg
[i
][j
];
668 xfs_sysfs_del(&cfg
->kobj
);
671 xfs_sysfs_del(&mp
->m_error_meta_kobj
);
672 xfs_sysfs_del(&mp
->m_error_kobj
);
675 struct xfs_error_cfg
*
677 struct xfs_mount
*mp
,
681 struct xfs_error_cfg
*cfg
;
688 cfg
= &mp
->m_error_cfg
[error_class
][XFS_ERR_EIO
];
691 cfg
= &mp
->m_error_cfg
[error_class
][XFS_ERR_ENOSPC
];
694 cfg
= &mp
->m_error_cfg
[error_class
][XFS_ERR_ENODEV
];
697 cfg
= &mp
->m_error_cfg
[error_class
][XFS_ERR_DEFAULT
];