diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2017-06-21 03:54:48 +0300 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2017-06-28 04:23:20 +0300 |
commit | f8c47250ba46eb221d1ac537266ac65bcf2866d5 (patch) | |
tree | 34b722bde56dd32d002993116f97a433013720f5 | |
parent | 9e24cfd044853e0e46e7149b91b7bb09effb0a79 (diff) | |
download | linux-f8c47250ba46eb221d1ac537266ac65bcf2866d5.tar.xz |
xfs: convert drop_writes to use the errortag mechanism
We now have enhanced error injection that can control the frequency
with which errors happen, so convert drop_writes to use this.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
-rw-r--r-- | fs/xfs/xfs_error.c | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_error.h | 12 | ||||
-rw-r--r-- | fs/xfs/xfs_iomap.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 24 | ||||
-rw-r--r-- | fs/xfs/xfs_sysfs.c | 42 |
5 files changed, 15 insertions, 68 deletions
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c index e2278af6aed1..a2f23d2bab16 100644 --- a/fs/xfs/xfs_error.c +++ b/fs/xfs/xfs_error.c @@ -55,6 +55,7 @@ static unsigned int xfs_errortag_random_default[] = { XFS_RANDOM_REFCOUNT_FINISH_ONE, XFS_RANDOM_BMAP_FINISH_ONE, XFS_RANDOM_AG_RESV_CRITICAL, + XFS_RANDOM_DROP_WRITES, }; struct xfs_errortag_attr { @@ -157,6 +158,7 @@ XFS_ERRORTAG_ATTR_RW(refcount_continue_update, XFS_ERRTAG_REFCOUNT_CONTINUE_UPDA XFS_ERRORTAG_ATTR_RW(refcount_finish_one, XFS_ERRTAG_REFCOUNT_FINISH_ONE); XFS_ERRORTAG_ATTR_RW(bmap_finish_one, XFS_ERRTAG_BMAP_FINISH_ONE); XFS_ERRORTAG_ATTR_RW(ag_resv_critical, XFS_ERRTAG_AG_RESV_CRITICAL); +XFS_ERRORTAG_ATTR_RW(drop_writes, XFS_ERRTAG_DROP_WRITES); static struct attribute *xfs_errortag_attrs[] = { XFS_ERRORTAG_ATTR_LIST(noerror), @@ -187,6 +189,7 @@ static struct attribute *xfs_errortag_attrs[] = { XFS_ERRORTAG_ATTR_LIST(refcount_finish_one), XFS_ERRORTAG_ATTR_LIST(bmap_finish_one), XFS_ERRORTAG_ATTR_LIST(ag_resv_critical), + XFS_ERRORTAG_ATTR_LIST(drop_writes), NULL, }; diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h index ae8935b90a93..e0e4cf776fac 100644 --- a/fs/xfs/xfs_error.h +++ b/fs/xfs/xfs_error.h @@ -96,7 +96,16 @@ extern void xfs_verifier_error(struct xfs_buf *bp); #define XFS_ERRTAG_REFCOUNT_FINISH_ONE 25 #define XFS_ERRTAG_BMAP_FINISH_ONE 26 #define XFS_ERRTAG_AG_RESV_CRITICAL 27 -#define XFS_ERRTAG_MAX 28 +/* + * DEBUG mode instrumentation to test and/or trigger delayed allocation + * block killing in the event of failed writes. When enabled, all + * buffered writes are silenty dropped and handled as if they failed. + * All delalloc blocks in the range of the write (including pre-existing + * delalloc blocks!) are tossed as part of the write failure error + * handling sequence. + */ +#define XFS_ERRTAG_DROP_WRITES 28 +#define XFS_ERRTAG_MAX 29 /* * Random factors for above tags, 1 means always, 2 means 1/2 time, etc. @@ -129,6 +138,7 @@ extern void xfs_verifier_error(struct xfs_buf *bp); #define XFS_RANDOM_REFCOUNT_FINISH_ONE 1 #define XFS_RANDOM_BMAP_FINISH_ONE 1 #define XFS_RANDOM_AG_RESV_CRITICAL 4 +#define XFS_RANDOM_DROP_WRITES 1 #ifdef DEBUG extern int xfs_errortag_init(struct xfs_mount *mp); diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 304b79d681e4..86f1a9fa46d2 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -1097,7 +1097,7 @@ xfs_file_iomap_end_delalloc( * Behave as if the write failed if drop writes is enabled. Set the NEW * flag to force delalloc cleanup. */ - if (xfs_mp_drop_writes(mp)) { + if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_DROP_WRITES)) { iomap->flags |= IOMAP_F_NEW; written = 0; } diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 931e9fc21a1c..e0792d036be2 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -205,16 +205,6 @@ typedef struct xfs_mount { */ unsigned int *m_errortag; struct xfs_kobj m_errortag_kobj; - - /* - * DEBUG mode instrumentation to test and/or trigger delayed allocation - * block killing in the event of failed writes. When enabled, all - * buffered writes are silenty dropped and handled as if they failed. - * All delalloc blocks in the range of the write (including pre-existing - * delalloc blocks!) are tossed as part of the write failure error - * handling sequence. - */ - bool m_drop_writes; #endif } xfs_mount_t; @@ -333,20 +323,6 @@ xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d) return (xfs_agblock_t) do_div(ld, mp->m_sb.sb_agblocks); } -#ifdef DEBUG -static inline bool -xfs_mp_drop_writes(struct xfs_mount *mp) -{ - return mp->m_drop_writes; -} -#else -static inline bool -xfs_mp_drop_writes(struct xfs_mount *mp) -{ - return 0; -} -#endif - /* per-AG block reservation data structures*/ enum xfs_ag_resv_type { XFS_AG_RESV_NONE = 0, diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c index ec6e0e2f95d6..56610a973593 100644 --- a/fs/xfs/xfs_sysfs.c +++ b/fs/xfs/xfs_sysfs.c @@ -90,49 +90,7 @@ to_mp(struct kobject *kobject) return container_of(kobj, struct xfs_mount, m_kobj); } -#ifdef DEBUG - -STATIC ssize_t -drop_writes_store( - struct kobject *kobject, - const char *buf, - size_t count) -{ - struct xfs_mount *mp = to_mp(kobject); - int ret; - int val; - - ret = kstrtoint(buf, 0, &val); - if (ret) - return ret; - - if (val == 1) - mp->m_drop_writes = true; - else if (val == 0) - mp->m_drop_writes = false; - else - return -EINVAL; - - return count; -} - -STATIC ssize_t -drop_writes_show( - struct kobject *kobject, - char *buf) -{ - struct xfs_mount *mp = to_mp(kobject); - - return snprintf(buf, PAGE_SIZE, "%d\n", mp->m_drop_writes ? 1 : 0); -} -XFS_SYSFS_ATTR_RW(drop_writes); - -#endif /* DEBUG */ - static struct attribute *xfs_mp_attrs[] = { -#ifdef DEBUG - ATTR_LIST(drop_writes), -#endif NULL, }; |