FS/XFS testing framework
 help / color / mirror / Atom feed
From: Anand Jain <anand.jain@oracle.com>
To: fdmanana@kernel.org, fstests@vger.kernel.org
Cc: linux-btrfs@vger.kernel.org, Filipe Manana <fdmanana@suse.com>
Subject: Re: [PATCH] generic: test concurrent direct IO writes and fsync using same fd
Date: Tue, 3 Sep 2024 20:42:52 +0800	[thread overview]
Message-ID: <99345f2f-250a-4717-863c-d61d573b08cb@oracle.com> (raw)
In-Reply-To: <fa20c58b1a711d9da9899b895a5237f8737163af.1724972803.git.fdmanana@suse.com>

On 30/8/24 7:10 am, fdmanana@kernel.org wrote:
> From: Filipe Manana <fdmanana@suse.com>
> 
> Test that a program that has 2 threads using the same file descriptor and
> concurrently doing direct IO writes and fsync doesn't trigger any crash
> or deadlock.
> 
> This is motivated by a bug found in btrfs fixed by the following patch:
> 
>    "btrfs: fix race between direct IO write and fsync when using same fd"
> 
> Signed-off-by: Filipe Manana <fdmanana@suse.com>
> ---

-----------------------------
FSTYP         -- btrfs
PLATFORM      -- Linux/aarch64 dev2 6.11.0-rc5+ #7 SMP PREEMPT_DYNAMIC 
Mon Sep  2 18:46:19 +08 2024
MKFS_OPTIONS  -- /dev/loop1
MOUNT_OPTIONS -- /dev/loop1 /mnt/scratch

