diff options
| -rw-r--r-- | Documentation/admin-guide/xfs.rst | 8 | ||||
| -rw-r--r-- | fs/xfs/xfs_error.c | 36 | ||||
| -rw-r--r-- | fs/xfs/xfs_error.h | 4 | ||||
| -rw-r--r-- | fs/xfs/xfs_super.c | 8 |
4 files changed, 55 insertions, 1 deletions
diff --git a/Documentation/admin-guide/xfs.rst b/Documentation/admin-guide/xfs.rst index c85cd327af28..746ea60eed3f 100644 --- a/Documentation/admin-guide/xfs.rst +++ b/Documentation/admin-guide/xfs.rst @@ -215,6 +215,14 @@ When mounting an XFS filesystem, the following options are accepted. inconsistent namespace presentation during or after a failover event. + errortag=tagname + When specified, enables the error inject tag named "tagname" with the + default frequency. Can be specified multiple times to enable multiple + errortags. Specifying this option on remount will reset the error tag + to the default value if it was set to any other value before. + This option is only supported when CONFIG_XFS_DEBUG is enabled, and + will not be reflected in /proc/self/mounts. + Deprecation of V4 Format ======================== diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c index 53704f1ed791..d652240a1dca 100644 --- a/fs/xfs/xfs_error.c +++ b/fs/xfs/xfs_error.c @@ -22,6 +22,12 @@ static const unsigned int xfs_errortag_random_default[] = { XFS_ERRTAGS }; #undef XFS_ERRTAG +#define XFS_ERRTAG(_tag, _name, _default) \ + [XFS_ERRTAG_##_tag] = __stringify(_name), +#include "xfs_errortag.h" +static const char *xfs_errortag_names[] = { XFS_ERRTAGS }; +#undef XFS_ERRTAG + struct xfs_errortag_attr { struct attribute attr; unsigned int tag; @@ -190,6 +196,36 @@ xfs_errortag_add( } int +xfs_errortag_add_name( + struct xfs_mount *mp, + const char *tag_name) +{ + unsigned int i; + + for (i = 0; i < XFS_ERRTAG_MAX; i++) { + if (xfs_errortag_names[i] && + !strcmp(xfs_errortag_names[i], tag_name)) + return xfs_errortag_add(mp, i); + } + + return -EINVAL; +} + +void +xfs_errortag_copy( + struct xfs_mount *dst_mp, + struct xfs_mount *src_mp) +{ + unsigned int val, i; + + for (i = 0; i < XFS_ERRTAG_MAX; i++) { + val = READ_ONCE(src_mp->m_errortag[i]); + if (val) + WRITE_ONCE(dst_mp->m_errortag[i], val); + } +} + +int xfs_errortag_clearall( struct xfs_mount *mp) { diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h index b40e7c671d2a..05fc1d1cf521 100644 --- a/fs/xfs/xfs_error.h +++ b/fs/xfs/xfs_error.h @@ -45,6 +45,8 @@ void xfs_errortag_delay(struct xfs_mount *mp, const char *file, int line, #define XFS_ERRORTAG_DELAY(mp, tag) \ xfs_errortag_delay((mp), __FILE__, __LINE__, (tag)) int xfs_errortag_add(struct xfs_mount *mp, unsigned int error_tag); +int xfs_errortag_add_name(struct xfs_mount *mp, const char *tag_name); +void xfs_errortag_copy(struct xfs_mount *dst_mp, struct xfs_mount *src_mp); int xfs_errortag_clearall(struct xfs_mount *mp); #else #define xfs_errortag_init(mp) (0) @@ -52,6 +54,8 @@ int xfs_errortag_clearall(struct xfs_mount *mp); #define XFS_TEST_ERROR(mp, tag) (false) #define XFS_ERRORTAG_DELAY(mp, tag) ((void)0) #define xfs_errortag_add(mp, tag) (-ENOSYS) +#define xfs_errortag_copy(dst_mp, src_mp) ((void)0) +#define xfs_errortag_add_name(mp, tag_name) (-ENOSYS) #define xfs_errortag_clearall(mp) (-ENOSYS) #endif /* DEBUG */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 5029bf63b87d..1dcbad1c5d68 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -40,6 +40,7 @@ #include "xfs_defer.h" #include "xfs_attr_item.h" #include "xfs_xattr.h" +#include "xfs_error.h" #include "xfs_errortag.h" #include "xfs_iunlink_item.h" #include "xfs_dahash_test.h" @@ -114,7 +115,7 @@ enum { Opt_prjquota, Opt_uquota, Opt_gquota, Opt_pquota, Opt_uqnoenforce, Opt_gqnoenforce, Opt_pqnoenforce, Opt_qnoenforce, Opt_discard, Opt_nodiscard, Opt_dax, Opt_dax_enum, Opt_max_open_zones, - Opt_lifetime, Opt_nolifetime, Opt_max_atomic_write, + Opt_lifetime, Opt_nolifetime, Opt_max_atomic_write, Opt_errortag, }; #define fsparam_dead(NAME) \ @@ -173,6 +174,7 @@ static const struct fs_parameter_spec xfs_fs_parameters[] = { fsparam_flag("lifetime", Opt_lifetime), fsparam_flag("nolifetime", Opt_nolifetime), fsparam_string("max_atomic_write", Opt_max_atomic_write), + fsparam_string("errortag", Opt_errortag), {} }; @@ -1593,6 +1595,8 @@ xfs_fs_parse_param( return -EINVAL; } return 0; + case Opt_errortag: + return xfs_errortag_add_name(parsing_mp, param->string); default: xfs_warn(parsing_mp, "unknown mount option [%s].", param->key); return -EINVAL; @@ -2184,6 +2188,8 @@ xfs_fs_reconfigure( if (error) return error; + xfs_errortag_copy(mp, new_mp); + /* Validate new max_atomic_write option before making other changes */ if (mp->m_awu_max_bytes != new_mp->m_awu_max_bytes) { error = xfs_set_max_atomic_write_opt(mp, |
