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 struct attribute
*xfs_error_attrs
[] = {
381 static inline struct xfs_error_cfg
*
382 to_error_cfg(struct kobject
*kobject
)
384 struct xfs_kobj
*kobj
= to_kobj(kobject
);
385 return container_of(kobj
, struct xfs_error_cfg
, kobj
);
388 struct kobj_type xfs_error_cfg_ktype
= {
389 .release
= xfs_sysfs_release
,
390 .sysfs_ops
= &xfs_sysfs_ops
,
391 .default_attrs
= xfs_error_attrs
,
394 struct kobj_type xfs_error_ktype
= {
395 .release
= xfs_sysfs_release
,
399 xfs_error_sysfs_init(
400 struct xfs_mount
*mp
)
402 struct xfs_error_cfg
*cfg
;
405 /* .../xfs/<dev>/error/ */
406 error
= xfs_sysfs_init(&mp
->m_error_kobj
, &xfs_error_ktype
,
407 &mp
->m_kobj
, "error");
411 /* .../xfs/<dev>/error/metadata/ */
412 error
= xfs_sysfs_init(&mp
->m_error_meta_kobj
, &xfs_error_ktype
,
413 &mp
->m_error_kobj
, "metadata");
417 cfg
= &mp
->m_error_cfg
[XFS_ERR_METADATA
][XFS_ERR_DEFAULT
];
418 error
= xfs_sysfs_init(&cfg
->kobj
, &xfs_error_cfg_ktype
,
419 &mp
->m_error_meta_kobj
, "default");
422 cfg
->max_retries
= -1;
427 xfs_sysfs_del(&mp
->m_error_meta_kobj
);
429 xfs_sysfs_del(&mp
->m_error_kobj
);
435 struct xfs_mount
*mp
)
437 struct xfs_error_cfg
*cfg
;
440 for (i
= 0; i
< XFS_ERR_CLASS_MAX
; i
++) {
441 for (j
= 0; j
< XFS_ERR_ERRNO_MAX
; j
++) {
442 cfg
= &mp
->m_error_cfg
[i
][j
];
444 xfs_sysfs_del(&cfg
->kobj
);
447 xfs_sysfs_del(&mp
->m_error_meta_kobj
);
448 xfs_sysfs_del(&mp
->m_error_kobj
);