generic/363 10s ... umount: /mnt/test: target is busy.
_check_btrfs_filesystem: filesystem on /dev/loop0 is inconsistent
(see /Volumes/work/ws/fstests/results//generic/363.full for details)
Trying to repair broken TEST_DEV file system
_check_dmesg: something found in dmesg (see 
/Volumes/work/ws/fstests/results//generic/363.dmesg)
-----------------------------


I managed to reproduce it in two iterations.

For now, the test case is fine as it is without the require_debug part,
since it doesn’t always reproduce every time even with it.

Reviewed-by: Anand Jain <anand.jain@oracle.com>

Thanks, Anand



>   .gitignore                    |   1 +
>   src/Makefile                  |   2 +-
>   src/dio-write-fsync-same-fd.c | 106 ++++++++++++++++++++++++++++++++++
>   tests/generic/363             |  30 ++++++++++
>   tests/generic/363.out         |   2 +
>   5 files changed, 140 insertions(+), 1 deletion(-)
>   create mode 100644 src/dio-write-fsync-same-fd.c
>   create mode 100755 tests/generic/363
>   create mode 100644 tests/generic/363.out
> 
> diff --git a/.gitignore b/.gitignore
> index 36083e9d..57519263 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -76,6 +76,7 @@ tags
>   /src/dio-buf-fault
>   /src/dio-interleaved
>   /src/dio-invalidate-cache
> +/src/dio-write-fsync-same-fd
>   /src/dirhash_collide
>   /src/dirperf
>   /src/dirstress
> diff --git a/src/Makefile b/src/Makefile
> index b3da59a0..b9ad6b5f 100644
> --- a/src/Makefile
> +++ b/src/Makefile
> @@ -20,7 +20,7 @@ TARGETS = dirstress fill fill2 getpagesize holes lstat64 \
>   	t_get_file_time t_create_short_dirs t_create_long_dirs t_enospc \
>   	t_mmap_writev_overlap checkpoint_journal mmap-rw-fault allocstale \
>   	t_mmap_cow_memory_failure fake-dump-rootino dio-buf-fault rewinddir-test \
> -	readdir-while-renames dio-append-buf-fault
> +	readdir-while-renames dio-append-buf-fault dio-write-fsync-same-fd
>   
>   LINUX_TARGETS = xfsctl bstat t_mtab getdevicesize preallo_rw_pattern_reader \
>   	preallo_rw_pattern_writer ftrunc trunc fs_perms testx looptest \
> diff --git a/src/dio-write-fsync-same-fd.c b/src/dio-write-fsync-same-fd.c
> new file mode 100644
> index 00000000..79472a9e
> --- /dev/null
> +++ b/src/dio-write-fsync-same-fd.c
> @@ -0,0 +1,106 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2024 SUSE Linux Products GmbH.  All Rights Reserved.
> + */
> +
> +/*
> + * Test two threads working with the same file descriptor, one doing direct IO
> + * writes into the file and the other just doing fsync calls. We want to verify
> + * that there are no crashes or deadlocks.
> + *
> + * This program never finishes, it starts two infinite loops to write and fsync
> + * the file. It's meant to be called with the 'timeout' program from coreutils.
> + */
> +
> +/* Get the O_DIRECT definition. */
> +#ifndef _GNU_SOURCE
> +#define _GNU_SOURCE
> +#endif
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <stdint.h>
> +#include <fcntl.h>
> +#include <errno.h>
> +#include <string.h>
> +#include <pthread.h>
> +
> +static int fd;
> +
> +static ssize_t do_write(int fd, const void *buf, size_t count, off_t offset)
> +{
> +        while (count > 0) {
> +		ssize_t ret;
> +
> +		ret = pwrite(fd, buf, count, offset);
> +		if (ret < 0) {
> +			if (errno == EINTR)
> +				continue;
> +			return ret;
> +		}
> +		count -= ret;
> +		buf += ret;
> +	}
> +	return 0;
> +}
> +
> +static void *fsync_loop(void *arg)
> +{
> +	while (1) {
> +		int ret;
> +
> +		ret = fsync(fd);
> +		if (ret != 0) {
> +			perror("Fsync failed");
> +			exit(6);
> +		}
> +	}
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	long pagesize;
> +	void *write_buf;
> +	pthread_t fsyncer;
> +	int ret;
> +
> +	if (argc != 2) {
> +		fprintf(stderr, "Use: %s <file path>\n", argv[0]);
> +		return 1;
> +	}
> +
> +	fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC | O_DIRECT, 0666);
> +	if (fd == -1) {
> +		perror("Failed to open/create file");
> +		return 1;
> +	}
> +
> +	pagesize = sysconf(_SC_PAGE_SIZE);
> +	if (pagesize == -1) {
> +		perror("Failed to get page size");
> +		return 2;
> +	}
> +
> +	ret = posix_memalign(&write_buf, pagesize, pagesize);
> +	if (ret) {
> +		perror("Failed to allocate buffer");
> +		return 3;
> +	}
> +
> +	ret = pthread_create(&fsyncer, NULL, fsync_loop, NULL);
> +	if (ret != 0) {
> +		fprintf(stderr, "Failed to create writer thread: %d\n", ret);
> +		return 4;
> +	}
> +
> +	while (1) {
> +		ret = do_write(fd, write_buf, pagesize, 0);
> +		if (ret != 0) {
> +			perror("Write failed");
> +			exit(5);
> +		}
> +	}
> +
> +	return 0;
> +}
> diff --git a/tests/generic/363 b/tests/generic/363
> new file mode 100755
> index 00000000..21159e24
> --- /dev/null
> +++ b/tests/generic/363
> @@ -0,0 +1,30 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (C) 2024 SUSE Linux Products GmbH. All Rights Reserved.
> +#
> +# FS QA Test 363
> +#
> +# Test that a program that has 2 threads using the same file descriptor and
> +# concurrently doing direct IO writes and fsync doesn't trigger any crash or
> +# deadlock.
> +#
> +. ./common/preamble
> +_begin_fstest auto quick
> +
> +_require_test
> +_require_odirect
> +_require_test_program dio-write-fsync-same-fd
> +_require_command "$TIMEOUT_PROG" timeout
> +
> +[ $FSTYP == "btrfs" ] && \
> +	_fixed_by_kernel_commit xxxxxxxxxxxx \
> +	"btrfs: fix race between direct IO write and fsync when using same fd"
> +
> +# On error the test program writes messages to stderr, causing a golden output
> +# mismatch and making the test fail.
> +$TIMEOUT_PROG 10s $here/src/dio-write-fsync-same-fd $TEST_DIR/dio-write-fsync-same-fd
> +
> +# success, all done
> +echo "Silence is golden"
> +status=0
> +exit
> diff --git a/tests/generic/363.out b/tests/generic/363.out
> new file mode 100644
> index 00000000..d03d2dc2
> --- /dev/null
> +++ b/tests/generic/363.out
> @@ -0,0 +1,2 @@
> +QA output created by 363
> +Silence is golden


      parent reply	other threads:[~2024-09-03 12:43 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-29 23:10 [PATCH] generic: test concurrent direct IO writes and fsync using same fd fdmanana
2024-09-02 20:28 ` Zorro Lang
2024-09-02 21:45   ` Filipe Manana
2024-09-03  4:09     ` Zorro Lang
2024-09-03  9:41       ` Filipe Manana
2024-09-03 10:02         ` Qu Wenruo
2024-09-04 11:13         ` Zorro Lang
2024-09-04 14:18           ` Filipe Manana
2024-09-03 12:42 ` Anand Jain [this message]

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=99345f2f-250a-4717-863c-d61d573b08cb@oracle.com \
    --to=anand.jain@oracle.com \
    --cc=fdmanana@kernel.org \
    --cc=fdmanana@suse.com \
    --cc=fstests@vger.kernel.org \
    --cc=linux-btrfs@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