]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
xfs: configurable error behavior via sysfs
authorCarlos Maiolino <cmaiolino@redhat.com>
Wed, 18 May 2016 00:58:51 +0000 (10:58 +1000)
committerChuck Anderson <chuck.anderson@oracle.com>
Sat, 10 Jun 2017 00:25:15 +0000 (17:25 -0700)
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>
(cherry picked from commit 192852be8b5fb14268c2133fe9ce5312e4745963)

Orabug: 26130728

Signed-off-by: Kirtikar Kashyap <kirtikar.kashyap@oracle.com>
Reviewed-by: Jack Vogel <jack.vogel@oracle.com>
 Conflicts:
fs/xfs/xfs_sysfs.c

fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.h
fs/xfs/xfs_sysfs.c
fs/xfs/xfs_sysfs.h

index 6d8b1a107094e1f8f36ad1138c3c13d05ffcd116..902718596c96e86bb1ca790ee4deda83bf0b2a38 100644 (file)
@@ -700,10 +700,15 @@ xfs_mountfs(
        if (error)
                goto out_remove_sysfs;
 
-       error = xfs_uuid_mount(mp);
+       error = xfs_error_sysfs_init(mp);
        if (error)
                goto out_del_stats;
 
+
+       error = xfs_uuid_mount(mp);
+       if (error)
+               goto out_remove_error_sysfs;
+
        /*
         * Set the minimum read and write sizes
         */
@@ -958,6 +963,8 @@ xfs_mountfs(
        xfs_da_unmount(mp);
  out_remove_uuid:
        xfs_uuid_unmount(mp);
+ out_remove_error_sysfs:
+       xfs_error_sysfs_del(mp);
  out_del_stats:
        xfs_sysfs_del(&mp->m_stats.xs_kobj);
  out_remove_sysfs:
@@ -1046,6 +1053,7 @@ xfs_unmountfs(
 #endif
        xfs_free_perag(mp);
 
+       xfs_error_sysfs_del(mp);
        xfs_sysfs_del(&mp->m_stats.xs_kobj);
        xfs_sysfs_del(&mp->m_kobj);
 }
index d43a804309844728dc3fb6780fa6fd94b84c2d3d..e41891975022cac225f18be5d0633e96303d8a2f 100644 (file)
@@ -37,6 +37,24 @@ enum {
        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 {
        struct super_block      *m_super;
        xfs_tid_t               m_tid;          /* next unused tid for fs */
@@ -125,6 +143,8 @@ typedef struct xfs_mount {
        int64_t                 m_low_space[XFS_LOWSP_MAX];
                                                /* low free space thresholds */
        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 workqueue_struct *m_buf_workqueue;
index ee70f5dec9dccf088eada0d354b06cb847577a2a..e59c105b76b87b0ca772e5096ffb5cc1e294942c 100644 (file)
  */
 
 #include "xfs.h"
-#include "xfs_sysfs.h"
+#include "xfs_shared.h"
+#include "xfs_format.h"
 #include "xfs_log_format.h"
+#include "xfs_trans_resv.h"
+#include "xfs_sysfs.h"
 #include "xfs_log.h"
 #include "xfs_log_priv.h"
 #include "xfs_stats.h"
+#include "xfs_mount.h"
 
 struct xfs_sysfs_attr {
        struct attribute attr;
@@ -268,3 +272,53 @@ struct kobj_type xfs_log_ktype = {
        .sysfs_ops = &xfs_sysfs_ops,
        .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);
+}
index be692e59938db7e8cba4ca4186b1a8f90928887c..d04637181ef21709715d6320bf0569e3d715740a 100644 (file)
@@ -58,4 +58,7 @@ xfs_sysfs_del(
        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__ */