Skip to content

Commit 2d263de

Browse files
Christoph Hellwigcmaiolino
authored andcommitted
xfs: allow setting errortags at mount time
Add an errortag mount option that enables an errortag with the default injection frequency. This allows injecting errors into the mount process instead of just on live file systems, and thus test mount error handling. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Hans Holmberg <hans.holmberg@wdc.com> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Signed-off-by: Carlos Maiolino <cem@kernel.org>
1 parent 4d8f424 commit 2d263de

4 files changed

Lines changed: 55 additions & 1 deletion

File tree

Documentation/admin-guide/xfs.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,14 @@ When mounting an XFS filesystem, the following options are accepted.
215215
inconsistent namespace presentation during or after a
216216
failover event.
217217

218+
errortag=tagname
219+
When specified, enables the error inject tag named "tagname" with the
220+
default frequency. Can be specified multiple times to enable multiple
221+
errortags. Specifying this option on remount will reset the error tag
222+
to the default value if it was set to any other value before.
223+
This option is only supported when CONFIG_XFS_DEBUG is enabled, and
224+
will not be reflected in /proc/self/mounts.
225+
218226
Deprecation of V4 Format
219227
========================
220228

fs/xfs/xfs_error.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@
2222
static const unsigned int xfs_errortag_random_default[] = { XFS_ERRTAGS };
2323
#undef XFS_ERRTAG
2424

25+
#define XFS_ERRTAG(_tag, _name, _default) \
26+
[XFS_ERRTAG_##_tag] = __stringify(_name),
27+
#include "xfs_errortag.h"
28+
static const char *xfs_errortag_names[] = { XFS_ERRTAGS };
29+
#undef XFS_ERRTAG
30+
2531
struct xfs_errortag_attr {
2632
struct attribute attr;
2733
unsigned int tag;
@@ -189,6 +195,36 @@ xfs_errortag_add(
189195
return 0;
190196
}
191197

198+
int
199+
xfs_errortag_add_name(
200+
struct xfs_mount *mp,
201+
const char *tag_name)
202+
{
203+
unsigned int i;
204+
205+
for (i = 0; i < XFS_ERRTAG_MAX; i++) {
206+
if (xfs_errortag_names[i] &&
207+
!strcmp(xfs_errortag_names[i], tag_name))
208+
return xfs_errortag_add(mp, i);
209+
}
210+
211+
return -EINVAL;
212+
}
213+
214+
void
215+
xfs_errortag_copy(
216+
struct xfs_mount *dst_mp,
217+
struct xfs_mount *src_mp)
218+
{
219+
unsigned int val, i;
220+
221+
for (i = 0; i < XFS_ERRTAG_MAX; i++) {
222+
val = READ_ONCE(src_mp->m_errortag[i]);
223+
if (val)
224+
WRITE_ONCE(dst_mp->m_errortag[i], val);
225+
}
226+
}
227+
192228
int
193229
xfs_errortag_clearall(
194230
struct xfs_mount *mp)

fs/xfs/xfs_error.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,17 @@ void xfs_errortag_delay(struct xfs_mount *mp, const char *file, int line,
4545
#define XFS_ERRORTAG_DELAY(mp, tag) \
4646
xfs_errortag_delay((mp), __FILE__, __LINE__, (tag))
4747
int xfs_errortag_add(struct xfs_mount *mp, unsigned int error_tag);
48+
int xfs_errortag_add_name(struct xfs_mount *mp, const char *tag_name);
49+
void xfs_errortag_copy(struct xfs_mount *dst_mp, struct xfs_mount *src_mp);
4850
int xfs_errortag_clearall(struct xfs_mount *mp);
4951
#else
5052
#define xfs_errortag_init(mp) (0)
5153
#define xfs_errortag_del(mp)
5254
#define XFS_TEST_ERROR(mp, tag) (false)
5355
#define XFS_ERRORTAG_DELAY(mp, tag) ((void)0)
5456
#define xfs_errortag_add(mp, tag) (-ENOSYS)
57+
#define xfs_errortag_copy(dst_mp, src_mp) ((void)0)
58+
#define xfs_errortag_add_name(mp, tag_name) (-ENOSYS)
5559
#define xfs_errortag_clearall(mp) (-ENOSYS)
5660
#endif /* DEBUG */
5761

fs/xfs/xfs_super.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "xfs_defer.h"
4141
#include "xfs_attr_item.h"
4242
#include "xfs_xattr.h"
43+
#include "xfs_error.h"
4344
#include "xfs_errortag.h"
4445
#include "xfs_iunlink_item.h"
4546
#include "xfs_dahash_test.h"
@@ -114,7 +115,7 @@ enum {
114115
Opt_prjquota, Opt_uquota, Opt_gquota, Opt_pquota,
115116
Opt_uqnoenforce, Opt_gqnoenforce, Opt_pqnoenforce, Opt_qnoenforce,
116117
Opt_discard, Opt_nodiscard, Opt_dax, Opt_dax_enum, Opt_max_open_zones,
117-
Opt_lifetime, Opt_nolifetime, Opt_max_atomic_write,
118+
Opt_lifetime, Opt_nolifetime, Opt_max_atomic_write, Opt_errortag,
118119
};
119120

120121
#define fsparam_dead(NAME) \
@@ -173,6 +174,7 @@ static const struct fs_parameter_spec xfs_fs_parameters[] = {
173174
fsparam_flag("lifetime", Opt_lifetime),
174175
fsparam_flag("nolifetime", Opt_nolifetime),
175176
fsparam_string("max_atomic_write", Opt_max_atomic_write),
177+
fsparam_string("errortag", Opt_errortag),
176178
{}
177179
};
178180

@@ -1593,6 +1595,8 @@ xfs_fs_parse_param(
15931595
return -EINVAL;
15941596
}
15951597
return 0;
1598+
case Opt_errortag:
1599+
return xfs_errortag_add_name(parsing_mp, param->string);
15961600
default:
15971601
xfs_warn(parsing_mp, "unknown mount option [%s].", param->key);
15981602
return -EINVAL;
@@ -2184,6 +2188,8 @@ xfs_fs_reconfigure(
21842188
if (error)
21852189
return error;
21862190

2191+
xfs_errortag_copy(mp, new_mp);
2192+
21872193
/* Validate new max_atomic_write option before making other changes */
21882194
if (mp->m_awu_max_bytes != new_mp->m_awu_max_bytes) {
21892195
error = xfs_set_max_atomic_write_opt(mp,

0 commit comments

Comments
 (0)