Skip to content

Commit 254e345

Browse files
author
Darrick J. Wong
committed
xfs: add debug knob to slow down write for fun
Add a new error injection knob so that we can arbitrarily slow down pagecache writes to test for race conditions and aberrant reclaim behavior if the writeback mechanisms are slow to issue writeback. This will enable functional testing for the ifork sequence counters introduced in commit 304a68b ("xfs: use iomap_valid method to detect stale cached iomaps") that fixes write racing with reclaim writeback. Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Dave Chinner <[email protected]>
1 parent c2beff9 commit 254e345

File tree

4 files changed

+60
-3
lines changed

4 files changed

+60
-3
lines changed

fs/xfs/libxfs/xfs_errortag.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@
6262
#define XFS_ERRTAG_DA_LEAF_SPLIT 40
6363
#define XFS_ERRTAG_ATTR_LEAF_TO_NODE 41
6464
#define XFS_ERRTAG_WB_DELAY_MS 42
65-
#define XFS_ERRTAG_MAX 43
65+
#define XFS_ERRTAG_WRITE_DELAY_MS 43
66+
#define XFS_ERRTAG_MAX 44
6667

6768
/*
6869
* Random factors for above tags, 1 means always, 2 means 1/2 time, etc.
@@ -109,5 +110,6 @@
109110
#define XFS_RANDOM_DA_LEAF_SPLIT 1
110111
#define XFS_RANDOM_ATTR_LEAF_TO_NODE 1
111112
#define XFS_RANDOM_WB_DELAY_MS 3000
113+
#define XFS_RANDOM_WRITE_DELAY_MS 3000
112114

113115
#endif /* __XFS_ERRORTAG_H_ */

fs/xfs/xfs_error.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ static unsigned int xfs_errortag_random_default[] = {
6161
XFS_RANDOM_DA_LEAF_SPLIT,
6262
XFS_RANDOM_ATTR_LEAF_TO_NODE,
6363
XFS_RANDOM_WB_DELAY_MS,
64+
XFS_RANDOM_WRITE_DELAY_MS,
6465
};
6566

6667
struct xfs_errortag_attr {
@@ -177,6 +178,7 @@ XFS_ERRORTAG_ATTR_RW(larp, XFS_ERRTAG_LARP);
177178
XFS_ERRORTAG_ATTR_RW(da_leaf_split, XFS_ERRTAG_DA_LEAF_SPLIT);
178179
XFS_ERRORTAG_ATTR_RW(attr_leaf_to_node, XFS_ERRTAG_ATTR_LEAF_TO_NODE);
179180
XFS_ERRORTAG_ATTR_RW(wb_delay_ms, XFS_ERRTAG_WB_DELAY_MS);
181+
XFS_ERRORTAG_ATTR_RW(write_delay_ms, XFS_ERRTAG_WRITE_DELAY_MS);
180182

181183
static struct attribute *xfs_errortag_attrs[] = {
182184
XFS_ERRORTAG_ATTR_LIST(noerror),
@@ -221,6 +223,7 @@ static struct attribute *xfs_errortag_attrs[] = {
221223
XFS_ERRORTAG_ATTR_LIST(da_leaf_split),
222224
XFS_ERRORTAG_ATTR_LIST(attr_leaf_to_node),
223225
XFS_ERRORTAG_ATTR_LIST(wb_delay_ms),
226+
XFS_ERRORTAG_ATTR_LIST(write_delay_ms),
224227
NULL,
225228
};
226229
ATTRIBUTE_GROUPS(xfs_errortag);

fs/xfs/xfs_iomap.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include "xfs_dquot_item.h"
2828
#include "xfs_dquot.h"
2929
#include "xfs_reflink.h"
30+
#include "xfs_error.h"
31+
#include "xfs_errortag.h"
3032

3133
#define XFS_ALLOC_ALIGN(mp, off) \
3234
(((off) >> mp->m_allocsize_log) << mp->m_allocsize_log)
@@ -71,8 +73,16 @@ xfs_iomap_valid(
7173
struct inode *inode,
7274
const struct iomap *iomap)
7375
{
74-
return iomap->validity_cookie ==
75-
xfs_iomap_inode_sequence(XFS_I(inode), iomap->flags);
76+
struct xfs_inode *ip = XFS_I(inode);
77+
78+
if (iomap->validity_cookie !=
79+
xfs_iomap_inode_sequence(ip, iomap->flags)) {
80+
trace_xfs_iomap_invalid(ip, iomap);
81+
return false;
82+
}
83+
84+
XFS_ERRORTAG_DELAY(ip->i_mount, XFS_ERRTAG_WRITE_DELAY_MS);
85+
return true;
7686
}
7787

7888
const struct iomap_page_ops xfs_iomap_page_ops = {

fs/xfs/xfs_trace.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3396,6 +3396,48 @@ DEFINE_EVENT(xfs_wb_invalid_class, name, \
33963396
DEFINE_WB_INVALID_EVENT(xfs_wb_cow_iomap_invalid);
33973397
DEFINE_WB_INVALID_EVENT(xfs_wb_data_iomap_invalid);
33983398

3399+
DECLARE_EVENT_CLASS(xfs_iomap_invalid_class,
3400+
TP_PROTO(struct xfs_inode *ip, const struct iomap *iomap),
3401+
TP_ARGS(ip, iomap),
3402+
TP_STRUCT__entry(
3403+
__field(dev_t, dev)
3404+
__field(xfs_ino_t, ino)
3405+
__field(u64, addr)
3406+
__field(loff_t, pos)
3407+
__field(u64, len)
3408+
__field(u64, validity_cookie)
3409+
__field(u64, inodeseq)
3410+
__field(u16, type)
3411+
__field(u16, flags)
3412+
),
3413+
TP_fast_assign(
3414+
__entry->dev = VFS_I(ip)->i_sb->s_dev;
3415+
__entry->ino = ip->i_ino;
3416+
__entry->addr = iomap->addr;
3417+
__entry->pos = iomap->offset;
3418+
__entry->len = iomap->length;
3419+
__entry->validity_cookie = iomap->validity_cookie;
3420+
__entry->type = iomap->type;
3421+
__entry->flags = iomap->flags;
3422+
__entry->inodeseq = xfs_iomap_inode_sequence(ip, iomap->flags);
3423+
),
3424+
TP_printk("dev %d:%d ino 0x%llx pos 0x%llx addr 0x%llx bytecount 0x%llx type 0x%x flags 0x%x validity_cookie 0x%llx inodeseq 0x%llx",
3425+
MAJOR(__entry->dev), MINOR(__entry->dev),
3426+
__entry->ino,
3427+
__entry->pos,
3428+
__entry->addr,
3429+
__entry->len,
3430+
__entry->type,
3431+
__entry->flags,
3432+
__entry->validity_cookie,
3433+
__entry->inodeseq)
3434+
);
3435+
#define DEFINE_IOMAP_INVALID_EVENT(name) \
3436+
DEFINE_EVENT(xfs_iomap_invalid_class, name, \
3437+
TP_PROTO(struct xfs_inode *ip, const struct iomap *iomap), \
3438+
TP_ARGS(ip, iomap))
3439+
DEFINE_IOMAP_INVALID_EVENT(xfs_iomap_invalid);
3440+
33993441
/* refcount/reflink tracepoint definitions */
34003442

34013443
/* reflink tracepoints */

0 commit comments

Comments
 (0)