@@ -73,6 +73,13 @@ struct xfs_mp_error_cfg_kobj {
struct xfs_error_cfg cfg;
};
+struct xfs_dft_error_cfg_kobj {
+ struct xfs_kobj kobj;
+ struct xfs_error_cfg cfg;
+ int error_class;
+ int error_nr;
+};
+
struct xfs_mp_error_obj {
struct xfs_kobj kobj;
struct xfs_kobj meta_kobj;
@@ -80,6 +87,13 @@ struct xfs_mp_error_obj {
bool fail_unmount;
};
+struct xfs_dft_error_obj {
+ struct xfs_kobj kobj;
+ struct xfs_kobj meta_kobj;
+ struct xfs_dft_error_cfg_kobj cfg_kobj[XFS_ERR_CLASS_MAX][XFS_ERR_ERRNO_MAX];
+ bool fail_unmount;
+};
+
typedef struct xfs_mount {
struct super_block *m_super;
xfs_tid_t m_tid; /* next unused tid for fs */
@@ -2043,11 +2043,15 @@ init_xfs_fs(void)
if (error)
goto out_free_stats;
+ error = xfs_dft_error_sysfs_init(xfs_kset);
+ if (error)
+ goto out_remove_stats_kobj;
+
#ifdef DEBUG
xfs_dbg_kobj.kobject.kset = xfs_kset;
error = xfs_sysfs_init(&xfs_dbg_kobj, &xfs_dbg_ktype, NULL, "debug");
if (error)
- goto out_remove_stats_kobj;
+ goto out_remove_dft_error_sysfs;
#endif
error = xfs_qm_init();
@@ -2064,8 +2068,10 @@ init_xfs_fs(void)
out_remove_dbg_kobj:
#ifdef DEBUG
xfs_sysfs_del(&xfs_dbg_kobj);
- out_remove_stats_kobj:
+ out_remove_dft_error_sysfs:
#endif
+ xfs_dft_error_sysfs_del();
+ out_remove_stats_kobj:
xfs_sysfs_del(&xfsstats.xs_kobj);
out_free_stats:
free_percpu(xfsstats.xs_stats);
@@ -2095,6 +2101,7 @@ exit_xfs_fs(void)
#ifdef DEBUG
xfs_sysfs_del(&xfs_dbg_kobj);
#endif
+ xfs_dft_error_sysfs_del();
xfs_sysfs_del(&xfsstats.xs_kobj);
free_percpu(xfsstats.xs_stats);
kset_unregister(xfs_kset);
@@ -45,6 +45,8 @@ struct xfs_sysfs_attr {
size_t count);
};
+static struct xfs_dft_error_obj xfs_dft_eobj;
+
static inline struct xfs_sysfs_attr *
to_attr(struct attribute *attr)
{
@@ -57,8 +59,12 @@ to_attr(struct attribute *attr)
static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RO(name)
#define XFS_SYSFS_ATTR_WO(name) \
static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_WO(name)
+#define XFS_SYSFS_DFT_ATTR_RW(name) \
+ static struct xfs_sysfs_attr xfs_sysfs_attr_dft_##name = \
+ __ATTR(name, 0644, dft_##name##_show, dft_##name##_store)
-#define ATTR_LIST(name) &xfs_sysfs_attr_##name.attr
+#define ATTR_LIST(name) (&xfs_sysfs_attr_##name.attr)
+#define DFT_ATTR_LIST(name) (&xfs_sysfs_attr_dft_##name.attr)
STATIC ssize_t
xfs_sysfs_object_show(
@@ -344,16 +350,34 @@ static inline struct xfs_mp_error_cfg_kobj *
to_mp_error_cfg_kobj(struct kobject *kobject)
{
struct xfs_kobj *kobj = to_kobj(kobject);
+
return container_of(kobj, struct xfs_mp_error_cfg_kobj, kobj);
}
+static inline struct xfs_dft_error_cfg_kobj *
+to_dft_error_cfg_kobj(struct kobject *kobject)
+{
+ struct xfs_kobj *kobj = to_kobj(kobject);
+
+ return container_of(kobj, struct xfs_dft_error_cfg_kobj, kobj);
+}
+
static inline struct xfs_mp_error_obj *
to_mp_error_obj(struct kobject *kobject)
{
struct xfs_kobj *kobj = to_kobj(kobject);
+
return container_of(kobj, struct xfs_mp_error_obj, kobj);
}
+static inline struct xfs_dft_error_obj *
+to_dft_error_obj(struct kobject *kobject)
+{
+ struct xfs_kobj *kobj = to_kobj(kobject);
+
+ return container_of(kobj, struct xfs_dft_error_obj, kobj);
+}
+
static ssize_t
__max_retries_show(
struct xfs_error_cfg *cfg,
@@ -415,6 +439,30 @@ max_retries_store(
XFS_SYSFS_ATTR_RW(max_retries);
static ssize_t
+dft_max_retries_show(
+ struct kobject *kobject,
+ char *buf)
+{
+ struct xfs_dft_error_cfg_kobj *cfg_kobj =
+ to_dft_error_cfg_kobj(kobject);
+
+ return __max_retries_show(&cfg_kobj->cfg, buf);
+}
+
+static ssize_t
+dft_max_retries_store(
+ struct kobject *kobject,
+ const char *buf,
+ size_t count)
+{
+ struct xfs_dft_error_cfg_kobj *cfg_kobj =
+ to_dft_error_cfg_kobj(kobject);
+
+ return __max_retries_store(&cfg_kobj->cfg, buf, count);
+}
+XFS_SYSFS_DFT_ATTR_RW(max_retries);
+
+static ssize_t
__retry_timeout_seconds_show(
struct xfs_error_cfg *cfg,
char *buf)
@@ -477,6 +525,30 @@ retry_timeout_seconds_store(
}
XFS_SYSFS_ATTR_RW(retry_timeout_seconds);
+static ssize_t
+dft_retry_timeout_seconds_show(
+ struct kobject *kobject,
+ char *buf)
+{
+ struct xfs_dft_error_cfg_kobj *cfg_kobj =
+ to_dft_error_cfg_kobj(kobject);
+
+ return __retry_timeout_seconds_show(&cfg_kobj->cfg, buf);
+}
+
+static ssize_t
+dft_retry_timeout_seconds_store(
+ struct kobject *kobject,
+ const char *buf,
+ size_t count)
+{
+ struct xfs_dft_error_cfg_kobj *cfg_kobj =
+ to_dft_error_cfg_kobj(kobject);
+
+ return __retry_timeout_seconds_store(&cfg_kobj->cfg, buf, count);
+}
+XFS_SYSFS_DFT_ATTR_RW(retry_timeout_seconds);
+
static inline ssize_t
__fail_at_unmount_show(
bool fail_unmount,
@@ -527,12 +599,39 @@ fail_at_unmount_store(
}
XFS_SYSFS_ATTR_RW(fail_at_unmount);
+static ssize_t
+dft_fail_at_unmount_show(
+ struct kobject *kobject,
+ char *buf)
+{
+ struct xfs_dft_error_obj *eobj = to_dft_error_obj(kobject);
+
+ return __fail_at_unmount_show(eobj->fail_unmount, buf);
+}
+
+static ssize_t
+dft_fail_at_unmount_store(
+ struct kobject *kobject,
+ const char *buf,
+ size_t count)
+{
+ struct xfs_dft_error_obj *eobj = to_dft_error_obj(kobject);
+
+ return __fail_at_unmount_store(&eobj->fail_unmount, buf, count);
+}
+XFS_SYSFS_DFT_ATTR_RW(fail_at_unmount);
+
static struct attribute *xfs_error_attrs[] = {
ATTR_LIST(max_retries),
ATTR_LIST(retry_timeout_seconds),
NULL,
};
+static struct attribute *xfs_dft_error_attrs[] = {
+ DFT_ATTR_LIST(max_retries),
+ DFT_ATTR_LIST(retry_timeout_seconds),
+ NULL,
+};
static struct kobj_type xfs_error_cfg_ktype = {
.release = xfs_sysfs_release,
@@ -540,6 +639,12 @@ static struct kobj_type xfs_error_cfg_ktype = {
.default_attrs = xfs_error_attrs,
};
+static struct kobj_type xfs_dft_error_cfg_ktype = {
+ .release = xfs_sysfs_release,
+ .sysfs_ops = &xfs_sysfs_ops,
+ .default_attrs = xfs_dft_error_attrs,
+};
+
static struct kobj_type xfs_error_ktype = {
.release = xfs_sysfs_release,
.sysfs_ops = &xfs_sysfs_ops,
@@ -621,7 +726,7 @@ __xfs_error_sysfs_init(
{
int error;
- /* .../xfs/<dev>/error/ */
+ /* .../xfs/default_error/ or .../xfs/<dev>/error/ */
error = xfs_sysfs_init(arg->kobj, &xfs_error_ktype, parent, name);
if (error)
return error;
@@ -630,7 +735,7 @@ __xfs_error_sysfs_init(
if (error)
goto out_error;
- /* .../xfs/<dev>/error/metadata/ */
+ /* .../xfs/error/metadata/ or .../xfs/<dev>/error/metadata/ */
error = xfs_error_sysfs_init_class(arg, XFS_ERR_METADATA,
"metadata", xfs_error_meta_init);
if (error)
@@ -758,3 +863,50 @@ xfs_error_get_cfg(
return &eobj->cfg_kobj[error_class][idx].cfg;
}
+
+static struct xfs_kobj *
+xfs_get_dft_error_cfg_kobj(
+ void *priv,
+ int class,
+ int nr)
+{
+ struct xfs_dft_error_obj *eobj = priv;
+
+ return &eobj->cfg_kobj[class][nr].kobj;
+}
+
+int
+xfs_dft_error_sysfs_init(struct kset *kset)
+{
+ struct xfs_dft_error_obj *eobj = &xfs_dft_eobj;
+ struct xfs_error_sysfs_arg arg;
+
+ eobj->kobj.kobject.kset = kset;
+
+ eobj->fail_unmount = 1;
+
+ arg.kobj = &eobj->kobj;
+ arg.meta_kobj = &eobj->meta_kobj;
+ arg.fail_unmount_attr = DFT_ATTR_LIST(fail_at_unmount);
+ arg.cfg_ktype = &xfs_dft_error_cfg_ktype;
+ arg.get_cfg_kobj = xfs_get_dft_error_cfg_kobj;
+ arg.priv = eobj;
+
+ return __xfs_error_sysfs_init(&arg, "default_error", NULL);
+}
+
+void
+xfs_dft_error_sysfs_del(void)
+{
+ struct xfs_dft_error_obj *eobj = &xfs_dft_eobj;
+ struct xfs_error_sysfs_arg arg;
+
+ arg.kobj = &eobj->kobj;
+ arg.meta_kobj = &eobj->meta_kobj;
+ arg.fail_unmount_attr = NULL;
+ arg.cfg_ktype = NULL;
+ arg.get_cfg_kobj = xfs_get_dft_error_cfg_kobj;
+ arg.priv = eobj;
+
+ __xfs_error_sysfs_del(&arg);
+}
@@ -63,5 +63,7 @@ xfs_sysfs_del(
int xfs_error_sysfs_init(struct xfs_mp_error_obj *eobj,
struct xfs_kobj *parent);
void xfs_error_sysfs_del(struct xfs_mp_error_obj *eobj);
+int xfs_dft_error_sysfs_init(struct kset *kset);
+void xfs_dft_error_sysfs_del(void);
#endif /* __XFS_SYSFS_H__ */
Both the hierarchies and the names are the same with the sysfs tree of the mount-point specific error configuration. The only difference is the root of error configuration sysfs tree: for the sysfs tree of default values it is "xfs/default_error" instead of "xfs/<dev_name>/error". Signed-off-by: Hou Tao <houtao1@huawei.com> --- fs/xfs/xfs_mount.h | 14 +++++ fs/xfs/xfs_super.c | 11 +++- fs/xfs/xfs_sysfs.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++- fs/xfs/xfs_sysfs.h | 2 + 4 files changed, 180 insertions(+), 5 deletions(-)