提交 192852be 编写于 作者: C Carlos Maiolino 提交者: Dave Chinner

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: NDave Chinner <dchinner@redhat.com>
Signed-off-by: NCarlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: NBrian Foster <bfoster@redhat.com>
Signed-off-by: NDave Chinner <david@fromorbit.com>
上级 9bdd9bd6
...@@ -690,10 +690,15 @@ xfs_mountfs( ...@@ -690,10 +690,15 @@ xfs_mountfs(
if (error) if (error)
goto out_remove_sysfs; goto out_remove_sysfs;
error = xfs_uuid_mount(mp); error = xfs_error_sysfs_init(mp);
if (error) if (error)
goto out_del_stats; goto out_del_stats;
error = xfs_uuid_mount(mp);
if (error)
goto out_remove_error_sysfs;
/* /*
* Set the minimum read and write sizes * Set the minimum read and write sizes
*/ */
...@@ -968,6 +973,8 @@ xfs_mountfs( ...@@ -968,6 +973,8 @@ xfs_mountfs(
xfs_da_unmount(mp); xfs_da_unmount(mp);
out_remove_uuid: out_remove_uuid:
xfs_uuid_unmount(mp); xfs_uuid_unmount(mp);
out_remove_error_sysfs:
xfs_error_sysfs_del(mp);
out_del_stats: out_del_stats:
xfs_sysfs_del(&mp->m_stats.xs_kobj); xfs_sysfs_del(&mp->m_stats.xs_kobj);
out_remove_sysfs: out_remove_sysfs:
...@@ -1056,6 +1063,7 @@ xfs_unmountfs( ...@@ -1056,6 +1063,7 @@ xfs_unmountfs(
#endif #endif
xfs_free_perag(mp); xfs_free_perag(mp);
xfs_error_sysfs_del(mp);
xfs_sysfs_del(&mp->m_stats.xs_kobj); xfs_sysfs_del(&mp->m_stats.xs_kobj);
xfs_sysfs_del(&mp->m_kobj); xfs_sysfs_del(&mp->m_kobj);
} }
......
...@@ -37,6 +37,24 @@ enum { ...@@ -37,6 +37,24 @@ enum {
XFS_LOWSP_MAX, XFS_LOWSP_MAX,
}; };
/*
* Error Configuration
*
* Error classes define the subsystem the configuration belongs to.
* Error numbers define the errors that are configurable.
*/
enum {
XFS_ERR_CLASS_MAX,
};
enum {
XFS_ERR_ERRNO_MAX,
};
struct xfs_error_cfg {
struct xfs_kobj kobj;
int max_retries;
};
typedef struct xfs_mount { typedef struct xfs_mount {
struct super_block *m_super; struct super_block *m_super;
xfs_tid_t m_tid; /* next unused tid for fs */ xfs_tid_t m_tid; /* next unused tid for fs */
...@@ -127,6 +145,8 @@ typedef struct xfs_mount { ...@@ -127,6 +145,8 @@ typedef struct xfs_mount {
int64_t m_low_space[XFS_LOWSP_MAX]; int64_t m_low_space[XFS_LOWSP_MAX];
/* low free space thresholds */ /* low free space thresholds */
struct xfs_kobj m_kobj; struct xfs_kobj m_kobj;
struct xfs_kobj m_error_kobj;
struct xfs_error_cfg m_error_cfg[XFS_ERR_CLASS_MAX][XFS_ERR_ERRNO_MAX];
struct xstats m_stats; /* per-fs stats */ struct xstats m_stats; /* per-fs stats */
struct workqueue_struct *m_buf_workqueue; struct workqueue_struct *m_buf_workqueue;
......
...@@ -17,10 +17,11 @@ ...@@ -17,10 +17,11 @@
*/ */
#include "xfs.h" #include "xfs.h"
#include "xfs_sysfs.h" #include "xfs_shared.h"
#include "xfs_format.h" #include "xfs_format.h"
#include "xfs_log_format.h" #include "xfs_log_format.h"
#include "xfs_trans_resv.h" #include "xfs_trans_resv.h"
#include "xfs_sysfs.h"
#include "xfs_log.h" #include "xfs_log.h"
#include "xfs_log_priv.h" #include "xfs_log_priv.h"
#include "xfs_stats.h" #include "xfs_stats.h"
...@@ -362,3 +363,53 @@ struct kobj_type xfs_log_ktype = { ...@@ -362,3 +363,53 @@ struct kobj_type xfs_log_ktype = {
.sysfs_ops = &xfs_sysfs_ops, .sysfs_ops = &xfs_sysfs_ops,
.default_attrs = xfs_log_attrs, .default_attrs = xfs_log_attrs,
}; };
/*
* Metadata IO error configuration
*
* The sysfs structure here is:
* ...xfs/<dev>/error/<class>/<errno>/<error_attrs>
*
* where <class> allows us to discriminate between data IO and metadata IO,
* and any other future type of IO (e.g. special inode or directory error
* handling) we care to support.
*/
static struct attribute *xfs_error_attrs[] = {
NULL,
};
static inline struct xfs_error_cfg *
to_error_cfg(struct kobject *kobject)
{
struct xfs_kobj *kobj = to_kobj(kobject);
return container_of(kobj, struct xfs_error_cfg, kobj);
}
struct kobj_type xfs_error_cfg_ktype = {
.release = xfs_sysfs_release,
.sysfs_ops = &xfs_sysfs_ops,
.default_attrs = xfs_error_attrs,
};
struct kobj_type xfs_error_ktype = {
.release = xfs_sysfs_release,
};
int
xfs_error_sysfs_init(
struct xfs_mount *mp)
{
int error;
/* .../xfs/<dev>/error/ */
error = xfs_sysfs_init(&mp->m_error_kobj, &xfs_error_ktype,
&mp->m_kobj, "error");
return error;
}
void
xfs_error_sysfs_del(
struct xfs_mount *mp)
{
xfs_sysfs_del(&mp->m_error_kobj);
}
...@@ -58,4 +58,7 @@ xfs_sysfs_del( ...@@ -58,4 +58,7 @@ xfs_sysfs_del(
wait_for_completion(&kobj->complete); wait_for_completion(&kobj->complete);
} }
int xfs_error_sysfs_init(struct xfs_mount *mp);
void xfs_error_sysfs_del(struct xfs_mount *mp);
#endif /* __XFS_SYSFS_H__ */ #endif /* __XFS_SYSFS_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册