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"
14 #include "xfs_log_priv.h"
15 #include "xfs_stats.h"
16 #include "xfs_mount.h"
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
,
25 static inline struct xfs_sysfs_attr
*
26 to_attr(struct attribute
*attr
)
28 return container_of(attr
, struct xfs_sysfs_attr
, attr
);
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)
38 #define ATTR_LIST(name) &xfs_sysfs_attr_##name.attr
41 xfs_sysfs_object_show(
42 struct kobject
*kobject
,
43 struct attribute
*attr
,
46 struct xfs_sysfs_attr
*xfs_attr
= to_attr(attr
);
48 return xfs_attr
->show
? xfs_attr
->show(kobject
, buf
) : 0;
52 xfs_sysfs_object_store(
53 struct kobject
*kobject
,
54 struct attribute
*attr
,
58 struct xfs_sysfs_attr
*xfs_attr
= to_attr(attr
);
60 return xfs_attr
->store
? xfs_attr
->store(kobject
, buf
, count
) : 0;
63 static const struct sysfs_ops xfs_sysfs_ops
= {
64 .show
= xfs_sysfs_object_show
,
65 .store
= xfs_sysfs_object_store
,
69 * xfs_mount kobject. The mp kobject also serves as the per-mount parent object
70 * that is identified by the fsname under sysfs.
73 static inline struct xfs_mount
*
74 to_mp(struct kobject
*kobject
)
76 struct xfs_kobj
*kobj
= to_kobj(kobject
);
78 return container_of(kobj
, struct xfs_mount
, m_kobj
);
81 static struct attribute
*xfs_mp_attrs
[] = {
85 struct kobj_type xfs_mp_ktype
= {
86 .release
= xfs_sysfs_release
,
87 .sysfs_ops
= &xfs_sysfs_ops
,
88 .default_attrs
= xfs_mp_attrs
,
96 struct kobject
*kobject
,
103 ret
= kstrtoint(buf
, 0, &val
);
108 xfs_globals
.bug_on_assert
= true;
110 xfs_globals
.bug_on_assert
= false;
119 struct kobject
*kobject
,
122 return snprintf(buf
, PAGE_SIZE
, "%d\n", xfs_globals
.bug_on_assert
? 1 : 0);
124 XFS_SYSFS_ATTR_RW(bug_on_assert
);
127 log_recovery_delay_store(
128 struct kobject
*kobject
,
135 ret
= kstrtoint(buf
, 0, &val
);
139 if (val
< 0 || val
> 60)
142 xfs_globals
.log_recovery_delay
= val
;
148 log_recovery_delay_show(
149 struct kobject
*kobject
,
152 return snprintf(buf
, PAGE_SIZE
, "%d\n", xfs_globals
.log_recovery_delay
);
154 XFS_SYSFS_ATTR_RW(log_recovery_delay
);
158 struct kobject
*kobject
,
165 ret
= kstrtoint(buf
, 0, &val
);
169 if (val
< 0 || val
> 60)
172 xfs_globals
.mount_delay
= val
;
179 struct kobject
*kobject
,
182 return snprintf(buf
, PAGE_SIZE
, "%d\n", xfs_globals
.mount_delay
);
184 XFS_SYSFS_ATTR_RW(mount_delay
);
186 static struct attribute
*xfs_dbg_attrs
[] = {
187 ATTR_LIST(bug_on_assert
),
188 ATTR_LIST(log_recovery_delay
),
189 ATTR_LIST(mount_delay
),
193 struct kobj_type xfs_dbg_ktype
= {
194 .release
= xfs_sysfs_release
,
195 .sysfs_ops
= &xfs_sysfs_ops
,
196 .default_attrs
= xfs_dbg_attrs
,
203 static inline struct xstats
*
204 to_xstats(struct kobject
*kobject
)
206 struct xfs_kobj
*kobj
= to_kobj(kobject
);
208 return container_of(kobj
, struct xstats
, xs_kobj
);
213 struct kobject
*kobject
,
216 struct xstats
*stats
= to_xstats(kobject
);
218 return xfs_stats_format(stats
->xs_stats
, buf
);
220 XFS_SYSFS_ATTR_RO(stats
);
224 struct kobject
*kobject
,
230 struct xstats
*stats
= to_xstats(kobject
);
232 ret
= kstrtoint(buf
, 0, &val
);
239 xfs_stats_clearall(stats
->xs_stats
);
242 XFS_SYSFS_ATTR_WO(stats_clear
);
244 static struct attribute
*xfs_stats_attrs
[] = {
246 ATTR_LIST(stats_clear
),
250 struct kobj_type xfs_stats_ktype
= {
251 .release
= xfs_sysfs_release
,
252 .sysfs_ops
= &xfs_sysfs_ops
,
253 .default_attrs
= xfs_stats_attrs
,
258 static inline struct xlog
*
259 to_xlog(struct kobject
*kobject
)
261 struct xfs_kobj
*kobj
= to_kobj(kobject
);
263 return container_of(kobj
, struct xlog
, l_kobj
);
268 struct kobject
*kobject
,
273 struct xlog
*log
= to_xlog(kobject
);
275 spin_lock(&log
->l_icloglock
);
276 cycle
= log
->l_curr_cycle
;
277 block
= log
->l_curr_block
;
278 spin_unlock(&log
->l_icloglock
);
280 return snprintf(buf
, PAGE_SIZE
, "%d:%d\n", cycle
, block
);
282 XFS_SYSFS_ATTR_RO(log_head_lsn
);
286 struct kobject
*kobject
,
291 struct xlog
*log
= to_xlog(kobject
);
293 xlog_crack_atomic_lsn(&log
->l_tail_lsn
, &cycle
, &block
);
294 return snprintf(buf
, PAGE_SIZE
, "%d:%d\n", cycle
, block
);
296 XFS_SYSFS_ATTR_RO(log_tail_lsn
);
299 reserve_grant_head_show(
300 struct kobject
*kobject
,
306 struct xlog
*log
= to_xlog(kobject
);
308 xlog_crack_grant_head(&log
->l_reserve_head
.grant
, &cycle
, &bytes
);
309 return snprintf(buf
, PAGE_SIZE
, "%d:%d\n", cycle
, bytes
);
311 XFS_SYSFS_ATTR_RO(reserve_grant_head
);
314 write_grant_head_show(
315 struct kobject
*kobject
,
320 struct xlog
*log
= to_xlog(kobject
);
322 xlog_crack_grant_head(&log
->l_write_head
.grant
, &cycle
, &bytes
);
323 return snprintf(buf
, PAGE_SIZE
, "%d:%d\n", cycle
, bytes
);
325 XFS_SYSFS_ATTR_RO(write_grant_head
);
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
),
335 struct kobj_type xfs_log_ktype
= {
336 .release
= xfs_sysfs_release
,
337 .sysfs_ops
= &xfs_sysfs_ops
,
338 .default_attrs
= xfs_log_attrs
,
342 * Metadata IO error configuration
344 * The sysfs structure here is:
345 * ...xfs/<dev>/error/<class>/<errno>/<error_attrs>
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.
351 static inline struct xfs_error_cfg
*
352 to_error_cfg(struct kobject
*kobject
)
354 struct xfs_kobj
*kobj
= to_kobj(kobject
);
355 return container_of(kobj
, struct xfs_error_cfg
, kobj
);
358 static inline struct xfs_mount
*
359 err_to_mp(struct kobject
*kobject
)
361 struct xfs_kobj
*kobj
= to_kobj(kobject
);
362 return container_of(kobj
, struct xfs_mount
, m_error_kobj
);
367 struct kobject
*kobject
,
371 struct xfs_error_cfg
*cfg
= to_error_cfg(kobject
);
373 if (cfg
->max_retries
== XFS_ERR_RETRY_FOREVER
)
376 retries
= cfg
->max_retries
;
378 return snprintf(buf
, PAGE_SIZE
, "%d\n", retries
);
383 struct kobject
*kobject
,
387 struct xfs_error_cfg
*cfg
= to_error_cfg(kobject
);
391 ret
= kstrtoint(buf
, 0, &val
);
399 cfg
->max_retries
= XFS_ERR_RETRY_FOREVER
;
401 cfg
->max_retries
= val
;
404 XFS_SYSFS_ATTR_RW(max_retries
);
407 retry_timeout_seconds_show(
408 struct kobject
*kobject
,
412 struct xfs_error_cfg
*cfg
= to_error_cfg(kobject
);
414 if (cfg
->retry_timeout
== XFS_ERR_RETRY_FOREVER
)
417 timeout
= jiffies_to_msecs(cfg
->retry_timeout
) / MSEC_PER_SEC
;
419 return snprintf(buf
, PAGE_SIZE
, "%d\n", timeout
);
423 retry_timeout_seconds_store(
424 struct kobject
*kobject
,
428 struct xfs_error_cfg
*cfg
= to_error_cfg(kobject
);
432 ret
= kstrtoint(buf
, 0, &val
);
436 /* 1 day timeout maximum, -1 means infinite */
437 if (val
< -1 || val
> 86400)
441 cfg
->retry_timeout
= XFS_ERR_RETRY_FOREVER
;
443 cfg
->retry_timeout
= msecs_to_jiffies(val
* MSEC_PER_SEC
);
444 ASSERT(msecs_to_jiffies(val
* MSEC_PER_SEC
) < LONG_MAX
);
448 XFS_SYSFS_ATTR_RW(retry_timeout_seconds
);
451 fail_at_unmount_show(
452 struct kobject
*kobject
,
455 struct xfs_mount
*mp
= err_to_mp(kobject
);
457 return snprintf(buf
, PAGE_SIZE
, "%d\n", mp
->m_fail_unmount
);
461 fail_at_unmount_store(
462 struct kobject
*kobject
,
466 struct xfs_mount
*mp
= err_to_mp(kobject
);
470 ret
= kstrtoint(buf
, 0, &val
);
474 if (val
< 0 || val
> 1)
477 mp
->m_fail_unmount
= val
;
480 XFS_SYSFS_ATTR_RW(fail_at_unmount
);
482 static struct attribute
*xfs_error_attrs
[] = {
483 ATTR_LIST(max_retries
),
484 ATTR_LIST(retry_timeout_seconds
),
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
,
495 static struct kobj_type xfs_error_ktype
= {
496 .release
= xfs_sysfs_release
,
497 .sysfs_ops
= &xfs_sysfs_ops
,
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
506 struct xfs_error_init
{
509 int retry_timeout
; /* in seconds */
512 static const struct xfs_error_init xfs_error_meta_init
[XFS_ERR_ERRNO_MAX
] = {
514 .max_retries
= XFS_ERR_RETRY_FOREVER
,
515 .retry_timeout
= XFS_ERR_RETRY_FOREVER
,
518 .max_retries
= XFS_ERR_RETRY_FOREVER
,
519 .retry_timeout
= XFS_ERR_RETRY_FOREVER
,
522 .max_retries
= XFS_ERR_RETRY_FOREVER
,
523 .retry_timeout
= XFS_ERR_RETRY_FOREVER
,
526 .max_retries
= 0, /* We can't recover from devices disappearing */
532 xfs_error_sysfs_init_class(
533 struct xfs_mount
*mp
,
535 const char *parent_name
,
536 struct xfs_kobj
*parent_kobj
,
537 const struct xfs_error_init init
[])
539 struct xfs_error_cfg
*cfg
;
543 ASSERT(class < XFS_ERR_CLASS_MAX
);
545 error
= xfs_sysfs_init(parent_kobj
, &xfs_error_ktype
,
546 &mp
->m_error_kobj
, parent_name
);
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
);
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
;
561 cfg
->retry_timeout
= msecs_to_jiffies(
562 init
[i
].retry_timeout
* MSEC_PER_SEC
);
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
);
572 xfs_sysfs_del(parent_kobj
);
577 xfs_error_sysfs_init(
578 struct xfs_mount
*mp
)
582 /* .../xfs/<dev>/error/ */
583 error
= xfs_sysfs_init(&mp
->m_error_kobj
, &xfs_error_ktype
,
584 &mp
->m_kobj
, "error");
588 error
= sysfs_create_file(&mp
->m_error_kobj
.kobject
,
589 ATTR_LIST(fail_at_unmount
));
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
);
604 xfs_sysfs_del(&mp
->m_error_kobj
);
610 struct xfs_mount
*mp
)
612 struct xfs_error_cfg
*cfg
;
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
];
619 xfs_sysfs_del(&cfg
->kobj
);
622 xfs_sysfs_del(&mp
->m_error_meta_kobj
);
623 xfs_sysfs_del(&mp
->m_error_kobj
);
626 struct xfs_error_cfg
*
628 struct xfs_mount
*mp
,
632 struct xfs_error_cfg
*cfg
;
639 cfg
= &mp
->m_error_cfg
[error_class
][XFS_ERR_EIO
];
642 cfg
= &mp
->m_error_cfg
[error_class
][XFS_ERR_ENOSPC
];
645 cfg
= &mp
->m_error_cfg
[error_class
][XFS_ERR_ENODEV
];
648 cfg
= &mp
->m_error_cfg
[error_class
][XFS_ERR_DEFAULT
];