From: Brian Foster <bfoster@redhat.com>
To: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: linux-xfs@vger.kernel.org
Subject: Re: [PATCH 1/4] xfs: make errortag a per-mountpoint structure
Date: Mon, 26 Jun 2017 07:10:53 -0400 [thread overview]
Message-ID: <20170626111050.GA54427@bfoster.bfoster> (raw)
In-Reply-To: <149823571523.31786.9698090244865978473.stgit@birch.djwong.org>
On Fri, Jun 23, 2017 at 09:35:15AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> Remove the xfs_etest structure in favor of a per-mountpoint structure.
> This will give us the flexibility to set as many error injection points
> as we want, and later enable us to set up sysfs knobs to set the trigger
> frequency as we wish. This comes at a cost of higher memory use, but
> unti we hit 1024 injection points (we're at 29) or a lot of mounts this
> shouldn't be a huge issue.
>
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
Reviewed-by: Brian Foster <bfoster@redhat.com>
> fs/xfs/xfs_error.c | 154 +++++++++++++++++++++++++++-------------------------
> fs/xfs/xfs_error.h | 25 +++++---
> fs/xfs/xfs_ioctl.c | 4 +
> fs/xfs/xfs_mount.c | 10 +++
> fs/xfs/xfs_mount.h | 7 ++
> 5 files changed, 111 insertions(+), 89 deletions(-)
>
>
> diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
> index ed7ee4e..52f75bc 100644
> --- a/fs/xfs/xfs_error.c
> +++ b/fs/xfs/xfs_error.c
> @@ -25,100 +25,106 @@
>
> #ifdef DEBUG
>
> -int xfs_etest[XFS_NUM_INJECT_ERROR];
> -int64_t xfs_etest_fsid[XFS_NUM_INJECT_ERROR];
> -char * xfs_etest_fsname[XFS_NUM_INJECT_ERROR];
> -int xfs_error_test_active;
> +static unsigned int xfs_errortag_random_default[] = {
> + XFS_RANDOM_DEFAULT,
> + XFS_RANDOM_IFLUSH_1,
> + XFS_RANDOM_IFLUSH_2,
> + XFS_RANDOM_IFLUSH_3,
> + XFS_RANDOM_IFLUSH_4,
> + XFS_RANDOM_IFLUSH_5,
> + XFS_RANDOM_IFLUSH_6,
> + XFS_RANDOM_DA_READ_BUF,
> + XFS_RANDOM_BTREE_CHECK_LBLOCK,
> + XFS_RANDOM_BTREE_CHECK_SBLOCK,
> + XFS_RANDOM_ALLOC_READ_AGF,
> + XFS_RANDOM_IALLOC_READ_AGI,
> + XFS_RANDOM_ITOBP_INOTOBP,
> + XFS_RANDOM_IUNLINK,
> + XFS_RANDOM_IUNLINK_REMOVE,
> + XFS_RANDOM_DIR_INO_VALIDATE,
> + XFS_RANDOM_BULKSTAT_READ_CHUNK,
> + XFS_RANDOM_IODONE_IOERR,
> + XFS_RANDOM_STRATREAD_IOERR,
> + XFS_RANDOM_STRATCMPL_IOERR,
> + XFS_RANDOM_DIOWRITE_IOERR,
> + XFS_RANDOM_BMAPIFORMAT,
> + XFS_RANDOM_FREE_EXTENT,
> + XFS_RANDOM_RMAP_FINISH_ONE,
> + XFS_RANDOM_REFCOUNT_CONTINUE_UPDATE,
> + XFS_RANDOM_REFCOUNT_FINISH_ONE,
> + XFS_RANDOM_BMAP_FINISH_ONE,
> + XFS_RANDOM_AG_RESV_CRITICAL,
> +};
>
> int
> -xfs_error_test(int error_tag, int *fsidp, char *expression,
> - int line, char *file, unsigned long randfactor)
> +xfs_errortag_init(
> + struct xfs_mount *mp)
> {
> - int i;
> - int64_t fsid;
> + mp->m_errortag = kmem_zalloc(sizeof(unsigned int) * XFS_ERRTAG_MAX,
> + KM_SLEEP | KM_MAYFAIL);
> + if (!mp->m_errortag)
> + return -ENOMEM;
> + return 0;
> +}
>
> - if (prandom_u32() % randfactor)
> - return 0;
> +void
> +xfs_errortag_del(
> + struct xfs_mount *mp)
> +{
> + kmem_free(mp->m_errortag);
> +}
>
> - memcpy(&fsid, fsidp, sizeof(xfs_fsid_t));
> +bool
> +xfs_errortag_test(
> + struct xfs_mount *mp,
> + const char *expression,
> + const char *file,
> + int line,
> + unsigned int error_tag)
> +{
> + unsigned int randfactor;
>
> - for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) {
> - if (xfs_etest[i] == error_tag && xfs_etest_fsid[i] == fsid) {
> - xfs_warn(NULL,
> - "Injecting error (%s) at file %s, line %d, on filesystem \"%s\"",
> - expression, file, line, xfs_etest_fsname[i]);
> - return 1;
> - }
> - }
> + ASSERT(error_tag < XFS_ERRTAG_MAX);
> + randfactor = mp->m_errortag[error_tag];
> + if (!randfactor || prandom_u32() % randfactor)
> + return false;
>
> - return 0;
> + xfs_warn_ratelimited(mp,
> +"Injecting error (%s) at file %s, line %d, on filesystem \"%s\"",
> + expression, file, line, mp->m_fsname);
> + return true;
> }
>
> int
> -xfs_errortag_add(unsigned int error_tag, xfs_mount_t *mp)
> +xfs_errortag_set(
> + struct xfs_mount *mp,
> + unsigned int error_tag,
> + unsigned int tag_value)
> {
> - int i;
> - int len;
> - int64_t fsid;
> -
> if (error_tag >= XFS_ERRTAG_MAX)
> return -EINVAL;
>
> - memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t));
> -
> - for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) {
> - if (xfs_etest_fsid[i] == fsid && xfs_etest[i] == error_tag) {
> - xfs_warn(mp, "error tag #%d on", error_tag);
> - return 0;
> - }
> - }
> -
> - for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) {
> - if (xfs_etest[i] == 0) {
> - xfs_warn(mp, "Turned on XFS error tag #%d",
> - error_tag);
> - xfs_etest[i] = error_tag;
> - xfs_etest_fsid[i] = fsid;
> - len = strlen(mp->m_fsname);
> - xfs_etest_fsname[i] = kmem_alloc(len + 1, KM_SLEEP);
> - strcpy(xfs_etest_fsname[i], mp->m_fsname);
> - xfs_error_test_active++;
> - return 0;
> - }
> - }
> -
> - xfs_warn(mp, "error tag overflow, too many turned on");
> -
> - return 1;
> + mp->m_errortag[error_tag] = tag_value;
> + return 0;
> }
>
> int
> -xfs_errortag_clearall(xfs_mount_t *mp, int loud)
> +xfs_errortag_add(
> + struct xfs_mount *mp,
> + unsigned int error_tag)
> {
> - int64_t fsid;
> - int cleared = 0;
> - int i;
> -
> - memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t));
> -
> -
> - for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) {
> - if ((fsid == 0LL || xfs_etest_fsid[i] == fsid) &&
> - xfs_etest[i] != 0) {
> - cleared = 1;
> - xfs_warn(mp, "Clearing XFS error tag #%d",
> - xfs_etest[i]);
> - xfs_etest[i] = 0;
> - xfs_etest_fsid[i] = 0LL;
> - kmem_free(xfs_etest_fsname[i]);
> - xfs_etest_fsname[i] = NULL;
> - xfs_error_test_active--;
> - }
> - }
> + if (error_tag >= XFS_ERRTAG_MAX)
> + return -EINVAL;
>
> - if (loud || cleared)
> - xfs_warn(mp, "Cleared all XFS error tags for filesystem");
> + return xfs_errortag_set(mp, error_tag,
> + xfs_errortag_random_default[error_tag]);
> +}
>
> +int
> +xfs_errortag_clearall(
> + struct xfs_mount *mp)
> +{
> + memset(mp->m_errortag, 0, sizeof(unsigned int) * XFS_ERRTAG_MAX);
> return 0;
> }
> #endif /* DEBUG */
> diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h
> index 05f8666..b4316d3 100644
> --- a/fs/xfs/xfs_error.h
> +++ b/fs/xfs/xfs_error.h
> @@ -131,21 +131,24 @@ extern void xfs_verifier_error(struct xfs_buf *bp);
> #define XFS_RANDOM_AG_RESV_CRITICAL 4
>
> #ifdef DEBUG
> -extern int xfs_error_test_active;
> -extern int xfs_error_test(int, int *, char *, int, char *, unsigned long);
> -
> -#define XFS_NUM_INJECT_ERROR 10
> +extern int xfs_errortag_init(struct xfs_mount *mp);
> +extern void xfs_errortag_del(struct xfs_mount *mp);
> +extern bool xfs_errortag_test(struct xfs_mount *mp, const char *expression,
> + const char *file, int line, unsigned int error_tag);
> #define XFS_TEST_ERROR(expr, mp, tag, rf) \
> - ((expr) || (xfs_error_test_active && \
> - xfs_error_test((tag), (mp)->m_fixedfsid, "expr", __LINE__, __FILE__, \
> - (rf))))
> + ((expr) || xfs_errortag_test((mp), #expr, __FILE__, __LINE__, (tag)))
>
> -extern int xfs_errortag_add(unsigned int error_tag, struct xfs_mount *mp);
> -extern int xfs_errortag_clearall(struct xfs_mount *mp, int loud);
> +extern int xfs_errortag_set(struct xfs_mount *mp, unsigned int error_tag,
> + unsigned int tag_value);
> +extern int xfs_errortag_add(struct xfs_mount *mp, unsigned int error_tag);
> +extern int xfs_errortag_clearall(struct xfs_mount *mp);
> #else
> +#define xfs_errortag_init(mp) (0)
> +#define xfs_errortag_del(mp)
> #define XFS_TEST_ERROR(expr, mp, tag, rf) (expr)
> -#define xfs_errortag_add(tag, mp) (ENOSYS)
> -#define xfs_errortag_clearall(mp, loud) (ENOSYS)
> +#define xfs_errortag_set(mp, tag, val) (ENOSYS)
> +#define xfs_errortag_add(mp, tag) (ENOSYS)
> +#define xfs_errortag_clearall(mp) (ENOSYS)
> #endif /* DEBUG */
>
> /*
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index 8ffe4ea..9c0c7a9 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -2037,14 +2037,14 @@ xfs_file_ioctl(
> if (copy_from_user(&in, arg, sizeof(in)))
> return -EFAULT;
>
> - return xfs_errortag_add(in.errtag, mp);
> + return xfs_errortag_add(mp, in.errtag);
> }
>
> case XFS_IOC_ERROR_CLEARALL:
> if (!capable(CAP_SYS_ADMIN))
> return -EPERM;
>
> - return xfs_errortag_clearall(mp, 1);
> + return xfs_errortag_clearall(mp);
>
> case XFS_IOC_FREE_EOFBLOCKS: {
> struct xfs_fs_eofblocks eofb;
> diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
> index cc6789d..1a98c35 100644
> --- a/fs/xfs/xfs_mount.c
> +++ b/fs/xfs/xfs_mount.c
> @@ -720,10 +720,13 @@ xfs_mountfs(
> if (error)
> goto out_del_stats;
>
> + error = xfs_errortag_init(mp);
> + if (error)
> + goto out_remove_error_sysfs;
>
> error = xfs_uuid_mount(mp);
> if (error)
> - goto out_remove_error_sysfs;
> + goto out_remove_errortag;
>
> /*
> * Set the minimum read and write sizes
> @@ -1042,6 +1045,8 @@ xfs_mountfs(
> xfs_da_unmount(mp);
> out_remove_uuid:
> xfs_uuid_unmount(mp);
> + out_remove_errortag:
> + xfs_errortag_del(mp);
> out_remove_error_sysfs:
> xfs_error_sysfs_del(mp);
> out_del_stats:
> @@ -1145,10 +1150,11 @@ xfs_unmountfs(
> xfs_uuid_unmount(mp);
>
> #if defined(DEBUG)
> - xfs_errortag_clearall(mp, 0);
> + xfs_errortag_clearall(mp);
> #endif
> xfs_free_perag(mp);
>
> + xfs_errortag_del(mp);
> xfs_error_sysfs_del(mp);
> xfs_sysfs_del(&mp->m_stats.xs_kobj);
> xfs_sysfs_del(&mp->m_kobj);
> diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> index 305d953..e002ac5 100644
> --- a/fs/xfs/xfs_mount.h
> +++ b/fs/xfs/xfs_mount.h
> @@ -199,6 +199,13 @@ typedef struct xfs_mount {
> bool m_fail_unmount;
> #ifdef DEBUG
> /*
> + * Frequency with which errors are injected. Replaces xfs_etest; the
> + * value stored in here is the inverse of the frequency with which the
> + * error triggers. 1 = always, 2 = half the time, etc.
> + */
> + unsigned int *m_errortag;
> +
> + /*
> * 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.
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2017-06-26 11:10 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-23 16:35 [PATCH v2 0/4] xfs: more configurable error injection Darrick J. Wong
2017-06-23 16:35 ` [PATCH 1/4] xfs: make errortag a per-mountpoint structure Darrick J. Wong
2017-06-26 11:10 ` Brian Foster [this message]
2017-06-27 7:35 ` Carlos Maiolino
2017-06-23 16:35 ` [PATCH 2/4] xfs: expose errortag knobs via sysfs Darrick J. Wong
2017-06-26 11:10 ` Brian Foster
2017-06-27 10:26 ` Carlos Maiolino
2017-06-23 16:35 ` [PATCH 3/4] xfs: remove unneeded parameter from XFS_TEST_ERROR Darrick J. Wong
2017-06-27 10:33 ` Carlos Maiolino
2017-06-23 16:35 ` [PATCH 4/4] xfs: convert drop_writes to use the errortag mechanism Darrick J. Wong
2017-06-27 10:51 ` Carlos Maiolino
2017-06-27 12:35 ` [PATCH] xfs: replace log_badcrc_factor knob with error injection tag Brian Foster
2017-06-27 16:51 ` Darrick J. Wong
-- strict thread matches above, loose matches on Subject: below --
2017-06-21 1:11 [RFC PATCH 0/4] xfs: more configurable error injection Darrick J. Wong
2017-06-21 1:11 ` [PATCH 1/4] xfs: make errortag a per-mountpoint structure Darrick J. Wong
2017-06-21 18:18 ` Brian Foster
2017-06-21 18:46 ` Darrick J. Wong
2017-06-21 19:05 ` Brian Foster
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170626111050.GA54427@bfoster.bfoster \
--to=bfoster@redhat.com \
--cc=darrick.wong@oracle.com \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).