2 * Copyright (c) 2014 Red Hat, Inc.
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.
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.
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
20 #include "xfs_shared.h"
21 #include "xfs_format.h"
22 #include "xfs_log_format.h"
23 #include "xfs_trans_resv.h"
24 #include "xfs_sysfs.h"
26 #include "xfs_log_priv.h"
27 #include "xfs_stats.h"
28 #include "xfs_mount.h"
30 struct xfs_sysfs_attr
{
31 struct attribute attr
;
32 ssize_t (*show
)(struct kobject
*kobject
, char *buf
);
33 ssize_t (*store
)(struct kobject
*kobject
, const char *buf
,
37 static inline struct xfs_sysfs_attr
*
38 to_attr(struct attribute
*attr
)
40 return container_of(attr
, struct xfs_sysfs_attr
, attr
);
43 #define XFS_SYSFS_ATTR_RW(name) \
44 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RW(name)
45 #define XFS_SYSFS_ATTR_RO(name) \
46 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RO(name)
47 #define XFS_SYSFS_ATTR_WO(name) \
48 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_WO(name)
50 #define ATTR_LIST(name) &xfs_sysfs_attr_##name.attr
53 xfs_sysfs_object_show(
54 struct kobject
*kobject
,
55 struct attribute
*attr
,
58 struct xfs_sysfs_attr
*xfs_attr
= to_attr(attr
);
60 return xfs_attr
->show
? xfs_attr
->show(kobject
, buf
) : 0;
64 xfs_sysfs_object_store(
65 struct kobject
*kobject
,
66 struct attribute
*attr
,
70 struct xfs_sysfs_attr
*xfs_attr
= to_attr(attr
);
72 return xfs_attr
->store
? xfs_attr
->store(kobject
, buf
, count
) : 0;
75 static const struct sysfs_ops xfs_sysfs_ops
= {
76 .show
= xfs_sysfs_object_show
,
77 .store
= xfs_sysfs_object_store
,
81 * xfs_mount kobject. The mp kobject also serves as the per-mount parent object
82 * that is identified by the fsname under sysfs.
85 static inline struct xfs_mount
*
86 to_mp(struct kobject
*kobject
)
88 struct xfs_kobj
*kobj
= to_kobj(kobject
);
90 return container_of(kobj
, struct xfs_mount
, m_kobj
);
97 struct kobject
*kobject
,
101 struct xfs_mount
*mp
= to_mp(kobject
);
105 ret
= kstrtoint(buf
, 0, &val
);
110 mp
->m_fail_writes
= true;
112 mp
->m_fail_writes
= false;
121 struct kobject
*kobject
,
124 struct xfs_mount
*mp
= to_mp(kobject
);
126 return snprintf(buf
, PAGE_SIZE
, "%d\n", mp
->m_fail_writes
? 1 : 0);
128 XFS_SYSFS_ATTR_RW(fail_writes
);
132 static struct attribute
*xfs_mp_attrs
[] = {
134 ATTR_LIST(fail_writes
),
139 struct kobj_type xfs_mp_ktype
= {
140 .release
= xfs_sysfs_release
,
141 .sysfs_ops
= &xfs_sysfs_ops
,
142 .default_attrs
= xfs_mp_attrs
,
149 log_recovery_delay_store(
150 struct kobject
*kobject
,
157 ret
= kstrtoint(buf
, 0, &val
);
161 if (val
< 0 || val
> 60)
164 xfs_globals
.log_recovery_delay
= val
;
170 log_recovery_delay_show(
171 struct kobject
*kobject
,
174 return snprintf(buf
, PAGE_SIZE
, "%d\n", xfs_globals
.log_recovery_delay
);
176 XFS_SYSFS_ATTR_RW(log_recovery_delay
);
178 static struct attribute
*xfs_dbg_attrs
[] = {
179 ATTR_LIST(log_recovery_delay
),
183 struct kobj_type xfs_dbg_ktype
= {
184 .release
= xfs_sysfs_release
,
185 .sysfs_ops
= &xfs_sysfs_ops
,
186 .default_attrs
= xfs_dbg_attrs
,
193 static inline struct xstats
*
194 to_xstats(struct kobject
*kobject
)
196 struct xfs_kobj
*kobj
= to_kobj(kobject
);
198 return container_of(kobj
, struct xstats
, xs_kobj
);
203 struct kobject
*kobject
,
206 struct xstats
*stats
= to_xstats(kobject
);
208 return xfs_stats_format(stats
->xs_stats
, buf
);
210 XFS_SYSFS_ATTR_RO(stats
);
214 struct kobject
*kobject
,
220 struct xstats
*stats
= to_xstats(kobject
);
222 ret
= kstrtoint(buf
, 0, &val
);
229 xfs_stats_clearall(stats
->xs_stats
);
232 XFS_SYSFS_ATTR_WO(stats_clear
);
234 static struct attribute
*xfs_stats_attrs
[] = {
236 ATTR_LIST(stats_clear
),
240 struct kobj_type xfs_stats_ktype
= {
241 .release
= xfs_sysfs_release
,
242 .sysfs_ops
= &xfs_sysfs_ops
,
243 .default_attrs
= xfs_stats_attrs
,
248 static inline struct xlog
*
249 to_xlog(struct kobject
*kobject
)
251 struct xfs_kobj
*kobj
= to_kobj(kobject
);
253 return container_of(kobj
, struct xlog
, l_kobj
);
258 struct kobject
*kobject
,
263 struct xlog
*log
= to_xlog(kobject
);
265 spin_lock(&log
->l_icloglock
);
266 cycle
= log
->l_curr_cycle
;
267 block
= log
->l_curr_block
;
268 spin_unlock(&log
->l_icloglock
);
270 return snprintf(buf
, PAGE_SIZE
, "%d:%d\n", cycle
, block
);
272 XFS_SYSFS_ATTR_RO(log_head_lsn
);
276 struct kobject
*kobject
,
281 struct xlog
*log
= to_xlog(kobject
);
283 xlog_crack_atomic_lsn(&log
->l_tail_lsn
, &cycle
, &block
);
284 return snprintf(buf
, PAGE_SIZE
, "%d:%d\n", cycle
, block
);
286 XFS_SYSFS_ATTR_RO(log_tail_lsn
);
289 reserve_grant_head_show(
290 struct kobject
*kobject
,
296 struct xlog
*log
= to_xlog(kobject
);
298 xlog_crack_grant_head(&log
->l_reserve_head
.grant
, &cycle
, &bytes
);
299 return snprintf(buf
, PAGE_SIZE
, "%d:%d\n", cycle
, bytes
);
301 XFS_SYSFS_ATTR_RO(reserve_grant_head
);
304 write_grant_head_show(
305 struct kobject
*kobject
,
310 struct xlog
*log
= to_xlog(kobject
);
312 xlog_crack_grant_head(&log
->l_write_head
.grant
, &cycle
, &bytes
);
313 return snprintf(buf
, PAGE_SIZE
, "%d:%d\n", cycle
, bytes
);
315 XFS_SYSFS_ATTR_RO(write_grant_head
);
319 log_badcrc_factor_store(
320 struct kobject
*kobject
,
324 struct xlog
*log
= to_xlog(kobject
);
328 ret
= kstrtouint(buf
, 0, &val
);
332 log
->l_badcrc_factor
= val
;
338 log_badcrc_factor_show(
339 struct kobject
*kobject
,
342 struct xlog
*log
= to_xlog(kobject
);
344 return snprintf(buf
, PAGE_SIZE
, "%d\n", log
->l_badcrc_factor
);
347 XFS_SYSFS_ATTR_RW(log_badcrc_factor
);
350 static struct attribute
*xfs_log_attrs
[] = {
351 ATTR_LIST(log_head_lsn
),
352 ATTR_LIST(log_tail_lsn
),
353 ATTR_LIST(reserve_grant_head
),
354 ATTR_LIST(write_grant_head
),
356 ATTR_LIST(log_badcrc_factor
),
361 struct kobj_type xfs_log_ktype
= {
362 .release
= xfs_sysfs_release
,
363 .sysfs_ops
= &xfs_sysfs_ops
,
364 .default_attrs
= xfs_log_attrs
,
368 * Metadata IO error configuration
370 * The sysfs structure here is:
371 * ...xfs/<dev>/error/<class>/<errno>/<error_attrs>
373 * where <class> allows us to discriminate between data IO and metadata IO,
374 * and any other future type of IO (e.g. special inode or directory error
375 * handling) we care to support.
377 static inline struct xfs_error_cfg
*
378 to_error_cfg(struct kobject
*kobject
)
380 struct xfs_kobj
*kobj
= to_kobj(kobject
);
381 return container_of(kobj
, struct xfs_error_cfg
, kobj
);
384 static inline struct xfs_mount
*
385 err_to_mp(struct kobject
*kobject
)
387 struct xfs_kobj
*kobj
= to_kobj(kobject
);
388 return container_of(kobj
, struct xfs_mount
, m_error_kobj
);
393 struct kobject
*kobject
,
397 struct xfs_error_cfg
*cfg
= to_error_cfg(kobject
);
399 if (cfg
->max_retries
== XFS_ERR_RETRY_FOREVER
)
402 retries
= cfg
->max_retries
;
404 return snprintf(buf
, PAGE_SIZE
, "%d\n", retries
);
409 struct kobject
*kobject
,
413 struct xfs_error_cfg
*cfg
= to_error_cfg(kobject
);
417 ret
= kstrtoint(buf
, 0, &val
);
425 cfg
->max_retries
= XFS_ERR_RETRY_FOREVER
;
427 cfg
->max_retries
= val
;
430 XFS_SYSFS_ATTR_RW(max_retries
);
433 retry_timeout_seconds_show(
434 struct kobject
*kobject
,
438 struct xfs_error_cfg
*cfg
= to_error_cfg(kobject
);
440 if (cfg
->retry_timeout
== XFS_ERR_RETRY_FOREVER
)
443 timeout
= jiffies_to_msecs(cfg
->retry_timeout
) / MSEC_PER_SEC
;
445 return snprintf(buf
, PAGE_SIZE
, "%d\n", timeout
);
449 retry_timeout_seconds_store(
450 struct kobject
*kobject
,
454 struct xfs_error_cfg
*cfg
= to_error_cfg(kobject
);
458 ret
= kstrtoint(buf
, 0, &val
);
462 /* 1 day timeout maximum, -1 means infinite */
463 if (val
< -1 || val
> 86400)
467 cfg
->retry_timeout
= XFS_ERR_RETRY_FOREVER
;
469 cfg
->retry_timeout
= msecs_to_jiffies(val
* MSEC_PER_SEC
);
470 ASSERT(msecs_to_jiffies(val
* MSEC_PER_SEC
) < LONG_MAX
);
474 XFS_SYSFS_ATTR_RW(retry_timeout_seconds
);
477 fail_at_unmount_show(
478 struct kobject
*kobject
,
481 struct xfs_mount
*mp
= err_to_mp(kobject
);
483 return snprintf(buf
, PAGE_SIZE
, "%d\n", mp
->m_fail_unmount
);
487 fail_at_unmount_store(
488 struct kobject
*kobject
,
492 struct xfs_mount
*mp
= err_to_mp(kobject
);
496 ret
= kstrtoint(buf
, 0, &val
);
500 if (val
< 0 || val
> 1)
503 mp
->m_fail_unmount
= val
;
506 XFS_SYSFS_ATTR_RW(fail_at_unmount
);
508 static struct attribute
*xfs_error_attrs
[] = {
509 ATTR_LIST(max_retries
),
510 ATTR_LIST(retry_timeout_seconds
),
515 static struct kobj_type xfs_error_cfg_ktype
= {
516 .release
= xfs_sysfs_release
,
517 .sysfs_ops
= &xfs_sysfs_ops
,
518 .default_attrs
= xfs_error_attrs
,
521 static struct kobj_type xfs_error_ktype
= {
522 .release
= xfs_sysfs_release
,
523 .sysfs_ops
= &xfs_sysfs_ops
,
527 * Error initialization tables. These need to be ordered in the same
528 * order as the enums used to index the array. All class init tables need to
529 * define a "default" behaviour as the first entry, all other entries can be
532 struct xfs_error_init
{
535 int retry_timeout
; /* in seconds */
538 static const struct xfs_error_init xfs_error_meta_init
[XFS_ERR_ERRNO_MAX
] = {
540 .max_retries
= XFS_ERR_RETRY_FOREVER
,
541 .retry_timeout
= XFS_ERR_RETRY_FOREVER
,
544 .max_retries
= XFS_ERR_RETRY_FOREVER
,
545 .retry_timeout
= XFS_ERR_RETRY_FOREVER
,
548 .max_retries
= XFS_ERR_RETRY_FOREVER
,
549 .retry_timeout
= XFS_ERR_RETRY_FOREVER
,
552 .max_retries
= 0, /* We can't recover from devices disappearing */
558 xfs_error_sysfs_init_class(
559 struct xfs_mount
*mp
,
561 const char *parent_name
,
562 struct xfs_kobj
*parent_kobj
,
563 const struct xfs_error_init init
[])
565 struct xfs_error_cfg
*cfg
;
569 ASSERT(class < XFS_ERR_CLASS_MAX
);
571 error
= xfs_sysfs_init(parent_kobj
, &xfs_error_ktype
,
572 &mp
->m_error_kobj
, parent_name
);
576 for (i
= 0; i
< XFS_ERR_ERRNO_MAX
; i
++) {
577 cfg
= &mp
->m_error_cfg
[class][i
];
578 error
= xfs_sysfs_init(&cfg
->kobj
, &xfs_error_cfg_ktype
,
579 parent_kobj
, init
[i
].name
);
583 cfg
->max_retries
= init
[i
].max_retries
;
584 if (init
[i
].retry_timeout
== XFS_ERR_RETRY_FOREVER
)
585 cfg
->retry_timeout
= XFS_ERR_RETRY_FOREVER
;
587 cfg
->retry_timeout
= msecs_to_jiffies(
588 init
[i
].retry_timeout
* MSEC_PER_SEC
);
593 /* unwind the entries that succeeded */
594 for (i
--; i
>= 0; i
--) {
595 cfg
= &mp
->m_error_cfg
[class][i
];
596 xfs_sysfs_del(&cfg
->kobj
);
598 xfs_sysfs_del(parent_kobj
);
603 xfs_error_sysfs_init(
604 struct xfs_mount
*mp
)
608 /* .../xfs/<dev>/error/ */
609 error
= xfs_sysfs_init(&mp
->m_error_kobj
, &xfs_error_ktype
,
610 &mp
->m_kobj
, "error");
614 error
= sysfs_create_file(&mp
->m_error_kobj
.kobject
,
615 ATTR_LIST(fail_at_unmount
));
620 /* .../xfs/<dev>/error/metadata/ */
621 error
= xfs_error_sysfs_init_class(mp
, XFS_ERR_METADATA
,
622 "metadata", &mp
->m_error_meta_kobj
,
623 xfs_error_meta_init
);
630 xfs_sysfs_del(&mp
->m_error_kobj
);
636 struct xfs_mount
*mp
)
638 struct xfs_error_cfg
*cfg
;
641 for (i
= 0; i
< XFS_ERR_CLASS_MAX
; i
++) {
642 for (j
= 0; j
< XFS_ERR_ERRNO_MAX
; j
++) {
643 cfg
= &mp
->m_error_cfg
[i
][j
];
645 xfs_sysfs_del(&cfg
->kobj
);
648 xfs_sysfs_del(&mp
->m_error_meta_kobj
);
649 xfs_sysfs_del(&mp
->m_error_kobj
);
652 struct xfs_error_cfg
*
654 struct xfs_mount
*mp
,
658 struct xfs_error_cfg
*cfg
;
665 cfg
= &mp
->m_error_cfg
[error_class
][XFS_ERR_EIO
];
668 cfg
= &mp
->m_error_cfg
[error_class
][XFS_ERR_ENOSPC
];
671 cfg
= &mp
->m_error_cfg
[error_class
][XFS_ERR_ENODEV
];
674 cfg
= &mp
->m_error_cfg
[error_class
][XFS_ERR_DEFAULT
];