aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorCarlos Maiolino <cmaiolino@redhat.com>2016-05-17 20:58:51 -0400
committerDave Chinner <david@fromorbit.com>2016-05-17 20:58:51 -0400
commit192852be8b5fb14268c2133fe9ce5312e4745963 (patch)
treeb859e946965a129ee024aba4136fa5c79bc56cfe /fs/xfs
parent9bdd9bd69b826875531bb1b2efb6aeb8d70e6f72 (diff)
xfs: configurable error behavior via sysfs
We need to be able to change the way XFS behaviours in error conditions depending on the type of underlying storage. This is necessary for handling non-traditional block devices with extended error cases, such as thin provisioned devices that can return ENOSPC as an IO error. Introduce the basic sysfs infrastructure needed to define and configure error behaviours. This is done to be generic enough to extend to configuring behaviour in other error conditions, such as ENOMEM, which also has different desired behaviours according to machine configuration. Signed-off-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_mount.c10
-rw-r--r--fs/xfs/xfs_mount.h20
-rw-r--r--fs/xfs/xfs_sysfs.c53
-rw-r--r--fs/xfs/xfs_sysfs.h3
4 files changed, 84 insertions, 2 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 536a0ee9cd5a..677c3e0da472 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -690,10 +690,15 @@ xfs_mountfs(
690 if (error) 690 if (error)
691 goto out_remove_sysfs; 691 goto out_remove_sysfs;
692 692
693 error = xfs_uuid_mount(mp); 693 error = xfs_error_sysfs_init(mp);
694 if (error) 694 if (error)
695 goto out_del_stats; 695 goto out_del_stats;
696 696
697
698 error = xfs_uuid_mount(mp);
699 if (error)
700 goto out_remove_error_sysfs;
701
697 /* 702 /*
698 * Set the minimum read and write sizes 703 * Set the minimum read and write sizes
699 */ 704 */
@@ -968,6 +973,8 @@ xfs_mountfs(
968 xfs_da_unmount(mp); 973 xfs_da_unmount(mp);
969 out_remove_uuid: 974 out_remove_uuid:
970 xfs_uuid_unmount(mp); 975 xfs_uuid_unmount(mp);
976 out_remove_error_sysfs:
977 xfs_error_sysfs_del(mp);
971 out_del_stats: 978 out_del_stats:
972 xfs_sysfs_del(&mp->m_stats.xs_kobj); 979 xfs_sysfs_del(&mp->m_stats.xs_kobj);
973 out_remove_sysfs: 980 out_remove_sysfs:
@@ -1056,6 +1063,7 @@ xfs_unmountfs(
1056#endif 1063#endif
1057 xfs_free_perag(mp); 1064 xfs_free_perag(mp);
1058 1065
1066 xfs_error_sysfs_del(mp);
1059 xfs_sysfs_del(&mp->m_stats.xs_kobj); 1067 xfs_sysfs_del(&mp->m_stats.xs_kobj);
1060 xfs_sysfs_del(&mp->m_kobj); 1068 xfs_sysfs_del(&mp->m_kobj);
1061} 1069}
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index bac6b3435591..d639795b0310 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -37,6 +37,24 @@ enum {
37 XFS_LOWSP_MAX, 37 XFS_LOWSP_MAX,
38}; 38};
39 39
40/*
41 * Error Configuration
42 *
43 * Error classes define the subsystem the configuration belongs to.
44 * Error numbers define the errors that are configurable.
45 */
46enum {
47 XFS_ERR_CLASS_MAX,
48};
49enum {
50 XFS_ERR_ERRNO_MAX,
51};
52
53struct xfs_error_cfg {
54 struct xfs_kobj kobj;
55 int max_retries;
56};
57
40typedef struct xfs_mount { 58typedef struct xfs_mount {
41 struct super_block *m_super; 59 struct super_block *m_super;
42 xfs_tid_t m_tid; /* next unused tid for fs */ 60 xfs_tid_t m_tid; /* next unused tid for fs */
@@ -127,6 +145,8 @@ typedef struct xfs_mount {
127 int64_t m_low_space[XFS_LOWSP_MAX]; 145 int64_t m_low_space[XFS_LOWSP_MAX];
128 /* low free space thresholds */ 146 /* low free space thresholds */
129 struct xfs_kobj m_kobj; 147 struct xfs_kobj m_kobj;
148 struct xfs_kobj m_error_kobj;
149 struct xfs_error_cfg m_error_cfg[XFS_ERR_CLASS_MAX][XFS_ERR_ERRNO_MAX];
130 struct xstats m_stats; /* per-fs stats */ 150 struct xstats m_stats; /* per-fs stats */
131 151
132 struct workqueue_struct *m_buf_workqueue; 152 struct workqueue_struct *m_buf_workqueue;
diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c
index 6ced4f143494..74e394071242 100644
--- a/fs/xfs/xfs_sysfs.c
+++ b/fs/xfs/xfs_sysfs.c
@@ -17,10 +17,11 @@
17 */ 17 */
18 18
19#include "xfs.h" 19#include "xfs.h"
20#include "xfs_sysfs.h" 20#include "xfs_shared.h"
21#include "xfs_format.h" 21#include "xfs_format.h"
22#include "xfs_log_format.h" 22#include "xfs_log_format.h"
23#include "xfs_trans_resv.h" 23#include "xfs_trans_resv.h"
24#include "xfs_sysfs.h"
24#include "xfs_log.h" 25#include "xfs_log.h"
25#include "xfs_log_priv.h" 26#include "xfs_log_priv.h"
26#include "xfs_stats.h" 27#include "xfs_stats.h"
@@ -362,3 +363,53 @@ struct kobj_type xfs_log_ktype = {
362 .sysfs_ops = &xfs_sysfs_ops, 363 .sysfs_ops = &xfs_sysfs_ops,
363 .default_attrs = xfs_log_attrs, 364 .default_attrs = xfs_log_attrs,
364}; 365};
366
367/*
368 * Metadata IO error configuration
369 *
370 * The sysfs structure here is:
371 * ...xfs/<dev>/error/<class>/<errno>/<error_attrs>
372 *
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.
376 */
377static struct attribute *xfs_error_attrs[] = {
378 NULL,
379};
380
381static inline struct xfs_error_cfg *
382to_error_cfg(struct kobject *kobject)
383{
384 struct xfs_kobj *kobj = to_kobj(kobject);
385 return container_of(kobj, struct xfs_error_cfg, kobj);
386}
387
388struct kobj_type xfs_error_cfg_ktype = {
389 .release = xfs_sysfs_release,
390 .sysfs_ops = &xfs_sysfs_ops,
391 .default_attrs = xfs_error_attrs,
392};
393
394struct kobj_type xfs_error_ktype = {
395 .release = xfs_sysfs_release,
396};
397
398int
399xfs_error_sysfs_init(
400 struct xfs_mount *mp)
401{
402 int error;
403
404 /* .../xfs/<dev>/error/ */
405 error = xfs_sysfs_init(&mp->m_error_kobj, &xfs_error_ktype,
406 &mp->m_kobj, "error");
407 return error;
408}
409
410void
411xfs_error_sysfs_del(
412 struct xfs_mount *mp)
413{
414 xfs_sysfs_del(&mp->m_error_kobj);
415}
diff --git a/fs/xfs/xfs_sysfs.h b/fs/xfs/xfs_sysfs.h
index be692e59938d..d04637181ef2 100644
--- a/fs/xfs/xfs_sysfs.h
+++ b/fs/xfs/xfs_sysfs.h
@@ -58,4 +58,7 @@ xfs_sysfs_del(
58 wait_for_completion(&kobj->complete); 58 wait_for_completion(&kobj->complete);
59} 59}
60 60
61int xfs_error_sysfs_init(struct xfs_mount *mp);
62void xfs_error_sysfs_del(struct xfs_mount *mp);
63
61#endif /* __XFS_SYSFS_H__ */ 64#endif /* __XFS_SYSFS_H__ */