* [PATCH 1/6] generic/765: fix a few issues
2025-05-14 0:29 [PATCH 0/6] atomic writes tests Catherine Hoang
@ 2025-05-14 0:29 ` Catherine Hoang
2025-05-14 12:47 ` John Garry
2025-05-17 3:17 ` Ritesh Harjani
2025-05-14 0:29 ` [PATCH 2/6] generic/765: adjust various things Catherine Hoang
` (4 subsequent siblings)
5 siblings, 2 replies; 29+ messages in thread
From: Catherine Hoang @ 2025-05-14 0:29 UTC (permalink / raw)
To: linux-xfs, fstests; +Cc: djwong, john.g.garry
From: "Darrick J. Wong" <djwong@kernel.org>
Fix a few bugs in the single block atomic writes test, such as requiring
directio, using page size for the ext4 max bsize, and making sure we check
the max atomic write size.
Cc: ritesh.list@gmail.com
Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
common/rc | 2 +-
tests/generic/765 | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/common/rc b/common/rc
index 657772e7..bc8dabc5 100644
--- a/common/rc
+++ b/common/rc
@@ -2989,7 +2989,7 @@ _require_xfs_io_command()
fi
if [ "$param" == "-A" ]; then
opts+=" -d"
- pwrite_opts+="-D -V 1 -b 4k"
+ pwrite_opts+="-d -V 1 -b 4k"
fi
testio=`$XFS_IO_PROG -f $opts -c \
"pwrite $pwrite_opts $param 0 4k" $testfile 2>&1`
diff --git a/tests/generic/765 b/tests/generic/765
index 9bab3b8a..8695a306 100755
--- a/tests/generic/765
+++ b/tests/generic/765
@@ -28,7 +28,7 @@ get_supported_bsize()
;;
"ext4")
min_bsize=1024
- max_bsize=4096
+ max_bsize=$(_get_page_size)
;;
*)
_notrun "$FSTYP does not support atomic writes"
@@ -73,7 +73,7 @@ test_atomic_writes()
# Check that atomic min/max = FS block size
test $file_min_write -eq $bsize || \
echo "atomic write min $file_min_write, should be fs block size $bsize"
- test $file_min_write -eq $bsize || \
+ test $file_max_write -eq $bsize || \
echo "atomic write max $file_max_write, should be fs block size $bsize"
test $file_max_segments -eq 1 || \
echo "atomic write max segments $file_max_segments, should be 1"
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH 1/6] generic/765: fix a few issues
2025-05-14 0:29 ` [PATCH 1/6] generic/765: fix a few issues Catherine Hoang
@ 2025-05-14 12:47 ` John Garry
2025-05-14 15:38 ` Darrick J. Wong
2025-05-17 3:17 ` Ritesh Harjani
1 sibling, 1 reply; 29+ messages in thread
From: John Garry @ 2025-05-14 12:47 UTC (permalink / raw)
To: Catherine Hoang, linux-xfs, fstests; +Cc: djwong
On 14/05/2025 01:29, Catherine Hoang wrote:
> From: "Darrick J. Wong" <djwong@kernel.org>
>
> Fix a few bugs in the single block atomic writes test, such as requiring
> directio, using page size for the ext4 max bsize, and making sure we check
> the max atomic write size.
>
> Cc: ritesh.list@gmail.com
> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> ---
> common/rc | 2 +-
> tests/generic/765 | 4 ++--
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/common/rc b/common/rc
> index 657772e7..bc8dabc5 100644
> --- a/common/rc
> +++ b/common/rc
> @@ -2989,7 +2989,7 @@ _require_xfs_io_command()
> fi
> if [ "$param" == "-A" ]; then
> opts+=" -d"
> - pwrite_opts+="-D -V 1 -b 4k"
> + pwrite_opts+="-d -V 1 -b 4k"
according to the documentation for -b, 4096 is the default (so I don't
think that we need to set it explicitly). But is that flag even relevant
to pwritev2?
And setting -d in pwrite_opts means DIO for the input file, right? I am
not sure if that is required.
> fi
> testio=`$XFS_IO_PROG -f $opts -c \
> "pwrite $pwrite_opts $param 0 4k" $testfile 2>&1`
> diff --git a/tests/generic/765 b/tests/generic/765
> index 9bab3b8a..8695a306 100755
> --- a/tests/generic/765
> +++ b/tests/generic/765
> @@ -28,7 +28,7 @@ get_supported_bsize()
> ;;
> "ext4")
> min_bsize=1024
> - max_bsize=4096
> + max_bsize=$(_get_page_size)
looks ok
> ;;
> *)
> _notrun "$FSTYP does not support atomic writes"
> @@ -73,7 +73,7 @@ test_atomic_writes()
> # Check that atomic min/max = FS block size
> test $file_min_write -eq $bsize || \
> echo "atomic write min $file_min_write, should be fs block size $bsize"
> - test $file_min_write -eq $bsize || \
> + test $file_max_write -eq $bsize || \
looks ok
> echo "atomic write max $file_max_write, should be fs block size $bsize"
> test $file_max_segments -eq 1 || \
> echo "atomic write max segments $file_max_segments, should be 1"
Thanks,
John
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/6] generic/765: fix a few issues
2025-05-14 12:47 ` John Garry
@ 2025-05-14 15:38 ` Darrick J. Wong
2025-05-14 23:42 ` Catherine Hoang
2025-05-15 8:16 ` John Garry
0 siblings, 2 replies; 29+ messages in thread
From: Darrick J. Wong @ 2025-05-14 15:38 UTC (permalink / raw)
To: John Garry; +Cc: Catherine Hoang, linux-xfs, fstests
On Wed, May 14, 2025 at 01:47:20PM +0100, John Garry wrote:
> On 14/05/2025 01:29, Catherine Hoang wrote:
> > From: "Darrick J. Wong" <djwong@kernel.org>
> >
> > Fix a few bugs in the single block atomic writes test, such as requiring
> > directio, using page size for the ext4 max bsize, and making sure we check
> > the max atomic write size.
> >
> > Cc: ritesh.list@gmail.com
> > Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> > Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
> > Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> > ---
> > common/rc | 2 +-
> > tests/generic/765 | 4 ++--
> > 2 files changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/common/rc b/common/rc
> > index 657772e7..bc8dabc5 100644
> > --- a/common/rc
> > +++ b/common/rc
> > @@ -2989,7 +2989,7 @@ _require_xfs_io_command()
> > fi
> > if [ "$param" == "-A" ]; then
> > opts+=" -d"
> > - pwrite_opts+="-D -V 1 -b 4k"
> > + pwrite_opts+="-d -V 1 -b 4k"
>
> according to the documentation for -b, 4096 is the default (so I don't think
> that we need to set it explicitly). But is that flag even relevant to
> pwritev2?
The documentation is wrong -- on XFS the default is the fs blocksize.
Everywhere else is 4k.
> And setting -d in pwrite_opts means DIO for the input file, right? I am not
> sure if that is required.
It's not required, I mistook where that "-d" goes -- -d as an argument
to xfs_io is necessary, but -d as an argument to the pwrite subcommand
is not. It's also benign since we don't pass -i.
Curiously the version of this patch in my tree doesn't have the extra
-d... I wonder if I made that change and forgot to send it out.
--D
> > fi
> > testio=`$XFS_IO_PROG -f $opts -c \
> > "pwrite $pwrite_opts $param 0 4k" $testfile 2>&1`
> > diff --git a/tests/generic/765 b/tests/generic/765
> > index 9bab3b8a..8695a306 100755
> > --- a/tests/generic/765
> > +++ b/tests/generic/765
> > @@ -28,7 +28,7 @@ get_supported_bsize()
> > ;;
> > "ext4")
> > min_bsize=1024
> > - max_bsize=4096
> > + max_bsize=$(_get_page_size)
>
> looks ok
>
> > ;;
> > *)
> > _notrun "$FSTYP does not support atomic writes"
> > @@ -73,7 +73,7 @@ test_atomic_writes()
> > # Check that atomic min/max = FS block size
> > test $file_min_write -eq $bsize || \
> > echo "atomic write min $file_min_write, should be fs block size $bsize"
> > - test $file_min_write -eq $bsize || \
> > + test $file_max_write -eq $bsize || \
>
> looks ok
>
> > echo "atomic write max $file_max_write, should be fs block size $bsize"
> > test $file_max_segments -eq 1 || \
> > echo "atomic write max segments $file_max_segments, should be 1"
>
>
> Thanks,
> John
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/6] generic/765: fix a few issues
2025-05-14 15:38 ` Darrick J. Wong
@ 2025-05-14 23:42 ` Catherine Hoang
2025-05-15 1:47 ` Darrick J. Wong
2025-05-15 8:16 ` John Garry
1 sibling, 1 reply; 29+ messages in thread
From: Catherine Hoang @ 2025-05-14 23:42 UTC (permalink / raw)
To: Darrick J. Wong
Cc: John Garry, linux-xfs@vger.kernel.org, fstests@vger.kernel.org
> On May 14, 2025, at 8:38 AM, Darrick J. Wong <djwong@kernel.org> wrote:
>
> On Wed, May 14, 2025 at 01:47:20PM +0100, John Garry wrote:
>> On 14/05/2025 01:29, Catherine Hoang wrote:
>>> From: "Darrick J. Wong" <djwong@kernel.org>
>>>
>>> Fix a few bugs in the single block atomic writes test, such as requiring
>>> directio, using page size for the ext4 max bsize, and making sure we check
>>> the max atomic write size.
>>>
>>> Cc: ritesh.list@gmail.com
>>> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
>>> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
>>> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
>>> ---
>>> common/rc | 2 +-
>>> tests/generic/765 | 4 ++--
>>> 2 files changed, 3 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/common/rc b/common/rc
>>> index 657772e7..bc8dabc5 100644
>>> --- a/common/rc
>>> +++ b/common/rc
>>> @@ -2989,7 +2989,7 @@ _require_xfs_io_command()
>>> fi
>>> if [ "$param" == "-A" ]; then
>>> opts+=" -d"
>>> - pwrite_opts+="-D -V 1 -b 4k"
>>> + pwrite_opts+="-d -V 1 -b 4k"
>>
>> according to the documentation for -b, 4096 is the default (so I don't think
>> that we need to set it explicitly). But is that flag even relevant to
>> pwritev2?
>
> The documentation is wrong -- on XFS the default is the fs blocksize.
> Everywhere else is 4k.
>
>> And setting -d in pwrite_opts means DIO for the input file, right? I am not
>> sure if that is required.
>
> It's not required, I mistook where that "-d" goes -- -d as an argument
> to xfs_io is necessary, but -d as an argument to the pwrite subcommand
> is not. It's also benign since we don't pass -i.
>
> Curiously the version of this patch in my tree doesn't have the extra
> -d... I wonder if I made that change and forgot to send it out.
Hmm, it might have been from an old patch on my branch
that I forgot to update when I sent this out. Just to clarify,
this should just be
pwrite_opts+="-V 1 -b 4k”
right?
>
> --D
>
>>> fi
>>> testio=`$XFS_IO_PROG -f $opts -c \
>>> "pwrite $pwrite_opts $param 0 4k" $testfile 2>&1`
>>> diff --git a/tests/generic/765 b/tests/generic/765
>>> index 9bab3b8a..8695a306 100755
>>> --- a/tests/generic/765
>>> +++ b/tests/generic/765
>>> @@ -28,7 +28,7 @@ get_supported_bsize()
>>> ;;
>>> "ext4")
>>> min_bsize=1024
>>> - max_bsize=4096
>>> + max_bsize=$(_get_page_size)
>>
>> looks ok
>>
>>> ;;
>>> *)
>>> _notrun "$FSTYP does not support atomic writes"
>>> @@ -73,7 +73,7 @@ test_atomic_writes()
>>> # Check that atomic min/max = FS block size
>>> test $file_min_write -eq $bsize || \
>>> echo "atomic write min $file_min_write, should be fs block size $bsize"
>>> - test $file_min_write -eq $bsize || \
>>> + test $file_max_write -eq $bsize || \
>>
>> looks ok
>>
>>> echo "atomic write max $file_max_write, should be fs block size $bsize"
>>> test $file_max_segments -eq 1 || \
>>> echo "atomic write max segments $file_max_segments, should be 1"
>>
>>
>> Thanks,
>> John
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/6] generic/765: fix a few issues
2025-05-14 23:42 ` Catherine Hoang
@ 2025-05-15 1:47 ` Darrick J. Wong
0 siblings, 0 replies; 29+ messages in thread
From: Darrick J. Wong @ 2025-05-15 1:47 UTC (permalink / raw)
To: Catherine Hoang
Cc: John Garry, linux-xfs@vger.kernel.org, fstests@vger.kernel.org
On Wed, May 14, 2025 at 11:42:40PM +0000, Catherine Hoang wrote:
> > On May 14, 2025, at 8:38 AM, Darrick J. Wong <djwong@kernel.org> wrote:
> >
> > On Wed, May 14, 2025 at 01:47:20PM +0100, John Garry wrote:
> >> On 14/05/2025 01:29, Catherine Hoang wrote:
> >>> From: "Darrick J. Wong" <djwong@kernel.org>
> >>>
> >>> Fix a few bugs in the single block atomic writes test, such as requiring
> >>> directio, using page size for the ext4 max bsize, and making sure we check
> >>> the max atomic write size.
> >>>
> >>> Cc: ritesh.list@gmail.com
> >>> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> >>> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
> >>> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> >>> ---
> >>> common/rc | 2 +-
> >>> tests/generic/765 | 4 ++--
> >>> 2 files changed, 3 insertions(+), 3 deletions(-)
> >>>
> >>> diff --git a/common/rc b/common/rc
> >>> index 657772e7..bc8dabc5 100644
> >>> --- a/common/rc
> >>> +++ b/common/rc
> >>> @@ -2989,7 +2989,7 @@ _require_xfs_io_command()
> >>> fi
> >>> if [ "$param" == "-A" ]; then
> >>> opts+=" -d"
> >>> - pwrite_opts+="-D -V 1 -b 4k"
> >>> + pwrite_opts+="-d -V 1 -b 4k"
> >>
> >> according to the documentation for -b, 4096 is the default (so I don't think
> >> that we need to set it explicitly). But is that flag even relevant to
> >> pwritev2?
> >
> > The documentation is wrong -- on XFS the default is the fs blocksize.
> > Everywhere else is 4k.
> >
> >> And setting -d in pwrite_opts means DIO for the input file, right? I am not
> >> sure if that is required.
> >
> > It's not required, I mistook where that "-d" goes -- -d as an argument
> > to xfs_io is necessary, but -d as an argument to the pwrite subcommand
> > is not. It's also benign since we don't pass -i.
> >
> > Curiously the version of this patch in my tree doesn't have the extra
> > -d... I wonder if I made that change and forgot to send it out.
>
> Hmm, it might have been from an old patch on my branch
> that I forgot to update when I sent this out. Just to clarify,
> this should just be
>
> pwrite_opts+="-V 1 -b 4k”
>
> right?
Yep.
--D
> > --D
> >
> >>> fi
> >>> testio=`$XFS_IO_PROG -f $opts -c \
> >>> "pwrite $pwrite_opts $param 0 4k" $testfile 2>&1`
> >>> diff --git a/tests/generic/765 b/tests/generic/765
> >>> index 9bab3b8a..8695a306 100755
> >>> --- a/tests/generic/765
> >>> +++ b/tests/generic/765
> >>> @@ -28,7 +28,7 @@ get_supported_bsize()
> >>> ;;
> >>> "ext4")
> >>> min_bsize=1024
> >>> - max_bsize=4096
> >>> + max_bsize=$(_get_page_size)
> >>
> >> looks ok
> >>
> >>> ;;
> >>> *)
> >>> _notrun "$FSTYP does not support atomic writes"
> >>> @@ -73,7 +73,7 @@ test_atomic_writes()
> >>> # Check that atomic min/max = FS block size
> >>> test $file_min_write -eq $bsize || \
> >>> echo "atomic write min $file_min_write, should be fs block size $bsize"
> >>> - test $file_min_write -eq $bsize || \
> >>> + test $file_max_write -eq $bsize || \
> >>
> >> looks ok
> >>
> >>> echo "atomic write max $file_max_write, should be fs block size $bsize"
> >>> test $file_max_segments -eq 1 || \
> >>> echo "atomic write max segments $file_max_segments, should be 1"
> >>
> >>
> >> Thanks,
> >> John
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/6] generic/765: fix a few issues
2025-05-14 15:38 ` Darrick J. Wong
2025-05-14 23:42 ` Catherine Hoang
@ 2025-05-15 8:16 ` John Garry
2025-05-15 14:54 ` Darrick J. Wong
1 sibling, 1 reply; 29+ messages in thread
From: John Garry @ 2025-05-15 8:16 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: Catherine Hoang, linux-xfs, fstests
On 14/05/2025 16:38, Darrick J. Wong wrote:
>>> --- a/common/rc
>>> +++ b/common/rc
>>> @@ -2989,7 +2989,7 @@ _require_xfs_io_command()
>>> fi
>>> if [ "$param" == "-A" ]; then
>>> opts+=" -d"
>>> - pwrite_opts+="-D -V 1 -b 4k"
>>> + pwrite_opts+="-d -V 1 -b 4k"
>> according to the documentation for -b, 4096 is the default (so I don't think
>> that we need to set it explicitly). But is that flag even relevant to
>> pwritev2?
> The documentation is wrong -- on XFS the default is the fs blocksize.
> Everywhere else is 4k.
Right, I see that in init_cvtnum()
However, from checking write_buffer(), we seem to split writes on this
blocksize - that does not seem proper in this instance.
Should we really be doing something like:
xfs_io -d -C "pwrite -b $SIZE -V 1 -A -D 0 $SIZE" file
Thanks,
John
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/6] generic/765: fix a few issues
2025-05-15 8:16 ` John Garry
@ 2025-05-15 14:54 ` Darrick J. Wong
2025-05-15 17:57 ` John Garry
0 siblings, 1 reply; 29+ messages in thread
From: Darrick J. Wong @ 2025-05-15 14:54 UTC (permalink / raw)
To: John Garry; +Cc: Catherine Hoang, linux-xfs, fstests
On Thu, May 15, 2025 at 09:16:12AM +0100, John Garry wrote:
> On 14/05/2025 16:38, Darrick J. Wong wrote:
> > > > --- a/common/rc
> > > > +++ b/common/rc
> > > > @@ -2989,7 +2989,7 @@ _require_xfs_io_command()
> > > > fi
> > > > if [ "$param" == "-A" ]; then
> > > > opts+=" -d"
> > > > - pwrite_opts+="-D -V 1 -b 4k"
> > > > + pwrite_opts+="-d -V 1 -b 4k"
> > > according to the documentation for -b, 4096 is the default (so I don't think
> > > that we need to set it explicitly). But is that flag even relevant to
> > > pwritev2?
> > The documentation is wrong -- on XFS the default is the fs blocksize.
> > Everywhere else is 4k.
>
> Right, I see that in init_cvtnum()
>
> However, from checking write_buffer(), we seem to split writes on this
> blocksize - that does not seem proper in this instance.
>
> Should we really be doing something like:
>
> xfs_io -d -C "pwrite -b $SIZE -V 1 -A -D 0 $SIZE" file
In _require_xfs_io_command? That only writes the first 4k of a file, so
matching buffer size is ok.
Are you asking if _require_xfs_io_command should seek out the filesystem
block size, and use that for the buffer and write size arguments instead
of hardcoding 4k? For atomic writes, maybe it should be doing this,
since the fs blocksize could be 64k.
--D
> Thanks,
> John
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/6] generic/765: fix a few issues
2025-05-15 14:54 ` Darrick J. Wong
@ 2025-05-15 17:57 ` John Garry
2025-05-15 21:50 ` Catherine Hoang
0 siblings, 1 reply; 29+ messages in thread
From: John Garry @ 2025-05-15 17:57 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: Catherine Hoang, linux-xfs, fstests
On 15/05/2025 15:54, Darrick J. Wong wrote:
> On Thu, May 15, 2025 at 09:16:12AM +0100, John Garry wrote:
>> On 14/05/2025 16:38, Darrick J. Wong wrote:
>>>>> --- a/common/rc
>>>>> +++ b/common/rc
>>>>> @@ -2989,7 +2989,7 @@ _require_xfs_io_command()
>>>>> fi
>>>>> if [ "$param" == "-A" ]; then
>>>>> opts+=" -d"
>>>>> - pwrite_opts+="-D -V 1 -b 4k"
>>>>> + pwrite_opts+="-d -V 1 -b 4k"
>>>> according to the documentation for -b, 4096 is the default (so I don't think
>>>> that we need to set it explicitly). But is that flag even relevant to
>>>> pwritev2?
>>> The documentation is wrong -- on XFS the default is the fs blocksize.
>>> Everywhere else is 4k.
>>
>> Right, I see that in init_cvtnum()
>>
>> However, from checking write_buffer(), we seem to split writes on this
>> blocksize - that does not seem proper in this instance.
>>
>> Should we really be doing something like:
>>
>> xfs_io -d -C "pwrite -b $SIZE -V 1 -A -D 0 $SIZE" file
>
> In _require_xfs_io_command? That only writes the first 4k of a file, so
> matching buffer size is ok.
right, I missed that. The usage in _require_xfs_io_command looks ok.
>
> Are you asking if _require_xfs_io_command should seek out the filesystem
> block size, and use that for the buffer and write size arguments instead
> of hardcoding 4k? For atomic writes, maybe it should be doing this,
> since the fs blocksize could be 64k.
>
I was just a bit thrown by how we need to specify -b $size with -A to
actually write $size atomically.
Thanks,
John
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/6] generic/765: fix a few issues
2025-05-15 17:57 ` John Garry
@ 2025-05-15 21:50 ` Catherine Hoang
2025-05-16 6:59 ` John Garry
0 siblings, 1 reply; 29+ messages in thread
From: Catherine Hoang @ 2025-05-15 21:50 UTC (permalink / raw)
To: John Garry
Cc: Darrick J. Wong, linux-xfs@vger.kernel.org,
fstests@vger.kernel.org
> On May 15, 2025, at 10:57 AM, John Garry <john.g.garry@oracle.com> wrote:
>
> On 15/05/2025 15:54, Darrick J. Wong wrote:
>> On Thu, May 15, 2025 at 09:16:12AM +0100, John Garry wrote:
>>> On 14/05/2025 16:38, Darrick J. Wong wrote:
>>>>>> --- a/common/rc
>>>>>> +++ b/common/rc
>>>>>> @@ -2989,7 +2989,7 @@ _require_xfs_io_command()
>>>>>> fi
>>>>>> if [ "$param" == "-A" ]; then
>>>>>> opts+=" -d"
>>>>>> - pwrite_opts+="-D -V 1 -b 4k"
>>>>>> + pwrite_opts+="-d -V 1 -b 4k"
>>>>> according to the documentation for -b, 4096 is the default (so I don't think
>>>>> that we need to set it explicitly). But is that flag even relevant to
>>>>> pwritev2?
>>>> The documentation is wrong -- on XFS the default is the fs blocksize.
>>>> Everywhere else is 4k.
>>>
>>> Right, I see that in init_cvtnum()
>>>
>>> However, from checking write_buffer(), we seem to split writes on this
>>> blocksize - that does not seem proper in this instance.
>>>
>>> Should we really be doing something like:
>>>
>>> xfs_io -d -C "pwrite -b $SIZE -V 1 -A -D 0 $SIZE" file
>> In _require_xfs_io_command? That only writes the first 4k of a file, so
>> matching buffer size is ok.
>
> right, I missed that. The usage in _require_xfs_io_command looks ok.
>
>> Are you asking if _require_xfs_io_command should seek out the filesystem
>> block size, and use that for the buffer and write size arguments instead
>> of hardcoding 4k? For atomic writes, maybe it should be doing this,
>> since the fs blocksize could be 64k.
>
> I was just a bit thrown by how we need to specify -b $size with -A to actually write $size atomically.
There was a discussion about this a while back about why -b $bsize
was needed when using pwrite, although I’m not sure if it still applies
or if the way atomic writes works has been changed since then.
https://lore.kernel.org/linux-xfs/a6a2dc60f34ac353e5ea628a9ea1feba4800be7a.camel@linux.ibm.com/
>
> Thanks,
> John
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/6] generic/765: fix a few issues
2025-05-15 21:50 ` Catherine Hoang
@ 2025-05-16 6:59 ` John Garry
0 siblings, 0 replies; 29+ messages in thread
From: John Garry @ 2025-05-16 6:59 UTC (permalink / raw)
To: Catherine Hoang
Cc: Darrick J. Wong, linux-xfs@vger.kernel.org,
fstests@vger.kernel.org
On 15/05/2025 22:50, Catherine Hoang wrote:
>>> Are you asking if _require_xfs_io_command should seek out the filesystem
>>> block size, and use that for the buffer and write size arguments instead
>>> of hardcoding 4k? For atomic writes, maybe it should be doing this,
>>> since the fs blocksize could be 64k.
>> I was just a bit thrown by how we need to specify -b $size with -A to actually write $size atomically.
> There was a discussion about this a while back about why -b $bsize
> was needed when using pwrite, although I’m not sure if it still applies
> or if the way atomic writes works has been changed since then.
>
> https://lore.kernel.org/linux-xfs/
> a6a2dc60f34ac353e5ea628a9ea1feba4800be7a.camel@linux.ibm.com/
Yes, and the xfs_io behaviour for -A is my focus here. I don't like how
it splits by default (for $size > default blocksize).
We could have had behaviour that default blocksize for -A is $size.
Maybe that just complicates things. Anyway, I think that ship has sailed.
Thanks,
John
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/6] generic/765: fix a few issues
2025-05-14 0:29 ` [PATCH 1/6] generic/765: fix a few issues Catherine Hoang
2025-05-14 12:47 ` John Garry
@ 2025-05-17 3:17 ` Ritesh Harjani
1 sibling, 0 replies; 29+ messages in thread
From: Ritesh Harjani @ 2025-05-17 3:17 UTC (permalink / raw)
To: Catherine Hoang, linux-xfs, fstests; +Cc: djwong, john.g.garry
Catherine Hoang <catherine.hoang@oracle.com> writes:
> From: "Darrick J. Wong" <djwong@kernel.org>
>
> Fix a few bugs in the single block atomic writes test, such as requiring
> directio, using page size for the ext4 max bsize, and making sure we check
> the max atomic write size.
>
> Cc: ritesh.list@gmail.com
> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> ---
> common/rc | 2 +-
> tests/generic/765 | 4 ++--
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/common/rc b/common/rc
> index 657772e7..bc8dabc5 100644
> --- a/common/rc
> +++ b/common/rc
> @@ -2989,7 +2989,7 @@ _require_xfs_io_command()
> fi
> if [ "$param" == "-A" ]; then
> opts+=" -d"
> - pwrite_opts+="-D -V 1 -b 4k"
> + pwrite_opts+="-d -V 1 -b 4k"
I guess the discussion already happened that this needs fixing.
> fi
> testio=`$XFS_IO_PROG -f $opts -c \
> "pwrite $pwrite_opts $param 0 4k" $testfile 2>&1`
> diff --git a/tests/generic/765 b/tests/generic/765
> index 9bab3b8a..8695a306 100755
> --- a/tests/generic/765
> +++ b/tests/generic/765
> @@ -28,7 +28,7 @@ get_supported_bsize()
> ;;
> "ext4")
> min_bsize=1024
> - max_bsize=4096
> + max_bsize=$(_get_page_size)
> ;;
> *)
> _notrun "$FSTYP does not support atomic writes"
> @@ -73,7 +73,7 @@ test_atomic_writes()
> # Check that atomic min/max = FS block size
> test $file_min_write -eq $bsize || \
> echo "atomic write min $file_min_write, should be fs block size $bsize"
> - test $file_min_write -eq $bsize || \
> + test $file_max_write -eq $bsize || \
> echo "atomic write max $file_max_write, should be fs block size $bsize"
> test $file_max_segments -eq 1 || \
> echo "atomic write max segments $file_max_segments, should be 1"
> --
> 2.34.1
Otherwise the changes looks good. Thanks for fixing this!
-ritesh
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 2/6] generic/765: adjust various things
2025-05-14 0:29 [PATCH 0/6] atomic writes tests Catherine Hoang
2025-05-14 0:29 ` [PATCH 1/6] generic/765: fix a few issues Catherine Hoang
@ 2025-05-14 0:29 ` Catherine Hoang
2025-05-14 12:59 ` John Garry
2025-05-17 3:36 ` Ritesh Harjani
2025-05-14 0:29 ` [PATCH 3/6] generic/765: move common atomic write code to a library file Catherine Hoang
` (3 subsequent siblings)
5 siblings, 2 replies; 29+ messages in thread
From: Catherine Hoang @ 2025-05-14 0:29 UTC (permalink / raw)
To: linux-xfs, fstests; +Cc: djwong, john.g.garry
From: "Darrick J. Wong" <djwong@kernel.org>
Fix some bugs when detecting the atomic write geometry, record what
atomic write geometry we're testing each time through the loop, and
create a group for atomic writes tests.
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
---
common/rc | 4 ++--
doc/group-names.txt | 1 +
tests/generic/765 | 25 ++++++++++++++++++++++++-
3 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/common/rc b/common/rc
index bc8dabc5..3a70c707 100644
--- a/common/rc
+++ b/common/rc
@@ -5442,13 +5442,13 @@ _get_atomic_write_unit_min()
_get_atomic_write_unit_max()
{
$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
- grep atomic_write_unit_max | grep -o '[0-9]\+'
+ grep -w atomic_write_unit_max | grep -o '[0-9]\+'
}
_get_atomic_write_segments_max()
{
$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
- grep atomic_write_segments_max | grep -o '[0-9]\+'
+ grep -w atomic_write_segments_max | grep -o '[0-9]\+'
}
_require_scratch_write_atomic()
diff --git a/doc/group-names.txt b/doc/group-names.txt
index f510bb82..1b38f73b 100644
--- a/doc/group-names.txt
+++ b/doc/group-names.txt
@@ -12,6 +12,7 @@ acl Access Control Lists
admin xfs_admin functionality
aio general libaio async io tests
atime file access time
+atomicwrites RWF_ATOMIC testing
attr extended attributes
attr2 xfs v2 extended aributes
balance btrfs tree rebalance
diff --git a/tests/generic/765 b/tests/generic/765
index 8695a306..84381730 100755
--- a/tests/generic/765
+++ b/tests/generic/765
@@ -7,7 +7,7 @@
# Validate atomic write support
#
. ./common/preamble
-_begin_fstest auto quick rw
+_begin_fstest auto quick rw atomicwrites
_require_scratch_write_atomic
_require_xfs_io_command pwrite -A
@@ -34,6 +34,10 @@ get_supported_bsize()
_notrun "$FSTYP does not support atomic writes"
;;
esac
+
+ echo "fs config ------------" >> $seqres.full
+ echo "min_bsize $min_bsize" >> $seqres.full
+ echo "max_bsize $max_bsize" >> $seqres.full
}
get_mkfs_opts()
@@ -70,6 +74,11 @@ test_atomic_writes()
file_max_write=$(_get_atomic_write_unit_max $testfile)
file_max_segments=$(_get_atomic_write_segments_max $testfile)
+ echo "test $bsize --------------" >> $seqres.full
+ echo "file awu_min $file_min_write" >> $seqres.full
+ echo "file awu_max $file_max_write" >> $seqres.full
+ echo "file awu_segments $file_max_segments" >> $seqres.full
+
# Check that atomic min/max = FS block size
test $file_min_write -eq $bsize || \
echo "atomic write min $file_min_write, should be fs block size $bsize"
@@ -145,6 +154,15 @@ test_atomic_write_bounds()
testfile=$SCRATCH_MNT/testfile
touch $testfile
+ file_min_write=$(_get_atomic_write_unit_min $testfile)
+ file_max_write=$(_get_atomic_write_unit_max $testfile)
+ file_max_segments=$(_get_atomic_write_segments_max $testfile)
+
+ echo "test awb $bsize --------------" >> $seqres.full
+ echo "file awu_min $file_min_write" >> $seqres.full
+ echo "file awu_max $file_max_write" >> $seqres.full
+ echo "file awu_segments $file_max_segments" >> $seqres.full
+
$XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile 2>> $seqres.full && \
echo "atomic write should fail when bsize is out of bounds"
@@ -157,6 +175,11 @@ sys_max_write=$(cat "/sys/block/$(_short_dev $SCRATCH_DEV)/queue/atomic_write_un
bdev_min_write=$(_get_atomic_write_unit_min $SCRATCH_DEV)
bdev_max_write=$(_get_atomic_write_unit_max $SCRATCH_DEV)
+echo "sysfs awu_min $sys_min_write" >> $seqres.full
+echo "sysfs awu_min $sys_max_write" >> $seqres.full
+echo "bdev awu_min $bdev_min_write" >> $seqres.full
+echo "bdev awu_min $bdev_max_write" >> $seqres.full
+
# Test that statx atomic values are the same as sysfs values
if [ "$sys_min_write" -ne "$bdev_min_write" ]; then
echo "bdev min write != sys min write"
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH 2/6] generic/765: adjust various things
2025-05-14 0:29 ` [PATCH 2/6] generic/765: adjust various things Catherine Hoang
@ 2025-05-14 12:59 ` John Garry
2025-05-17 3:36 ` Ritesh Harjani
1 sibling, 0 replies; 29+ messages in thread
From: John Garry @ 2025-05-14 12:59 UTC (permalink / raw)
To: Catherine Hoang, linux-xfs, fstests; +Cc: djwong
On 14/05/2025 01:29, Catherine Hoang wrote:
> From: "Darrick J. Wong" <djwong@kernel.org>
>
> Fix some bugs when detecting the atomic write geometry, record what
> atomic write geometry we're testing each time through the loop, and
> create a group for atomic writes tests.
>
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Just a small comment below
cheers
> }
>
> get_mkfs_opts()
> @@ -70,6 +74,11 @@ test_atomic_writes()
> file_max_write=$(_get_atomic_write_unit_max $testfile)
> file_max_segments=$(_get_atomic_write_segments_max $testfile)
>
> + echo "test $bsize --------------" >> $seqres.full
> + echo "file awu_min $file_min_write" >> $seqres.full
> + echo "file awu_max $file_max_write" >> $seqres.full
> + echo "file awu_segments $file_max_segments" >> $seqres.full
We should prob report and test atomic write unit max opt also when it's
available officially in stat.h
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 2/6] generic/765: adjust various things
2025-05-14 0:29 ` [PATCH 2/6] generic/765: adjust various things Catherine Hoang
2025-05-14 12:59 ` John Garry
@ 2025-05-17 3:36 ` Ritesh Harjani
1 sibling, 0 replies; 29+ messages in thread
From: Ritesh Harjani @ 2025-05-17 3:36 UTC (permalink / raw)
To: Catherine Hoang, linux-xfs, fstests; +Cc: djwong, john.g.garry
Catherine Hoang <catherine.hoang@oracle.com> writes:
> From: "Darrick J. Wong" <djwong@kernel.org>
>
> Fix some bugs when detecting the atomic write geometry, record what
> atomic write geometry we're testing each time through the loop, and
> create a group for atomic writes tests.
>
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> ---
> common/rc | 4 ++--
> doc/group-names.txt | 1 +
> tests/generic/765 | 25 ++++++++++++++++++++++++-
> 3 files changed, 27 insertions(+), 3 deletions(-)
>
> diff --git a/common/rc b/common/rc
> index bc8dabc5..3a70c707 100644
> --- a/common/rc
> +++ b/common/rc
> @@ -5442,13 +5442,13 @@ _get_atomic_write_unit_min()
> _get_atomic_write_unit_max()
> {
> $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
> - grep atomic_write_unit_max | grep -o '[0-9]\+'
> + grep -w atomic_write_unit_max | grep -o '[0-9]\+'
> }
>
> _get_atomic_write_segments_max()
> {
> $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
> - grep atomic_write_segments_max | grep -o '[0-9]\+'
> + grep -w atomic_write_segments_max | grep -o '[0-9]\+'
> }
>
> _require_scratch_write_atomic()
> diff --git a/doc/group-names.txt b/doc/group-names.txt
> index f510bb82..1b38f73b 100644
> --- a/doc/group-names.txt
> +++ b/doc/group-names.txt
> @@ -12,6 +12,7 @@ acl Access Control Lists
> admin xfs_admin functionality
> aio general libaio async io tests
> atime file access time
> +atomicwrites RWF_ATOMIC testing
NIT: I wish we could have a shorter name for this? atomicwr or awio (Atomic write I/O)
Either ways, the changes looks logical to me. It's good to have these
various atomic units in $seqres.full file for later debugging.
Please feel free to add:
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
-ritesh
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 3/6] generic/765: move common atomic write code to a library file
2025-05-14 0:29 [PATCH 0/6] atomic writes tests Catherine Hoang
2025-05-14 0:29 ` [PATCH 1/6] generic/765: fix a few issues Catherine Hoang
2025-05-14 0:29 ` [PATCH 2/6] generic/765: adjust various things Catherine Hoang
@ 2025-05-14 0:29 ` Catherine Hoang
2025-05-14 13:00 ` John Garry
2025-05-17 3:49 ` Ritesh Harjani
2025-05-14 0:29 ` [PATCH 4/6] common/atomicwrites: adjust a few more things Catherine Hoang
` (2 subsequent siblings)
5 siblings, 2 replies; 29+ messages in thread
From: Catherine Hoang @ 2025-05-14 0:29 UTC (permalink / raw)
To: linux-xfs, fstests; +Cc: djwong, john.g.garry
From: "Darrick J. Wong" <djwong@kernel.org>
Move the common atomic writes code to common/atomic so we can share
them.
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
---
common/atomicwrites | 111 ++++++++++++++++++++++++++++++++++++++++++++
common/rc | 47 -------------------
tests/generic/765 | 53 ++-------------------
3 files changed, 114 insertions(+), 97 deletions(-)
create mode 100644 common/atomicwrites
diff --git a/common/atomicwrites b/common/atomicwrites
new file mode 100644
index 00000000..fd3a9b71
--- /dev/null
+++ b/common/atomicwrites
@@ -0,0 +1,111 @@
+##/bin/bash
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2025 Oracle. All Rights Reserved.
+#
+# Routines for testing atomic writes.
+
+_get_atomic_write_unit_min()
+{
+ $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
+ grep atomic_write_unit_min | grep -o '[0-9]\+'
+}
+
+_get_atomic_write_unit_max()
+{
+ $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
+ grep -w atomic_write_unit_max | grep -o '[0-9]\+'
+}
+
+_get_atomic_write_segments_max()
+{
+ $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
+ grep -w atomic_write_segments_max | grep -o '[0-9]\+'
+}
+
+_require_scratch_write_atomic()
+{
+ _require_scratch
+
+ export STATX_WRITE_ATOMIC=0x10000
+
+ awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
+ awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
+
+ if [ $awu_min_bdev -eq 0 ] && [ $awu_max_bdev -eq 0 ]; then
+ _notrun "write atomic not supported by this block device"
+ fi
+
+ _scratch_mkfs > /dev/null 2>&1
+ _scratch_mount
+
+ testfile=$SCRATCH_MNT/testfile
+ touch $testfile
+
+ awu_min_fs=$(_get_atomic_write_unit_min $testfile)
+ awu_max_fs=$(_get_atomic_write_unit_max $testfile)
+
+ _scratch_unmount
+
+ if [ $awu_min_fs -eq 0 ] && [ $awu_max_fs -eq 0 ]; then
+ _notrun "write atomic not supported by this filesystem"
+ fi
+}
+
+_test_atomic_file_writes()
+{
+ local bsize="$1"
+ local testfile="$2"
+ local bytes_written
+ local testfile_cp="$testfile.copy"
+
+ # Check that we can perform an atomic write of len = FS block size
+ bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
+ grep wrote | awk -F'[/ ]' '{print $2}')
+ test $bytes_written -eq $bsize || echo "atomic write len=$bsize failed"
+
+ # Check that we can perform an atomic single-block cow write
+ if [ "$FSTYP" == "xfs" ]; then
+ testfile_cp=$SCRATCH_MNT/testfile_copy
+ if _xfs_has_feature $SCRATCH_MNT reflink; then
+ cp --reflink $testfile $testfile_cp
+ fi
+ bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile_cp | \
+ grep wrote | awk -F'[/ ]' '{print $2}')
+ test $bytes_written -eq $bsize || echo "atomic write on reflinked file failed"
+ fi
+
+ # Check that we can perform an atomic write on an unwritten block
+ $XFS_IO_PROG -c "falloc $bsize $bsize" $testfile
+ bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize $bsize $bsize" $testfile | \
+ grep wrote | awk -F'[/ ]' '{print $2}')
+ test $bytes_written -eq $bsize || echo "atomic write to unwritten block failed"
+
+ # Check that we can perform an atomic write on a sparse hole
+ $XFS_IO_PROG -c "fpunch 0 $bsize" $testfile
+ bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
+ grep wrote | awk -F'[/ ]' '{print $2}')
+ test $bytes_written -eq $bsize || echo "atomic write to sparse hole failed"
+
+ # Check that we can perform an atomic write on a fully mapped block
+ bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
+ grep wrote | awk -F'[/ ]' '{print $2}')
+ test $bytes_written -eq $bsize || echo "atomic write to mapped block failed"
+
+ # Reject atomic write if len is out of bounds
+ $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $((bsize - 1))" $testfile 2>> $seqres.full && \
+ echo "atomic write len=$((bsize - 1)) should fail"
+ $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $((bsize + 1))" $testfile 2>> $seqres.full && \
+ echo "atomic write len=$((bsize + 1)) should fail"
+
+ # Reject atomic write when iovecs > 1
+ $XFS_IO_PROG -dc "pwrite -A -D -V2 -b $bsize 0 $bsize" $testfile 2>> $seqres.full && \
+ echo "atomic write only supports iovec count of 1"
+
+ # Reject atomic write when not using direct I/O
+ $XFS_IO_PROG -c "pwrite -A -V1 -b $bsize 0 $bsize" $testfile 2>> $seqres.full && \
+ echo "atomic write requires direct I/O"
+
+ # Reject atomic write when offset % bsize != 0
+ $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 1 $bsize" $testfile 2>> $seqres.full && \
+ echo "atomic write requires offset to be aligned to bsize"
+}
diff --git a/common/rc b/common/rc
index 3a70c707..781fc9ba 100644
--- a/common/rc
+++ b/common/rc
@@ -5433,53 +5433,6 @@ _require_scratch_btime()
_scratch_unmount
}
-_get_atomic_write_unit_min()
-{
- $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
- grep atomic_write_unit_min | grep -o '[0-9]\+'
-}
-
-_get_atomic_write_unit_max()
-{
- $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
- grep -w atomic_write_unit_max | grep -o '[0-9]\+'
-}
-
-_get_atomic_write_segments_max()
-{
- $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
- grep -w atomic_write_segments_max | grep -o '[0-9]\+'
-}
-
-_require_scratch_write_atomic()
-{
- _require_scratch
-
- export STATX_WRITE_ATOMIC=0x10000
-
- awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
- awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
-
- if [ $awu_min_bdev -eq 0 ] && [ $awu_max_bdev -eq 0 ]; then
- _notrun "write atomic not supported by this block device"
- fi
-
- _scratch_mkfs > /dev/null 2>&1
- _scratch_mount
-
- testfile=$SCRATCH_MNT/testfile
- touch $testfile
-
- awu_min_fs=$(_get_atomic_write_unit_min $testfile)
- awu_max_fs=$(_get_atomic_write_unit_max $testfile)
-
- _scratch_unmount
-
- if [ $awu_min_fs -eq 0 ] && [ $awu_max_fs -eq 0 ]; then
- _notrun "write atomic not supported by this filesystem"
- fi
-}
-
_require_inode_limits()
{
if [ $(_get_free_inode $TEST_DIR) -eq 0 ]; then
diff --git a/tests/generic/765 b/tests/generic/765
index 84381730..09e9fa38 100755
--- a/tests/generic/765
+++ b/tests/generic/765
@@ -9,6 +9,8 @@
. ./common/preamble
_begin_fstest auto quick rw atomicwrites
+. ./common/atomicwrites
+
_require_scratch_write_atomic
_require_xfs_io_command pwrite -A
@@ -87,56 +89,7 @@ test_atomic_writes()
test $file_max_segments -eq 1 || \
echo "atomic write max segments $file_max_segments, should be 1"
- # Check that we can perform an atomic write of len = FS block size
- bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
- grep wrote | awk -F'[/ ]' '{print $2}')
- test $bytes_written -eq $bsize || echo "atomic write len=$bsize failed"
-
- # Check that we can perform an atomic single-block cow write
- if [ "$FSTYP" == "xfs" ]; then
- testfile_cp=$SCRATCH_MNT/testfile_copy
- if _xfs_has_feature $SCRATCH_MNT reflink; then
- cp --reflink $testfile $testfile_cp
- fi
- bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile_cp | \
- grep wrote | awk -F'[/ ]' '{print $2}')
- test $bytes_written -eq $bsize || echo "atomic write on reflinked file failed"
- fi
-
- # Check that we can perform an atomic write on an unwritten block
- $XFS_IO_PROG -c "falloc $bsize $bsize" $testfile
- bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize $bsize $bsize" $testfile | \
- grep wrote | awk -F'[/ ]' '{print $2}')
- test $bytes_written -eq $bsize || echo "atomic write to unwritten block failed"
-
- # Check that we can perform an atomic write on a sparse hole
- $XFS_IO_PROG -c "fpunch 0 $bsize" $testfile
- bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
- grep wrote | awk -F'[/ ]' '{print $2}')
- test $bytes_written -eq $bsize || echo "atomic write to sparse hole failed"
-
- # Check that we can perform an atomic write on a fully mapped block
- bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
- grep wrote | awk -F'[/ ]' '{print $2}')
- test $bytes_written -eq $bsize || echo "atomic write to mapped block failed"
-
- # Reject atomic write if len is out of bounds
- $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $((bsize - 1))" $testfile 2>> $seqres.full && \
- echo "atomic write len=$((bsize - 1)) should fail"
- $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $((bsize + 1))" $testfile 2>> $seqres.full && \
- echo "atomic write len=$((bsize + 1)) should fail"
-
- # Reject atomic write when iovecs > 1
- $XFS_IO_PROG -dc "pwrite -A -D -V2 -b $bsize 0 $bsize" $testfile 2>> $seqres.full && \
- echo "atomic write only supports iovec count of 1"
-
- # Reject atomic write when not using direct I/O
- $XFS_IO_PROG -c "pwrite -A -V1 -b $bsize 0 $bsize" $testfile 2>> $seqres.full && \
- echo "atomic write requires direct I/O"
-
- # Reject atomic write when offset % bsize != 0
- $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 1 $bsize" $testfile 2>> $seqres.full && \
- echo "atomic write requires offset to be aligned to bsize"
+ _test_atomic_file_writes "$bsize" "$testfile"
_scratch_unmount
}
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH 3/6] generic/765: move common atomic write code to a library file
2025-05-14 0:29 ` [PATCH 3/6] generic/765: move common atomic write code to a library file Catherine Hoang
@ 2025-05-14 13:00 ` John Garry
2025-05-17 3:49 ` Ritesh Harjani
1 sibling, 0 replies; 29+ messages in thread
From: John Garry @ 2025-05-14 13:00 UTC (permalink / raw)
To: Catherine Hoang, linux-xfs, fstests; +Cc: djwong
On 14/05/2025 01:29, Catherine Hoang wrote:
> From: "Darrick J. Wong"<djwong@kernel.org>
>
> Move the common atomic writes code to common/atomic so we can share
> them.
>
> Signed-off-by: "Darrick J. Wong"<djwong@kernel.org>
> Signed-off-by: Catherine Hoang<catherine.hoang@oracle.com>
Reviewed-by: John Garry <john.g.garry@oracle.com>
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 3/6] generic/765: move common atomic write code to a library file
2025-05-14 0:29 ` [PATCH 3/6] generic/765: move common atomic write code to a library file Catherine Hoang
2025-05-14 13:00 ` John Garry
@ 2025-05-17 3:49 ` Ritesh Harjani
1 sibling, 0 replies; 29+ messages in thread
From: Ritesh Harjani @ 2025-05-17 3:49 UTC (permalink / raw)
To: Catherine Hoang, linux-xfs, fstests; +Cc: djwong, john.g.garry
Catherine Hoang <catherine.hoang@oracle.com> writes:
> From: "Darrick J. Wong" <djwong@kernel.org>
>
> Move the common atomic writes code to common/atomic so we can share
> them.
>
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> ---
> common/atomicwrites | 111 ++++++++++++++++++++++++++++++++++++++++++++
> common/rc | 47 -------------------
> tests/generic/765 | 53 ++-------------------
> 3 files changed, 114 insertions(+), 97 deletions(-)
> create mode 100644 common/atomicwrites
>
> diff --git a/common/atomicwrites b/common/atomicwrites
> new file mode 100644
> index 00000000..fd3a9b71
> --- /dev/null
> +++ b/common/atomicwrites
> @@ -0,0 +1,111 @@
> +##/bin/bash
> +# SPDX-License-Identifier: GPL-2.0+
> +# Copyright (c) 2025 Oracle. All Rights Reserved.
> +#
> +# Routines for testing atomic writes.
> +
> +_get_atomic_write_unit_min()
> +{
> + $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
> + grep atomic_write_unit_min | grep -o '[0-9]\+'
> +}
> +
> +_get_atomic_write_unit_max()
> +{
> + $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
> + grep -w atomic_write_unit_max | grep -o '[0-9]\+'
> +}
> +
> +_get_atomic_write_segments_max()
> +{
> + $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
> + grep -w atomic_write_segments_max | grep -o '[0-9]\+'
> +}
> +
> +_require_scratch_write_atomic()
NIT: It would be more convenient if we had this as _require_scratch_atomic_write()
> +{
> + _require_scratch
> +
> + export STATX_WRITE_ATOMIC=0x10000
> +
> + awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
> + awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
> +
> + if [ $awu_min_bdev -eq 0 ] && [ $awu_max_bdev -eq 0 ]; then
> + _notrun "write atomic not supported by this block device"
> + fi
> +
> + _scratch_mkfs > /dev/null 2>&1
> + _scratch_mount
> +
> + testfile=$SCRATCH_MNT/testfile
> + touch $testfile
> +
> + awu_min_fs=$(_get_atomic_write_unit_min $testfile)
> + awu_max_fs=$(_get_atomic_write_unit_max $testfile)
> +
> + _scratch_unmount
> +
> + if [ $awu_min_fs -eq 0 ] && [ $awu_max_fs -eq 0 ]; then
> + _notrun "write atomic not supported by this filesystem"
> + fi
> +}
> +
> +_test_atomic_file_writes()
> +{
> + local bsize="$1"
> + local testfile="$2"
> + local bytes_written
> + local testfile_cp="$testfile.copy"
> +
> + # Check that we can perform an atomic write of len = FS block size
> + bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
> + grep wrote | awk -F'[/ ]' '{print $2}')
> + test $bytes_written -eq $bsize || echo "atomic write len=$bsize failed"
> +
> + # Check that we can perform an atomic single-block cow write
> + if [ "$FSTYP" == "xfs" ]; then
> + testfile_cp=$SCRATCH_MNT/testfile_copy
> + if _xfs_has_feature $SCRATCH_MNT reflink; then
> + cp --reflink $testfile $testfile_cp
> + fi
> + bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile_cp | \
> + grep wrote | awk -F'[/ ]' '{print $2}')
> + test $bytes_written -eq $bsize || echo "atomic write on reflinked file failed"
> + fi
> +
> + # Check that we can perform an atomic write on an unwritten block
> + $XFS_IO_PROG -c "falloc $bsize $bsize" $testfile
> + bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize $bsize $bsize" $testfile | \
> + grep wrote | awk -F'[/ ]' '{print $2}')
> + test $bytes_written -eq $bsize || echo "atomic write to unwritten block failed"
> +
> + # Check that we can perform an atomic write on a sparse hole
> + $XFS_IO_PROG -c "fpunch 0 $bsize" $testfile
> + bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
> + grep wrote | awk -F'[/ ]' '{print $2}')
> + test $bytes_written -eq $bsize || echo "atomic write to sparse hole failed"
> +
> + # Check that we can perform an atomic write on a fully mapped block
> + bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
> + grep wrote | awk -F'[/ ]' '{print $2}')
> + test $bytes_written -eq $bsize || echo "atomic write to mapped block failed"
> +
> + # Reject atomic write if len is out of bounds
> + $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $((bsize - 1))" $testfile 2>> $seqres.full && \
> + echo "atomic write len=$((bsize - 1)) should fail"
> + $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $((bsize + 1))" $testfile 2>> $seqres.full && \
> + echo "atomic write len=$((bsize + 1)) should fail"
> +
> + # Reject atomic write when iovecs > 1
> + $XFS_IO_PROG -dc "pwrite -A -D -V2 -b $bsize 0 $bsize" $testfile 2>> $seqres.full && \
> + echo "atomic write only supports iovec count of 1"
> +
> + # Reject atomic write when not using direct I/O
> + $XFS_IO_PROG -c "pwrite -A -V1 -b $bsize 0 $bsize" $testfile 2>> $seqres.full && \
> + echo "atomic write requires direct I/O"
> +
> + # Reject atomic write when offset % bsize != 0
> + $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 1 $bsize" $testfile 2>> $seqres.full && \
> + echo "atomic write requires offset to be aligned to bsize"
> +}
> diff --git a/common/rc b/common/rc
> index 3a70c707..781fc9ba 100644
> --- a/common/rc
> +++ b/common/rc
> @@ -5433,53 +5433,6 @@ _require_scratch_btime()
> _scratch_unmount
> }
>
> -_get_atomic_write_unit_min()
> -{
> - $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
> - grep atomic_write_unit_min | grep -o '[0-9]\+'
> -}
> -
> -_get_atomic_write_unit_max()
> -{
> - $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
> - grep -w atomic_write_unit_max | grep -o '[0-9]\+'
> -}
> -
> -_get_atomic_write_segments_max()
> -{
> - $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
> - grep -w atomic_write_segments_max | grep -o '[0-9]\+'
> -}
> -
> -_require_scratch_write_atomic()
> -{
> - _require_scratch
> -
> - export STATX_WRITE_ATOMIC=0x10000
> -
> - awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
> - awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
> -
> - if [ $awu_min_bdev -eq 0 ] && [ $awu_max_bdev -eq 0 ]; then
> - _notrun "write atomic not supported by this block device"
> - fi
> -
> - _scratch_mkfs > /dev/null 2>&1
> - _scratch_mount
> -
> - testfile=$SCRATCH_MNT/testfile
> - touch $testfile
> -
> - awu_min_fs=$(_get_atomic_write_unit_min $testfile)
> - awu_max_fs=$(_get_atomic_write_unit_max $testfile)
> -
> - _scratch_unmount
> -
> - if [ $awu_min_fs -eq 0 ] && [ $awu_max_fs -eq 0 ]; then
> - _notrun "write atomic not supported by this filesystem"
> - fi
> -}
> -
> _require_inode_limits()
> {
> if [ $(_get_free_inode $TEST_DIR) -eq 0 ]; then
> diff --git a/tests/generic/765 b/tests/generic/765
> index 84381730..09e9fa38 100755
> --- a/tests/generic/765
> +++ b/tests/generic/765
> @@ -9,6 +9,8 @@
> . ./common/preamble
> _begin_fstest auto quick rw atomicwrites
>
> +. ./common/atomicwrites
> +
> _require_scratch_write_atomic
> _require_xfs_io_command pwrite -A
>
> @@ -87,56 +89,7 @@ test_atomic_writes()
> test $file_max_segments -eq 1 || \
> echo "atomic write max segments $file_max_segments, should be 1"
>
> - # Check that we can perform an atomic write of len = FS block size
> - bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
> - grep wrote | awk -F'[/ ]' '{print $2}')
> - test $bytes_written -eq $bsize || echo "atomic write len=$bsize failed"
> -
> - # Check that we can perform an atomic single-block cow write
> - if [ "$FSTYP" == "xfs" ]; then
> - testfile_cp=$SCRATCH_MNT/testfile_copy
> - if _xfs_has_feature $SCRATCH_MNT reflink; then
> - cp --reflink $testfile $testfile_cp
> - fi
> - bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile_cp | \
> - grep wrote | awk -F'[/ ]' '{print $2}')
> - test $bytes_written -eq $bsize || echo "atomic write on reflinked file failed"
> - fi
> -
> - # Check that we can perform an atomic write on an unwritten block
> - $XFS_IO_PROG -c "falloc $bsize $bsize" $testfile
> - bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize $bsize $bsize" $testfile | \
> - grep wrote | awk -F'[/ ]' '{print $2}')
> - test $bytes_written -eq $bsize || echo "atomic write to unwritten block failed"
> -
> - # Check that we can perform an atomic write on a sparse hole
> - $XFS_IO_PROG -c "fpunch 0 $bsize" $testfile
> - bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
> - grep wrote | awk -F'[/ ]' '{print $2}')
> - test $bytes_written -eq $bsize || echo "atomic write to sparse hole failed"
> -
> - # Check that we can perform an atomic write on a fully mapped block
> - bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
> - grep wrote | awk -F'[/ ]' '{print $2}')
> - test $bytes_written -eq $bsize || echo "atomic write to mapped block failed"
> -
> - # Reject atomic write if len is out of bounds
> - $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $((bsize - 1))" $testfile 2>> $seqres.full && \
> - echo "atomic write len=$((bsize - 1)) should fail"
> - $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $((bsize + 1))" $testfile 2>> $seqres.full && \
> - echo "atomic write len=$((bsize + 1)) should fail"
> -
> - # Reject atomic write when iovecs > 1
> - $XFS_IO_PROG -dc "pwrite -A -D -V2 -b $bsize 0 $bsize" $testfile 2>> $seqres.full && \
> - echo "atomic write only supports iovec count of 1"
> -
> - # Reject atomic write when not using direct I/O
> - $XFS_IO_PROG -c "pwrite -A -V1 -b $bsize 0 $bsize" $testfile 2>> $seqres.full && \
> - echo "atomic write requires direct I/O"
> -
> - # Reject atomic write when offset % bsize != 0
> - $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 1 $bsize" $testfile 2>> $seqres.full && \
> - echo "atomic write requires offset to be aligned to bsize"
> + _test_atomic_file_writes "$bsize" "$testfile"
I see this must be done since in later patches we are adding an atomic
write test using scsi debug.
Sure make sense in that case. Please feel free to add:
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
-ritesh
>
> _scratch_unmount
> }
> --
> 2.34.1
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 4/6] common/atomicwrites: adjust a few more things
2025-05-14 0:29 [PATCH 0/6] atomic writes tests Catherine Hoang
` (2 preceding siblings ...)
2025-05-14 0:29 ` [PATCH 3/6] generic/765: move common atomic write code to a library file Catherine Hoang
@ 2025-05-14 0:29 ` Catherine Hoang
2025-05-14 13:11 ` John Garry
2025-05-17 3:59 ` Ritesh Harjani
2025-05-14 0:29 ` [PATCH 5/6] common/atomicwrites: fix _require_scratch_write_atomic Catherine Hoang
2025-05-14 0:29 ` [PATCH 6/6] generic: various atomic write tests with scsi_debug Catherine Hoang
5 siblings, 2 replies; 29+ messages in thread
From: Catherine Hoang @ 2025-05-14 0:29 UTC (permalink / raw)
To: linux-xfs, fstests; +Cc: djwong, john.g.garry
From: "Darrick J. Wong" <djwong@kernel.org>
Always export STATX_WRITE_ATOMIC so anyone can use it, make the "cp
reflink" logic work for any filesystem, not just xfs, and create a
separate helper to check that the necessary xfs_io support is present.
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
---
common/atomicwrites | 18 +++++++++++-------
tests/generic/765 | 2 +-
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/common/atomicwrites b/common/atomicwrites
index fd3a9b71..9ec1ca68 100644
--- a/common/atomicwrites
+++ b/common/atomicwrites
@@ -4,6 +4,8 @@
#
# Routines for testing atomic writes.
+export STATX_WRITE_ATOMIC=0x10000
+
_get_atomic_write_unit_min()
{
$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
@@ -26,8 +28,6 @@ _require_scratch_write_atomic()
{
_require_scratch
- export STATX_WRITE_ATOMIC=0x10000
-
awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
@@ -51,6 +51,14 @@ _require_scratch_write_atomic()
fi
}
+# Check for xfs_io commands required to run _test_atomic_file_writes
+_require_atomic_write_test_commands()
+{
+ _require_xfs_io_command "falloc"
+ _require_xfs_io_command "fpunch"
+ _require_xfs_io_command pwrite -A
+}
+
_test_atomic_file_writes()
{
local bsize="$1"
@@ -64,11 +72,7 @@ _test_atomic_file_writes()
test $bytes_written -eq $bsize || echo "atomic write len=$bsize failed"
# Check that we can perform an atomic single-block cow write
- if [ "$FSTYP" == "xfs" ]; then
- testfile_cp=$SCRATCH_MNT/testfile_copy
- if _xfs_has_feature $SCRATCH_MNT reflink; then
- cp --reflink $testfile $testfile_cp
- fi
+ if cp --reflink=always $testfile $testfile_cp 2>> $seqres.full; then
bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile_cp | \
grep wrote | awk -F'[/ ]' '{print $2}')
test $bytes_written -eq $bsize || echo "atomic write on reflinked file failed"
diff --git a/tests/generic/765 b/tests/generic/765
index 09e9fa38..71604e5e 100755
--- a/tests/generic/765
+++ b/tests/generic/765
@@ -12,7 +12,7 @@ _begin_fstest auto quick rw atomicwrites
. ./common/atomicwrites
_require_scratch_write_atomic
-_require_xfs_io_command pwrite -A
+_require_atomic_write_test_commands
get_supported_bsize()
{
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH 4/6] common/atomicwrites: adjust a few more things
2025-05-14 0:29 ` [PATCH 4/6] common/atomicwrites: adjust a few more things Catherine Hoang
@ 2025-05-14 13:11 ` John Garry
2025-05-14 15:40 ` Darrick J. Wong
2025-05-17 3:59 ` Ritesh Harjani
1 sibling, 1 reply; 29+ messages in thread
From: John Garry @ 2025-05-14 13:11 UTC (permalink / raw)
To: Catherine Hoang, linux-xfs, fstests; +Cc: djwong
On 14/05/2025 01:29, Catherine Hoang wrote:
> From: "Darrick J. Wong"<djwong@kernel.org>
>
> Always export STATX_WRITE_ATOMIC so anyone can use it, make the "cp
> reflink" logic work for any filesystem, not just xfs, and create a
> separate helper to check that the necessary xfs_io support is present.
>
> Signed-off-by: "Darrick J. Wong"<djwong@kernel.org>
> Signed-off-by: Catherine Hoang<catherine.hoang@oracle.com>
Just a small comment query below.
Reviewed-by: John Garry <john.g.garry@oracle.com>
> ---
> common/atomicwrites | 18 +++++++++++-------
> tests/generic/765 | 2 +-
> 2 files changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/common/atomicwrites b/common/atomicwrites
> index fd3a9b71..9ec1ca68 100644
> --- a/common/atomicwrites
> +++ b/common/atomicwrites
> @@ -4,6 +4,8 @@
> #
> # Routines for testing atomic writes.
>
> +export STATX_WRITE_ATOMIC=0x10000
> +
> _get_atomic_write_unit_min()
> {
> $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
> @@ -26,8 +28,6 @@ _require_scratch_write_atomic()
> {
> _require_scratch
>
> - export STATX_WRITE_ATOMIC=0x10000
> -
> awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
> awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
>
> @@ -51,6 +51,14 @@ _require_scratch_write_atomic()
> fi
> }
>
> +# Check for xfs_io commands required to run _test_atomic_file_writes
> +_require_atomic_write_test_commands()
> +{
> + _require_xfs_io_command "falloc"
> + _require_xfs_io_command "fpunch"
> + _require_xfs_io_command pwrite -A
> +}
> +
> _test_atomic_file_writes()
> {
> local bsize="$1"
> @@ -64,11 +72,7 @@ _test_atomic_file_writes()
> test $bytes_written -eq $bsize || echo "atomic write len=$bsize failed"
>
> # Check that we can perform an atomic single-block cow write
> - if [ "$FSTYP" == "xfs" ]; then
> - testfile_cp=$SCRATCH_MNT/testfile_copy
> - if _xfs_has_feature $SCRATCH_MNT reflink; then
> - cp --reflink $testfile $testfile_cp
> - fi
> + if cp --reflink=always $testfile $testfile_cp 2>> $seqres.full; then
I suppose that previously for xfs where the cp --reflink failed, we
would pointlessly try the write - am I correct?
If so, now seems much better.
> bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile_cp | \
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 4/6] common/atomicwrites: adjust a few more things
2025-05-14 13:11 ` John Garry
@ 2025-05-14 15:40 ` Darrick J. Wong
0 siblings, 0 replies; 29+ messages in thread
From: Darrick J. Wong @ 2025-05-14 15:40 UTC (permalink / raw)
To: John Garry; +Cc: Catherine Hoang, linux-xfs, fstests
On Wed, May 14, 2025 at 02:11:00PM +0100, John Garry wrote:
> On 14/05/2025 01:29, Catherine Hoang wrote:
> > From: "Darrick J. Wong"<djwong@kernel.org>
> >
> > Always export STATX_WRITE_ATOMIC so anyone can use it, make the "cp
> > reflink" logic work for any filesystem, not just xfs, and create a
> > separate helper to check that the necessary xfs_io support is present.
> >
> > Signed-off-by: "Darrick J. Wong"<djwong@kernel.org>
> > Signed-off-by: Catherine Hoang<catherine.hoang@oracle.com>
>
> Just a small comment query below.
>
> Reviewed-by: John Garry <john.g.garry@oracle.com>
>
> > ---
> > common/atomicwrites | 18 +++++++++++-------
> > tests/generic/765 | 2 +-
> > 2 files changed, 12 insertions(+), 8 deletions(-)
> >
> > diff --git a/common/atomicwrites b/common/atomicwrites
> > index fd3a9b71..9ec1ca68 100644
> > --- a/common/atomicwrites
> > +++ b/common/atomicwrites
> > @@ -4,6 +4,8 @@
> > #
> > # Routines for testing atomic writes.
> > +export STATX_WRITE_ATOMIC=0x10000
> > +
> > _get_atomic_write_unit_min()
> > {
> > $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
> > @@ -26,8 +28,6 @@ _require_scratch_write_atomic()
> > {
> > _require_scratch
> > - export STATX_WRITE_ATOMIC=0x10000
> > -
> > awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
> > awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
> > @@ -51,6 +51,14 @@ _require_scratch_write_atomic()
> > fi
> > }
> > +# Check for xfs_io commands required to run _test_atomic_file_writes
> > +_require_atomic_write_test_commands()
> > +{
> > + _require_xfs_io_command "falloc"
> > + _require_xfs_io_command "fpunch"
> > + _require_xfs_io_command pwrite -A
> > +}
> > +
> > _test_atomic_file_writes()
> > {
> > local bsize="$1"
> > @@ -64,11 +72,7 @@ _test_atomic_file_writes()
> > test $bytes_written -eq $bsize || echo "atomic write len=$bsize failed"
> > # Check that we can perform an atomic single-block cow write
> > - if [ "$FSTYP" == "xfs" ]; then
> > - testfile_cp=$SCRATCH_MNT/testfile_copy
> > - if _xfs_has_feature $SCRATCH_MNT reflink; then
> > - cp --reflink $testfile $testfile_cp
> > - fi
> > + if cp --reflink=always $testfile $testfile_cp 2>> $seqres.full; then
>
> I suppose that previously for xfs where the cp --reflink failed, we would
> pointlessly try the write - am I correct?
Correct.
> If so, now seems much better.
That and any filesystem that supports reflink and atomic writes will now
test this. :)
Thanks for review!
--D
> > bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile_cp | \
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 4/6] common/atomicwrites: adjust a few more things
2025-05-14 0:29 ` [PATCH 4/6] common/atomicwrites: adjust a few more things Catherine Hoang
2025-05-14 13:11 ` John Garry
@ 2025-05-17 3:59 ` Ritesh Harjani
1 sibling, 0 replies; 29+ messages in thread
From: Ritesh Harjani @ 2025-05-17 3:59 UTC (permalink / raw)
To: Catherine Hoang, linux-xfs, fstests; +Cc: djwong, john.g.garry
Catherine Hoang <catherine.hoang@oracle.com> writes:
> From: "Darrick J. Wong" <djwong@kernel.org>
>
> Always export STATX_WRITE_ATOMIC so anyone can use it, make the "cp
> reflink" logic work for any filesystem, not just xfs, and create a
> separate helper to check that the necessary xfs_io support is present.
>
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> ---
> common/atomicwrites | 18 +++++++++++-------
> tests/generic/765 | 2 +-
> 2 files changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/common/atomicwrites b/common/atomicwrites
> index fd3a9b71..9ec1ca68 100644
> --- a/common/atomicwrites
> +++ b/common/atomicwrites
> @@ -4,6 +4,8 @@
> #
> # Routines for testing atomic writes.
>
> +export STATX_WRITE_ATOMIC=0x10000
> +
Finally we have this exported. Thanks for doing this :)
The changes looks good to me. Please feel free to add:
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
> _get_atomic_write_unit_min()
> {
> $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
> @@ -26,8 +28,6 @@ _require_scratch_write_atomic()
> {
> _require_scratch
>
> - export STATX_WRITE_ATOMIC=0x10000
> -
> awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
> awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
>
> @@ -51,6 +51,14 @@ _require_scratch_write_atomic()
> fi
> }
>
> +# Check for xfs_io commands required to run _test_atomic_file_writes
> +_require_atomic_write_test_commands()
> +{
> + _require_xfs_io_command "falloc"
> + _require_xfs_io_command "fpunch"
> + _require_xfs_io_command pwrite -A
> +}
> +
> _test_atomic_file_writes()
> {
> local bsize="$1"
> @@ -64,11 +72,7 @@ _test_atomic_file_writes()
> test $bytes_written -eq $bsize || echo "atomic write len=$bsize failed"
>
> # Check that we can perform an atomic single-block cow write
> - if [ "$FSTYP" == "xfs" ]; then
> - testfile_cp=$SCRATCH_MNT/testfile_copy
> - if _xfs_has_feature $SCRATCH_MNT reflink; then
> - cp --reflink $testfile $testfile_cp
> - fi
> + if cp --reflink=always $testfile $testfile_cp 2>> $seqres.full; then
> bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile_cp | \
> grep wrote | awk -F'[/ ]' '{print $2}')
> test $bytes_written -eq $bsize || echo "atomic write on reflinked file failed"
> diff --git a/tests/generic/765 b/tests/generic/765
> index 09e9fa38..71604e5e 100755
> --- a/tests/generic/765
> +++ b/tests/generic/765
> @@ -12,7 +12,7 @@ _begin_fstest auto quick rw atomicwrites
> . ./common/atomicwrites
>
> _require_scratch_write_atomic
> -_require_xfs_io_command pwrite -A
> +_require_atomic_write_test_commands
>
> get_supported_bsize()
> {
> --
> 2.34.1
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 5/6] common/atomicwrites: fix _require_scratch_write_atomic
2025-05-14 0:29 [PATCH 0/6] atomic writes tests Catherine Hoang
` (3 preceding siblings ...)
2025-05-14 0:29 ` [PATCH 4/6] common/atomicwrites: adjust a few more things Catherine Hoang
@ 2025-05-14 0:29 ` Catherine Hoang
2025-05-14 13:14 ` John Garry
2025-05-14 0:29 ` [PATCH 6/6] generic: various atomic write tests with scsi_debug Catherine Hoang
5 siblings, 1 reply; 29+ messages in thread
From: Catherine Hoang @ 2025-05-14 0:29 UTC (permalink / raw)
To: linux-xfs, fstests; +Cc: djwong, john.g.garry
From: "Darrick J. Wong" <djwong@kernel.org>
Fix this function to call _notrun whenever something fails. If we can't
figure out the atomic write geometry, then we haven't satisfied the
preconditions for the test.
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
---
common/atomicwrites | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/common/atomicwrites b/common/atomicwrites
index 9ec1ca68..391bb6f6 100644
--- a/common/atomicwrites
+++ b/common/atomicwrites
@@ -28,21 +28,23 @@ _require_scratch_write_atomic()
{
_require_scratch
- awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
- awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
+ local awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
+ local awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
if [ $awu_min_bdev -eq 0 ] && [ $awu_max_bdev -eq 0 ]; then
_notrun "write atomic not supported by this block device"
fi
- _scratch_mkfs > /dev/null 2>&1
- _scratch_mount
+ _scratch_mkfs > /dev/null 2>&1 || \
+ _notrun "cannot format scratch device for atomic write checks"
+ _try_scratch_mount || \
+ _notrun "cannot mount scratch device for atomic write checks"
- testfile=$SCRATCH_MNT/testfile
+ local testfile=$SCRATCH_MNT/testfile
touch $testfile
- awu_min_fs=$(_get_atomic_write_unit_min $testfile)
- awu_max_fs=$(_get_atomic_write_unit_max $testfile)
+ local awu_min_fs=$(_get_atomic_write_unit_min $testfile)
+ local awu_max_fs=$(_get_atomic_write_unit_max $testfile)
_scratch_unmount
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 6/6] generic: various atomic write tests with scsi_debug
2025-05-14 0:29 [PATCH 0/6] atomic writes tests Catherine Hoang
` (4 preceding siblings ...)
2025-05-14 0:29 ` [PATCH 5/6] common/atomicwrites: fix _require_scratch_write_atomic Catherine Hoang
@ 2025-05-14 0:29 ` Catherine Hoang
2025-05-14 13:41 ` John Garry
5 siblings, 1 reply; 29+ messages in thread
From: Catherine Hoang @ 2025-05-14 0:29 UTC (permalink / raw)
To: linux-xfs, fstests; +Cc: djwong, john.g.garry
From: "Darrick J. Wong" <djwong@kernel.org>
Simple tests of various atomic write requests and a (simulated) hardware
device.
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
---
common/atomicwrites | 10 +++
tests/generic/1222 | 86 +++++++++++++++++++++++++
tests/generic/1222.out | 10 +++
tests/generic/1223 | 66 +++++++++++++++++++
tests/generic/1223.out | 9 +++
tests/generic/1224 | 140 +++++++++++++++++++++++++++++++++++++++++
tests/generic/1224.out | 17 +++++
tests/generic/1225 | 51 +++++++++++++++
tests/generic/1225.out | 1 +
tests/xfs/1216 | 68 ++++++++++++++++++++
tests/xfs/1216.out | 9 +++
tests/xfs/1217 | 70 +++++++++++++++++++++
tests/xfs/1217.out | 3 +
tests/xfs/1218 | 59 +++++++++++++++++
tests/xfs/1218.out | 15 +++++
15 files changed, 614 insertions(+)
create mode 100755 tests/generic/1222
create mode 100644 tests/generic/1222.out
create mode 100755 tests/generic/1223
create mode 100644 tests/generic/1223.out
create mode 100644 tests/generic/1224
create mode 100644 tests/generic/1224.out
create mode 100644 tests/generic/1225
create mode 100644 tests/generic/1225.out
create mode 100755 tests/xfs/1216
create mode 100644 tests/xfs/1216.out
create mode 100755 tests/xfs/1217
create mode 100644 tests/xfs/1217.out
create mode 100644 tests/xfs/1218
create mode 100644 tests/xfs/1218.out
diff --git a/common/atomicwrites b/common/atomicwrites
index 391bb6f6..c75c3d39 100644
--- a/common/atomicwrites
+++ b/common/atomicwrites
@@ -115,3 +115,13 @@ _test_atomic_file_writes()
$XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 1 $bsize" $testfile 2>> $seqres.full && \
echo "atomic write requires offset to be aligned to bsize"
}
+
+_simple_atomic_write() {
+ local pos=$1
+ local count=$2
+ local file=$3
+ local directio=$4
+
+ echo "testing pos=$pos count=$count file=$file directio=$directio" >> $seqres.full
+ $XFS_IO_PROG $directio -c "pwrite -b $count -V 1 -A -D $pos $count" $file >> $seqres.full
+}
diff --git a/tests/generic/1222 b/tests/generic/1222
new file mode 100755
index 00000000..9d02bd70
--- /dev/null
+++ b/tests/generic/1222
@@ -0,0 +1,86 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Oracle. All Rights Reserved.
+#
+# FS QA Test 1222
+#
+# Validate multi-fsblock atomic write support with simulated hardware support
+#
+. ./common/preamble
+_begin_fstest auto quick rw atomicwrites
+
+. ./common/scsi_debug
+. ./common/atomicwrites
+
+_cleanup()
+{
+ _scratch_unmount &>/dev/null
+ _put_scsi_debug_dev &>/dev/null
+ cd /
+ rm -r -f $tmp.*
+}
+
+_require_scsi_debug
+_require_scratch_nocheck
+# Format something so that ./check doesn't freak out
+_scratch_mkfs >> $seqres.full
+
+# 512b logical/physical sectors, 512M size, atomic writes enabled
+dev=$(_get_scsi_debug_dev 512 512 0 512 "atomic_wr=1")
+test -b "$dev" || _notrun "could not create atomic writes scsi_debug device"
+
+export SCRATCH_DEV=$dev
+unset USE_EXTERNAL
+
+_require_scratch_write_atomic
+_require_atomic_write_test_commands
+
+echo "scsi_debug atomic write properties" >> $seqres.full
+$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full
+
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
+
+testfile=$SCRATCH_MNT/testfile
+touch $testfile
+
+echo "filesystem atomic write properties" >> $seqres.full
+$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
+
+sector_size=$(blockdev --getss $SCRATCH_DEV)
+min_awu=$(_get_atomic_write_unit_min $testfile)
+max_awu=$(_get_atomic_write_unit_max $testfile)
+
+$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
+
+# try outside the advertised sizes
+echo "two EINVAL for unsupported sizes"
+min_i=$((min_awu / 2))
+_simple_atomic_write $min_i $min_i $testfile -d
+max_i=$((max_awu * 2))
+_simple_atomic_write $max_i $max_i $testfile -d
+
+# try all of the advertised sizes
+echo "all should work"
+for ((i = min_awu; i <= max_awu; i *= 2)); do
+ $XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
+ _test_atomic_file_writes $i $testfile
+ _simple_atomic_write $i $i $testfile -d
+done
+
+# does not support buffered io
+echo "one EOPNOTSUPP for buffered atomic"
+_simple_atomic_write 0 $min_awu $testfile
+
+# does not support unaligned directio
+echo "one EINVAL for unaligned directio"
+_simple_atomic_write $sector_size $min_awu $testfile -d
+
+_scratch_unmount
+_put_scsi_debug_dev
+
+# success, all done
+echo Silence is golden
+status=0
+exit
diff --git a/tests/generic/1222.out b/tests/generic/1222.out
new file mode 100644
index 00000000..158b52fa
--- /dev/null
+++ b/tests/generic/1222.out
@@ -0,0 +1,10 @@
+QA output created by 1222
+two EINVAL for unsupported sizes
+pwrite: Invalid argument
+pwrite: Invalid argument
+all should work
+one EOPNOTSUPP for buffered atomic
+pwrite: Operation not supported
+one EINVAL for unaligned directio
+pwrite: Invalid argument
+Silence is golden
diff --git a/tests/generic/1223 b/tests/generic/1223
new file mode 100755
index 00000000..8a77386e
--- /dev/null
+++ b/tests/generic/1223
@@ -0,0 +1,66 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Oracle. All Rights Reserved.
+#
+# FS QA Test 1223
+#
+# Validate multi-fsblock atomic write support with or without hw support
+#
+. ./common/preamble
+_begin_fstest auto quick rw atomicwrites
+
+. ./common/atomicwrites
+
+_require_scratch
+_require_atomic_write_test_commands
+
+echo "scratch device atomic write properties" >> $seqres.full
+$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full
+
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
+
+testfile=$SCRATCH_MNT/testfile
+touch $testfile
+
+echo "filesystem atomic write properties" >> $seqres.full
+$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
+
+sector_size=$(blockdev --getss $SCRATCH_DEV)
+min_awu=$(_get_atomic_write_unit_min $testfile)
+max_awu=$(_get_atomic_write_unit_max $testfile)
+
+$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
+
+# try outside the advertised sizes
+echo "two EINVAL for unsupported sizes"
+min_i=$((min_awu / 2))
+_simple_atomic_write $min_i $min_i $testfile -d
+max_i=$((max_awu * 2))
+_simple_atomic_write $max_i $max_i $testfile -d
+
+# try all of the advertised sizes
+for ((i = min_awu; i <= max_awu; i *= 2)); do
+ $XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
+ _test_atomic_file_writes $i $testfile
+ _simple_atomic_write $i $i $testfile -d
+done
+
+# does not support buffered io
+echo "one EOPNOTSUPP for buffered atomic"
+_simple_atomic_write 0 $min_awu $testfile
+
+# does not support unaligned directio
+echo "one EINVAL for unaligned directio"
+if [ $sector_size -lt $min_awu ]; then
+ _simple_atomic_write $sector_size $min_awu $testfile -d
+else
+ # not supported, so fake the output
+ echo "pwrite: Invalid argument"
+fi
+
+# success, all done
+echo Silence is golden
+status=0
+exit
diff --git a/tests/generic/1223.out b/tests/generic/1223.out
new file mode 100644
index 00000000..edf5bd71
--- /dev/null
+++ b/tests/generic/1223.out
@@ -0,0 +1,9 @@
+QA output created by 1223
+two EINVAL for unsupported sizes
+pwrite: Invalid argument
+pwrite: Invalid argument
+one EOPNOTSUPP for buffered atomic
+pwrite: Operation not supported
+one EINVAL for unaligned directio
+pwrite: Invalid argument
+Silence is golden
diff --git a/tests/generic/1224 b/tests/generic/1224
new file mode 100644
index 00000000..fb178be4
--- /dev/null
+++ b/tests/generic/1224
@@ -0,0 +1,140 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Oracle. All Rights Reserved.
+#
+# FS QA Test 1224
+#
+# test large atomic writes with mixed mappings
+#
+. ./common/preamble
+_begin_fstest auto quick rw atomicwrites
+
+. ./common/atomicwrites
+. ./common/filter
+. ./common/reflink
+
+_require_scratch
+_require_atomic_write_test_commands
+_require_xfs_io_command pwrite -A
+_require_cp_reflink
+
+_scratch_mkfs_sized $((500 * 1048576)) >> $seqres.full 2>&1
+_scratch_mount
+
+file1=$SCRATCH_MNT/file1
+file2=$SCRATCH_MNT/file2
+file3=$SCRATCH_MNT/file3
+
+touch $file1
+
+max_awu=$(_get_atomic_write_unit_max $file1)
+test $max_awu -ge 262144 || _notrun "test requires atomic writes up to 256k"
+
+min_awu=$(_get_atomic_write_unit_min $file1)
+test $min_awu -le 4096 || _notrun "test requires atomic writes down to 4k"
+
+bsize=$(_get_file_block_size $SCRATCH_MNT)
+test $max_awu -gt $((bsize * 2)) || \
+ _notrun "max atomic write $max_awu less than 2 fsblocks $bsize"
+
+# reflink tests (files with shared extents)
+
+# atomic write shared data and unshared+shared data
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+cp --reflink=always $file1 $file2
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+md5sum $file2 | _filter_scratch
+
+# atomic write shared data and shared+unshared data
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+cp --reflink=always $file1 $file2
+$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+md5sum $file2 | _filter_scratch
+
+# atomic overwrite unshared data
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+cp --reflink=always $file1 $file2
+$XFS_IO_PROG -dc "pwrite -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+md5sum $file2 | _filter_scratch
+
+# atomic write shared+unshared+shared data
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+cp --reflink=always $file1 $file2
+$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+md5sum $file2 | _filter_scratch
+
+# atomic write interweaved hole+unwritten+written+reflinked
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+blksz=4096
+nr=32
+_weave_reflink_rainbow $blksz $nr $file1 $file2 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+md5sum $file2 | _filter_scratch
+
+# non-reflink tests
+
+# atomic write hole+mapped+hole
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+
+# atomic write adjacent mapped+hole and hole+mapped
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+
+# atomic write mapped+hole+mapped
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+
+# atomic write at EOF
+dd if=/dev/zero of=$file1 bs=128K count=3 conv=fsync >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 262144 262144" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+
+# atomic write preallocated region
+fallocate -l 10M $file1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+
+# atomic write max size
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+aw_max=$(_get_atomic_write_unit_max $file1)
+cp $file1 $file1.chk
+$XFS_IO_PROG -dc "pwrite -D -V1 0 $aw_max" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -c "pwrite 0 $aw_max" $file1.chk >>$seqres.full 2>&1
+cmp -s $file1 $file1.chk || echo "file1 doesnt match file1.chk"
+#md5sum $file1 | _filter_scratch
+
+# atomic write max size on fragmented fs
+avail=`_get_available_space $SCRATCH_MNT`
+filesizemb=$((avail / 1024 / 1024 - 1))
+fragmentedfile=$SCRATCH_MNT/fragmentedfile
+$XFS_IO_PROG -fc "falloc 0 ${filesizemb}m" $fragmentedfile
+$here/src/punch-alternating $fragmentedfile
+touch $file3
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file3 >>$seqres.full 2>&1
+md5sum $file3 | _filter_scratch
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/1224.out b/tests/generic/1224.out
new file mode 100644
index 00000000..1c788420
--- /dev/null
+++ b/tests/generic/1224.out
@@ -0,0 +1,17 @@
+QA output created by 1224
+111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
+f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
+111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
+f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
+111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
+f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
+111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
+f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
+4edfbc469bed9965219ea80c9ae54626 SCRATCH_MNT/file1
+93243a293a9f568903485b0b2a895815 SCRATCH_MNT/file2
+9464b66461bc1d20229e1b71733539d0 SCRATCH_MNT/file1
+9464b66461bc1d20229e1b71733539d0 SCRATCH_MNT/file1
+9464b66461bc1d20229e1b71733539d0 SCRATCH_MNT/file1
+75572c4929fde8faf131e84df4c6a764 SCRATCH_MNT/file1
+27a248351cd540bc9ac2c2dc841abca2 SCRATCH_MNT/file1
+27c9068d1b51da575a53ad34c57ca5cc SCRATCH_MNT/file3
diff --git a/tests/generic/1225 b/tests/generic/1225
new file mode 100644
index 00000000..600ada56
--- /dev/null
+++ b/tests/generic/1225
@@ -0,0 +1,51 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Oracle. All Rights Reserved.
+#
+# FS QA Test 1215
+#
+# fio test for large atomic writes
+#
+. ./common/preamble
+_begin_fstest aio rw stress atomicwrites
+
+. ./common/atomicwrites
+
+fio_config=$tmp.fio
+
+_require_scratch
+_require_atomic_write_test_commands
+_require_aio
+_require_odirect
+
+cat >$fio_config <<EOF
+[iops-test]
+directory=${SCRATCH_MNT}
+filesize=1M
+filename=testfile
+rw=write
+bs=16k
+ioengine=libaio
+loops=1000
+numjobs=10
+iodepth=1024
+group_reporting=1
+direct=1
+verify=crc64
+verify_write_sequence=0
+exitall_on_error=1
+atomic=1
+EOF
+
+_require_fio $fio_config
+
+_scratch_mkfs >> $seqres.full 2>&1
+_scratch_mount
+
+echo "Run fio with large atomic writes"
+cat $fio_config >> $seqres.full
+run_check $FIO_PROG $fio_config
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/1225.out b/tests/generic/1225.out
new file mode 100644
index 00000000..81e4ee0c
--- /dev/null
+++ b/tests/generic/1225.out
@@ -0,0 +1 @@
+QA output created by 1225
diff --git a/tests/xfs/1216 b/tests/xfs/1216
new file mode 100755
index 00000000..d9a10ed9
--- /dev/null
+++ b/tests/xfs/1216
@@ -0,0 +1,68 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Oracle. All Rights Reserved.
+#
+# FS QA Test 1216
+#
+# Validate multi-fsblock realtime file atomic write support with or without hw
+# support
+#
+. ./common/preamble
+_begin_fstest auto quick rw atomicwrites
+
+. ./common/atomicwrites
+
+_require_realtime
+_require_scratch
+_require_atomic_write_test_commands
+
+echo "scratch device atomic write properties" >> $seqres.full
+$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_RTDEV >> $seqres.full
+
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+test "$FSTYP" = "xfs" && _xfs_force_bdev realtime $SCRATCH_MNT
+
+testfile=$SCRATCH_MNT/testfile
+touch $testfile
+
+echo "filesystem atomic write properties" >> $seqres.full
+$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
+
+sector_size=$(blockdev --getss $SCRATCH_RTDEV)
+min_awu=$(_get_atomic_write_unit_min $testfile)
+max_awu=$(_get_atomic_write_unit_max $testfile)
+
+$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
+
+# try outside the advertised sizes
+echo "two EINVAL for unsupported sizes"
+min_i=$((min_awu / 2))
+_simple_atomic_write $min_i $min_i $testfile -d
+max_i=$((max_awu * 2))
+_simple_atomic_write $max_i $max_i $testfile -d
+
+# try all of the advertised sizes
+for ((i = min_awu; i <= max_awu; i *= 2)); do
+ $XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
+ _test_atomic_file_writes $i $testfile
+ _simple_atomic_write $i $i $testfile -d
+done
+
+# does not support buffered io
+echo "one EOPNOTSUPP for buffered atomic"
+_simple_atomic_write 0 $min_awu $testfile
+
+# does not support unaligned directio
+echo "one EINVAL for unaligned directio"
+if [ $sector_size -lt $min_awu ]; then
+ _simple_atomic_write $sector_size $min_awu $testfile -d
+else
+ # not supported, so fake the output
+ echo "pwrite: Invalid argument"
+fi
+
+# success, all done
+echo Silence is golden
+status=0
+exit
diff --git a/tests/xfs/1216.out b/tests/xfs/1216.out
new file mode 100644
index 00000000..51546082
--- /dev/null
+++ b/tests/xfs/1216.out
@@ -0,0 +1,9 @@
+QA output created by 1216
+two EINVAL for unsupported sizes
+pwrite: Invalid argument
+pwrite: Invalid argument
+one EOPNOTSUPP for buffered atomic
+pwrite: Operation not supported
+one EINVAL for unaligned directio
+pwrite: Invalid argument
+Silence is golden
diff --git a/tests/xfs/1217 b/tests/xfs/1217
new file mode 100755
index 00000000..012a1f46
--- /dev/null
+++ b/tests/xfs/1217
@@ -0,0 +1,70 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Oracle. All Rights Reserved.
+#
+# FS QA Test 1217
+#
+# Check that software atomic writes can complete an operation after a crash.
+#
+. ./common/preamble
+_begin_fstest auto quick rw atomicwrites
+
+. ./common/atomicwrites
+. ./common/inject
+. ./common/filter
+
+_require_scratch
+_require_atomic_write_test_commands
+_require_xfs_io_error_injection "free_extent"
+_require_test_program "punch-alternating"
+
+echo "scratch device atomic write properties" >> $seqres.full
+$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_RTDEV >> $seqres.full
+
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+
+testfile=$SCRATCH_MNT/testfile
+touch $testfile
+
+echo "filesystem atomic write properties" >> $seqres.full
+$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
+
+bsize=$(_get_file_block_size $SCRATCH_MNT)
+max_awu=$(_get_atomic_write_unit_max $testfile)
+
+test $max_awu -gt $((bsize * 2)) || \
+ _notrun "max atomic write $max_awu less than 2 fsblocks $bsize"
+
+# Create a fragmented file to force a software fallback
+$XFS_IO_PROG -f -c "pwrite -S 0x58 0 $((max_awu * 2))" $testfile >> $seqres.full
+$XFS_IO_PROG -f -c "pwrite -S 0x58 0 $((max_awu * 2))" $testfile.check >> $seqres.full
+$here/src/punch-alternating $testfile
+$here/src/punch-alternating $testfile.check
+$XFS_IO_PROG -c "pwrite -S 0xcd 0 $max_awu" $testfile.check >> $seqres.full
+$XFS_IO_PROG -c syncfs $SCRATCH_MNT
+
+# inject an error to force crash recovery on the ssecond block
+_scratch_inject_error "free_extent"
+_simple_atomic_write 0 $max_awu $testfile -d >> $seqres.full
+
+# make sure we're shut down
+touch $SCRATCH_MNT/barf 2>&1 | _filter_scratch
+
+# check that recovery worked
+_scratch_cycle_mount
+
+test -e $SCRATCH_MNT/barf && \
+ echo "saw $SCRATCH_MNT/barf that should not exist"
+
+if ! cmp -s $testfile $testfile.check; then
+ echo "crash recovery did not work"
+ md5sum $testfile
+ md5sum $testfile.check
+
+ od -tx1 -Ad -c $testfile >> $seqres.full
+ od -tx1 -Ad -c $testfile.check >> $seqres.full
+fi
+
+status=0
+exit
diff --git a/tests/xfs/1217.out b/tests/xfs/1217.out
new file mode 100644
index 00000000..6e5b22be
--- /dev/null
+++ b/tests/xfs/1217.out
@@ -0,0 +1,3 @@
+QA output created by 1217
+pwrite: Input/output error
+touch: cannot touch 'SCRATCH_MNT/barf': Input/output error
diff --git a/tests/xfs/1218 b/tests/xfs/1218
new file mode 100644
index 00000000..f3682e42
--- /dev/null
+++ b/tests/xfs/1218
@@ -0,0 +1,59 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Oracle. All Rights Reserved.
+#
+# FS QA Test 1218
+#
+# hardware large atomic writes error inject test
+#
+. ./common/preamble
+_begin_fstest auto rw quick atomicwrites
+
+. ./common/filter
+. ./common/inject
+. ./common/atomicwrites
+
+_require_scratch_write_atomic
+_require_xfs_io_command pwrite -A
+_require_xfs_io_error_injection "bmap_finish_one"
+
+_scratch_mkfs >> $seqres.full 2>&1
+_scratch_mount
+
+echo "Create files"
+file1=$SCRATCH_MNT/file1
+touch $file1
+
+max_awu=$(_get_atomic_write_unit_max $testfile)
+test $max_awu -ge 4096 || _notrun "cannot perform 4k atomic writes"
+
+file2=$SCRATCH_MNT/file2
+_pwrite_byte 0x66 0 64k $SCRATCH_MNT/file1 >> $seqres.full
+cp --reflink=always $file1 $file2
+
+echo "Check files"
+md5sum $SCRATCH_MNT/file1 | _filter_scratch
+md5sum $SCRATCH_MNT/file2 | _filter_scratch
+
+echo "Inject error"
+_scratch_inject_error "bmap_finish_one"
+
+echo "Atomic write to a reflinked file"
+$XFS_IO_PROG -dc "pwrite -A -D -V1 -S 0x67 0 4096" $file1
+
+echo "FS should be shut down, touch will fail"
+touch $SCRATCH_MNT/badfs 2>&1 | _filter_scratch
+
+echo "Remount to replay log"
+_scratch_remount_dump_log >> $seqres.full
+
+echo "Check files"
+md5sum $SCRATCH_MNT/file1 | _filter_scratch
+md5sum $SCRATCH_MNT/file2 | _filter_scratch
+
+echo "FS should be online, touch should succeed"
+touch $SCRATCH_MNT/goodfs 2>&1 | _filter_scratch
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1218.out b/tests/xfs/1218.out
new file mode 100644
index 00000000..02800213
--- /dev/null
+++ b/tests/xfs/1218.out
@@ -0,0 +1,15 @@
+QA output created by 1218
+Create files
+Check files
+77e3a730e3c75274c9ce310d7e39f938 SCRATCH_MNT/file1
+77e3a730e3c75274c9ce310d7e39f938 SCRATCH_MNT/file2
+Inject error
+Atomic write to a reflinked file
+pwrite: Input/output error
+FS should be shut down, touch will fail
+touch: cannot touch 'SCRATCH_MNT/badfs': Input/output error
+Remount to replay log
+Check files
+0df1f61ed02a7e9bee2b8b7665066ddc SCRATCH_MNT/file1
+77e3a730e3c75274c9ce310d7e39f938 SCRATCH_MNT/file2
+FS should be online, touch should succeed
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH 6/6] generic: various atomic write tests with scsi_debug
2025-05-14 0:29 ` [PATCH 6/6] generic: various atomic write tests with scsi_debug Catherine Hoang
@ 2025-05-14 13:41 ` John Garry
2025-05-14 16:01 ` Darrick J. Wong
0 siblings, 1 reply; 29+ messages in thread
From: John Garry @ 2025-05-14 13:41 UTC (permalink / raw)
To: Catherine Hoang, linux-xfs, fstests; +Cc: djwong
> +++ b/tests/generic/1222
> @@ -0,0 +1,86 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle. All Rights Reserved.
> +#
> +# FS QA Test 1222
> +#
> +# Validate multi-fsblock atomic write support with simulated hardware support
> +#
> +. ./common/preamble
> +_begin_fstest auto quick rw atomicwrites
> +
> +. ./common/scsi_debug
> +. ./common/atomicwrites
> +
> +_cleanup()
> +{
> + _scratch_unmount &>/dev/null
> + _put_scsi_debug_dev &>/dev/null
> + cd /
> + rm -r -f $tmp.*
> +}
> +
> +_require_scsi_debug
> +_require_scratch_nocheck
> +# Format something so that ./check doesn't freak out
> +_scratch_mkfs >> $seqres.full
> +
> +# 512b logical/physical sectors, 512M size, atomic writes enabled
> +dev=$(_get_scsi_debug_dev 512 512 0 512 "atomic_wr=1")
> +test -b "$dev" || _notrun "could not create atomic writes scsi_debug device"
> +
> +export SCRATCH_DEV=$dev
> +unset USE_EXTERNAL
> +
> +_require_scratch_write_atomic
> +_require_atomic_write_test_commands
> +
> +echo "scsi_debug atomic write properties" >> $seqres.full
> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full
> +
> +_scratch_mkfs >> $seqres.full
> +_scratch_mount
> +test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
> +
> +testfile=$SCRATCH_MNT/testfile
> +touch $testfile
> +
> +echo "filesystem atomic write properties" >> $seqres.full
> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
> +
> +sector_size=$(blockdev --getss $SCRATCH_DEV)
> +min_awu=$(_get_atomic_write_unit_min $testfile)
> +max_awu=$(_get_atomic_write_unit_max $testfile)
> +
> +$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> +
> +# try outside the advertised sizes
> +echo "two EINVAL for unsupported sizes"
> +min_i=$((min_awu / 2))
> +_simple_atomic_write $min_i $min_i $testfile -d
> +max_i=$((max_awu * 2))
> +_simple_atomic_write $max_i $max_i $testfile -d
> +
> +# try all of the advertised sizes
> +echo "all should work"
> +for ((i = min_awu; i <= max_awu; i *= 2)); do
> + $XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> + _test_atomic_file_writes $i $testfile
> + _simple_atomic_write $i $i $testfile -d
> +done
> +
> +# does not support buffered io
> +echo "one EOPNOTSUPP for buffered atomic"
> +_simple_atomic_write 0 $min_awu $testfile
> +
> +# does not support unaligned directio
> +echo "one EINVAL for unaligned directio"
> +_simple_atomic_write $sector_size $min_awu $testfile -d
I figure that $sector_size is default at 512, which would never be equal
to fsblocksize (so the test looks ok)
> +
> +_scratch_unmount
> +_put_scsi_debug_dev
> +
> +# success, all done
> +echo Silence is golden
> +status=0
> +exit
> diff --git a/tests/generic/1222.out b/tests/generic/1222.out
> new file mode 100644
> index 00000000..158b52fa
> --- /dev/null
> +++ b/tests/generic/1222.out
> @@ -0,0 +1,10 @@
> +QA output created by 1222
> +two EINVAL for unsupported sizes
> +pwrite: Invalid argument
> +pwrite: Invalid argument
> +all should work
> +one EOPNOTSUPP for buffered atomic
> +pwrite: Operation not supported
> +one EINVAL for unaligned directio
> +pwrite: Invalid argument
> +Silence is golden
> diff --git a/tests/generic/1223 b/tests/generic/1223
> new file mode 100755
> index 00000000..8a77386e
> --- /dev/null
> +++ b/tests/generic/1223
> @@ -0,0 +1,66 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle. All Rights Reserved.
> +#
> +# FS QA Test 1223
> +#
> +# Validate multi-fsblock atomic write support with or without hw support
> +#
> +. ./common/preamble
> +_begin_fstest auto quick rw atomicwrites
> +
> +. ./common/atomicwrites
> +
> +_require_scratch
> +_require_atomic_write_test_commands
> +
> +echo "scratch device atomic write properties" >> $seqres.full
> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full
> +
> +_scratch_mkfs >> $seqres.full
> +_scratch_mount
> +test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
> +
> +testfile=$SCRATCH_MNT/testfile
> +touch $testfile
> +
> +echo "filesystem atomic write properties" >> $seqres.full
> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
> +
> +sector_size=$(blockdev --getss $SCRATCH_DEV)
> +min_awu=$(_get_atomic_write_unit_min $testfile)
> +max_awu=$(_get_atomic_write_unit_max $testfile)
> +
> +$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> +
It seems many sub-tests are same as 1222
It is difficult to factor them out?
> +# try outside the advertised sizes
> +echo "two EINVAL for unsupported sizes"
> +min_i=$((min_awu / 2))
> +_simple_atomic_write $min_i $min_i $testfile -d
> +max_i=$((max_awu * 2))
> +_simple_atomic_write $max_i $max_i $testfile -d
> +
> +# try all of the advertised sizes
> +for ((i = min_awu; i <= max_awu; i *= 2)); do
> + $XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> + _test_atomic_file_writes $i $testfile
> + _simple_atomic_write $i $i $testfile -d
> +done
> +
> +# does not support buffered io
> +echo "one EOPNOTSUPP for buffered atomic"
> +_simple_atomic_write 0 $min_awu $testfile
> +
> +# does not support unaligned directio
> +echo "one EINVAL for unaligned directio"
> +if [ $sector_size -lt $min_awu ]; then
> + _simple_atomic_write $sector_size $min_awu $testfile -d
> +else
> + # not supported, so fake the output
> + echo "pwrite: Invalid argument"
> +fi
> +
> +# success, all done
> +echo Silence is golden
> +status=0
> +exit
> diff --git a/tests/generic/1223.out b/tests/generic/1223.out
> new file mode 100644
> index 00000000..edf5bd71
> --- /dev/null
> +++ b/tests/generic/1223.out
> @@ -0,0 +1,9 @@
> +QA output created by 1223
> +two EINVAL for unsupported sizes
> +pwrite: Invalid argument
> +pwrite: Invalid argument
> +one EOPNOTSUPP for buffered atomic
> +pwrite: Operation not supported
> +one EINVAL for unaligned directio
> +pwrite: Invalid argument
> +Silence is golden
> diff --git a/tests/generic/1224 b/tests/generic/1224
> new file mode 100644
> index 00000000..fb178be4
> --- /dev/null
> +++ b/tests/generic/1224
> @@ -0,0 +1,140 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle. All Rights Reserved.
> +#
> +# FS QA Test 1224
> +#
> +# test large atomic writes with mixed mappings
> +#
> +. ./common/preamble
> +_begin_fstest auto quick rw atomicwrites
> +
> +. ./common/atomicwrites
> +. ./common/filter
> +. ./common/reflink
> +
> +_require_scratch
> +_require_atomic_write_test_commands
> +_require_xfs_io_command pwrite -A
> +_require_cp_reflink
> +
> +_scratch_mkfs_sized $((500 * 1048576)) >> $seqres.full 2>&1
> +_scratch_mount
> +
> +file1=$SCRATCH_MNT/file1
> +file2=$SCRATCH_MNT/file2
> +file3=$SCRATCH_MNT/file3
> +
> +touch $file1
> +
> +max_awu=$(_get_atomic_write_unit_max $file1)
> +test $max_awu -ge 262144 || _notrun "test requires atomic writes up to 256k"
> +
> +min_awu=$(_get_atomic_write_unit_min $file1)
> +test $min_awu -le 4096 || _notrun "test requires atomic writes down to 4k"
> +
> +bsize=$(_get_file_block_size $SCRATCH_MNT)
> +test $max_awu -gt $((bsize * 2)) || \
> + _notrun "max atomic write $max_awu less than 2 fsblocks $bsize"
> +
> +# reflink tests (files with shared extents)
> +
> +# atomic write shared data and unshared+shared data
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +cp --reflink=always $file1 $file2
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +md5sum $file2 | _filter_scratch
> +
> +# atomic write shared data and shared+unshared data
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +cp --reflink=always $file1 $file2
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +md5sum $file2 | _filter_scratch
> +
> +# atomic overwrite unshared data
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +cp --reflink=always $file1 $file2
> +$XFS_IO_PROG -dc "pwrite -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +md5sum $file2 | _filter_scratch
> +
> +# atomic write shared+unshared+shared data
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +cp --reflink=always $file1 $file2
> +$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +md5sum $file2 | _filter_scratch
> +
> +# atomic write interweaved hole+unwritten+written+reflinked
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +blksz=4096
> +nr=32
> +_weave_reflink_rainbow $blksz $nr $file1 $file2 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +md5sum $file2 | _filter_scratch
> +
> +# non-reflink tests
> +
> +# atomic write hole+mapped+hole
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +
> +# atomic write adjacent mapped+hole and hole+mapped
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +
> +# atomic write mapped+hole+mapped
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +
> +# atomic write at EOF
> +dd if=/dev/zero of=$file1 bs=128K count=3 conv=fsync >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 262144 262144" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +
> +# atomic write preallocated region
> +fallocate -l 10M $file1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +
> +# atomic write max size
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +aw_max=$(_get_atomic_write_unit_max $file1)
> +cp $file1 $file1.chk
> +$XFS_IO_PROG -dc "pwrite -D -V1 0 $aw_max" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -c "pwrite 0 $aw_max" $file1.chk >>$seqres.full 2>&1
> +cmp -s $file1 $file1.chk || echo "file1 doesnt match file1.chk"
> +#md5sum $file1 | _filter_scratch
> +
> +# atomic write max size on fragmented fs
> +avail=`_get_available_space $SCRATCH_MNT`
> +filesizemb=$((avail / 1024 / 1024 - 1))
> +fragmentedfile=$SCRATCH_MNT/fragmentedfile
> +$XFS_IO_PROG -fc "falloc 0 ${filesizemb}m" $fragmentedfile
> +$here/src/punch-alternating $fragmentedfile
> +touch $file3
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file3 >>$seqres.full 2>&1
> +md5sum $file3 | _filter_scratch
nice :)
But we also test RWF_NOWAIT at some stage?
RWF_NOWAIT should fail always for filesystem-based atomic write
> +
> +# success, all done
> +status=0
> +exit
> diff --git a/tests/generic/1224.out b/tests/generic/1224.out
> new file mode 100644
> index 00000000..1c788420
> --- /dev/null
> +++ b/tests/generic/1224.out
> @@ -0,0 +1,17 @@
> +QA output created by 1224
> +111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
> +f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
> +111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
> +f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
> +111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
> +f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
> +111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
> +f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
> +4edfbc469bed9965219ea80c9ae54626 SCRATCH_MNT/file1
> +93243a293a9f568903485b0b2a895815 SCRATCH_MNT/file2
> +9464b66461bc1d20229e1b71733539d0 SCRATCH_MNT/file1
> +9464b66461bc1d20229e1b71733539d0 SCRATCH_MNT/file1
> +9464b66461bc1d20229e1b71733539d0 SCRATCH_MNT/file1
> +75572c4929fde8faf131e84df4c6a764 SCRATCH_MNT/file1
> +27a248351cd540bc9ac2c2dc841abca2 SCRATCH_MNT/file1
> +27c9068d1b51da575a53ad34c57ca5cc SCRATCH_MNT/file3
> diff --git a/tests/generic/1225 b/tests/generic/1225
> new file mode 100644
> index 00000000..600ada56
> --- /dev/null
> +++ b/tests/generic/1225
I think that we should now omit this test. We don't guarantee
serialization of atomic writes, so no point in testing it.
I should have confirmed this earlier, sorry
> @@ -0,0 +1,51 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle. All Rights Reserved.
> +#
> +# FS QA Test 1215
> +#
> +# fio test for large atomic writes
> +#
> +. ./common/preamble
> +_begin_fstest aio rw stress atomicwrites
> +
> +. ./common/atomicwrites
> +
> +fio_config=$tmp.fio
> +
> +_require_scratch
> +_require_atomic_write_test_commands
> +_require_aio
> +_require_odirect
> +
> +cat >$fio_config <<EOF
> +[iops-test]
> +directory=${SCRATCH_MNT}
> +filesize=1M
> +filename=testfile
> +rw=write
> +bs=16k
> +ioengine=libaio
> +loops=1000
> +numjobs=10
> +iodepth=1024
> +group_reporting=1
> +direct=1
> +verify=crc64
> +verify_write_sequence=0
> +exitall_on_error=1
> +atomic=1
> +EOF
> +
> +_require_fio $fio_config
> +
> +_scratch_mkfs >> $seqres.full 2>&1
> +_scratch_mount
> +
> +echo "Run fio with large atomic writes"
> +cat $fio_config >> $seqres.full
> +run_check $FIO_PROG $fio_config
> +
> +# success, all done
> +status=0
> +exit
> diff --git a/tests/generic/1225.out b/tests/generic/1225.out
> new file mode 100644
> index 00000000..81e4ee0c
> --- /dev/null
> +++ b/tests/generic/1225.out
> @@ -0,0 +1 @@
> +QA output created by 1225
> diff --git a/tests/xfs/1216 b/tests/xfs/1216
> new file mode 100755
> index 00000000..d9a10ed9
> --- /dev/null
> +++ b/tests/xfs/1216
> @@ -0,0 +1,68 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle. All Rights Reserved.
> +#
> +# FS QA Test 1216
> +#
> +# Validate multi-fsblock realtime file atomic write support with or without hw
> +# support
nice to see rtvol being tested.
> +#
> +. ./common/preamble
> +_begin_fstest auto quick rw atomicwrites
> +
> +. ./common/atomicwrites
> +
> +_require_realtime
> +_require_scratch
> +_require_atomic_write_test_commands
> +
> +echo "scratch device atomic write properties" >> $seqres.full
> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_RTDEV >> $seqres.full
> +
> +_scratch_mkfs >> $seqres.full
> +_scratch_mount
> +test "$FSTYP" = "xfs" && _xfs_force_bdev realtime $SCRATCH_MNT
> +
> +testfile=$SCRATCH_MNT/testfile
> +touch $testfile
> +
> +echo "filesystem atomic write properties" >> $seqres.full
> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
> +
> +sector_size=$(blockdev --getss $SCRATCH_RTDEV)
> +min_awu=$(_get_atomic_write_unit_min $testfile)
> +max_awu=$(_get_atomic_write_unit_max $testfile)
> +
> +$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> +
> +# try outside the advertised sizes
> +echo "two EINVAL for unsupported sizes"
> +min_i=$((min_awu / 2))
> +_simple_atomic_write $min_i $min_i $testfile -d
> +max_i=$((max_awu * 2))
> +_simple_atomic_write $max_i $max_i $testfile -d
> +
> +# try all of the advertised sizes
> +for ((i = min_awu; i <= max_awu; i *= 2)); do
> + $XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> + _test_atomic_file_writes $i $testfile
> + _simple_atomic_write $i $i $testfile -d
> +done
> +
> +# does not support buffered io
> +echo "one EOPNOTSUPP for buffered atomic"
> +_simple_atomic_write 0 $min_awu $testfile
> +
> +# does not support unaligned directio
> +echo "one EINVAL for unaligned directio"
> +if [ $sector_size -lt $min_awu ]; then
> + _simple_atomic_write $sector_size $min_awu $testfile -d
> +else
> + # not supported, so fake the output
> + echo "pwrite: Invalid argument"
> +fi
> +
> +# success, all done
> +echo Silence is golden
> +status=0
> +exit
> diff --git a/tests/xfs/1216.out b/tests/xfs/1216.out
> new file mode 100644
> index 00000000..51546082
> --- /dev/null
> +++ b/tests/xfs/1216.out
> @@ -0,0 +1,9 @@
> +QA output created by 1216
> +two EINVAL for unsupported sizes
> +pwrite: Invalid argument
> +pwrite: Invalid argument
> +one EOPNOTSUPP for buffered atomic
> +pwrite: Operation not supported
> +one EINVAL for unaligned directio
> +pwrite: Invalid argument
> +Silence is golden
> diff --git a/tests/xfs/1217 b/tests/xfs/1217
> new file mode 100755
> index 00000000..012a1f46
> --- /dev/null
> +++ b/tests/xfs/1217
> @@ -0,0 +1,70 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle. All Rights Reserved.
> +#
> +# FS QA Test 1217
> +#
> +# Check that software atomic writes can complete an operation after a crash.
> +#
Could we prove that we get a torn write for a regular non-atomic write also?
> +. ./common/preamble
> +_begin_fstest auto quick rw atomicwrites
> +
Thanks,
John
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 6/6] generic: various atomic write tests with scsi_debug
2025-05-14 13:41 ` John Garry
@ 2025-05-14 16:01 ` Darrick J. Wong
2025-05-14 16:30 ` John Garry
2025-05-14 23:49 ` Catherine Hoang
0 siblings, 2 replies; 29+ messages in thread
From: Darrick J. Wong @ 2025-05-14 16:01 UTC (permalink / raw)
To: John Garry; +Cc: Catherine Hoang, linux-xfs, fstests
On Wed, May 14, 2025 at 02:41:40PM +0100, John Garry wrote:
>
> > +++ b/tests/generic/1222
> > @@ -0,0 +1,86 @@
<snip>
> > +# try all of the advertised sizes
> > +echo "all should work"
> > +for ((i = min_awu; i <= max_awu; i *= 2)); do
> > + $XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> > + _test_atomic_file_writes $i $testfile
> > + _simple_atomic_write $i $i $testfile -d
> > +done
> > +
> > +# does not support buffered io
> > +echo "one EOPNOTSUPP for buffered atomic"
> > +_simple_atomic_write 0 $min_awu $testfile
> > +
> > +# does not support unaligned directio
> > +echo "one EINVAL for unaligned directio"
> > +_simple_atomic_write $sector_size $min_awu $testfile -d
>
> I figure that $sector_size is default at 512, which would never be equal to
> fsblocksize (so the test looks ok)
For now, yes -- the only filesystems supporting atomic writes (ext4 and
XFS v5) don't support 512b fsblocks.
<snip>
> > diff --git a/tests/generic/1223 b/tests/generic/1223
> > new file mode 100755
> > index 00000000..8a77386e
> > --- /dev/null
> > +++ b/tests/generic/1223
> > @@ -0,0 +1,66 @@
> > +#! /bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2025 Oracle. All Rights Reserved.
> > +#
> > +# FS QA Test 1223
> > +#
> > +# Validate multi-fsblock atomic write support with or without hw support
> > +#
> > +. ./common/preamble
> > +_begin_fstest auto quick rw atomicwrites
> > +
> > +. ./common/atomicwrites
> > +
> > +_require_scratch
> > +_require_atomic_write_test_commands
> > +
> > +echo "scratch device atomic write properties" >> $seqres.full
> > +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full
> > +
> > +_scratch_mkfs >> $seqres.full
> > +_scratch_mount
> > +test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
> > +
> > +testfile=$SCRATCH_MNT/testfile
> > +touch $testfile
> > +
> > +echo "filesystem atomic write properties" >> $seqres.full
> > +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
> > +
> > +sector_size=$(blockdev --getss $SCRATCH_DEV)
> > +min_awu=$(_get_atomic_write_unit_min $testfile)
> > +max_awu=$(_get_atomic_write_unit_max $testfile)
> > +
> > +$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> > +
>
> It seems many sub-tests are same as 1222
>
> It is difficult to factor them out?
Yes. g/1222 will _notrun itself if the scsi_debug module isn't present
or the fake device cannot be created. Apparently many of the people who
run fstests also have test infrastructure that cannot handle modules, so
they don't run anything involving scsi_debug.
That's why g/1223 only requires that the scratch fs advertises some sort
of atomic write capability, it doesn't care how it provides that.
<snip>
> > diff --git a/tests/generic/1224 b/tests/generic/1224
> > new file mode 100644
> > index 00000000..fb178be4
> > --- /dev/null
> > +++ b/tests/generic/1224
<snip>
> > +# atomic write max size
> > +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> > +aw_max=$(_get_atomic_write_unit_max $file1)
> > +cp $file1 $file1.chk
> > +$XFS_IO_PROG -dc "pwrite -D -V1 0 $aw_max" $file1 >>$seqres.full 2>&1
> > +$XFS_IO_PROG -c "pwrite 0 $aw_max" $file1.chk >>$seqres.full 2>&1
> > +cmp -s $file1 $file1.chk || echo "file1 doesnt match file1.chk"
> > +#md5sum $file1 | _filter_scratch
> > +
> > +# atomic write max size on fragmented fs
> > +avail=`_get_available_space $SCRATCH_MNT`
> > +filesizemb=$((avail / 1024 / 1024 - 1))
> > +fragmentedfile=$SCRATCH_MNT/fragmentedfile
> > +$XFS_IO_PROG -fc "falloc 0 ${filesizemb}m" $fragmentedfile
> > +$here/src/punch-alternating $fragmentedfile
> > +touch $file3
> > +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file3 >>$seqres.full 2>&1
> > +md5sum $file3 | _filter_scratch
>
> nice :)
>
> But we also test RWF_NOWAIT at some stage?
>
> RWF_NOWAIT should fail always for filesystem-based atomic write
It's hard to test NOWAIT because the selected io path might not actually
encounter contention, and there are various things that NOWAIT will wait
on anyway (like memory allocation and metadata reads).
<snip>
> > diff --git a/tests/generic/1225 b/tests/generic/1225
> > new file mode 100644
> > index 00000000..600ada56
> > --- /dev/null
> > +++ b/tests/generic/1225
>
> I think that we should now omit this test. We don't guarantee serialization
> of atomic writes, so no point in testing it.
>
> I should have confirmed this earlier, sorry
Ok.
<snip>
> > diff --git a/tests/xfs/1216 b/tests/xfs/1216
> > new file mode 100755
> > index 00000000..d9a10ed9
> > --- /dev/null
> > +++ b/tests/xfs/1216
> > @@ -0,0 +1,68 @@
> > +#! /bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2025 Oracle. All Rights Reserved.
> > +#
> > +# FS QA Test 1216
> > +#
> > +# Validate multi-fsblock realtime file atomic write support with or without hw
> > +# support
>
> nice to see rtvol being tested.
Thanks. :)
> > +#
> > +. ./common/preamble
> > +_begin_fstest auto quick rw atomicwrites
> > +
> > +. ./common/atomicwrites
> > +
> > +_require_realtime
> > +_require_scratch
> > +_require_atomic_write_test_commands
> > +
> > +echo "scratch device atomic write properties" >> $seqres.full
> > +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_RTDEV >> $seqres.full
> > +
> > +_scratch_mkfs >> $seqres.full
> > +_scratch_mount
> > +test "$FSTYP" = "xfs" && _xfs_force_bdev realtime $SCRATCH_MNT
Don't need this FSTYP test here, FSTYP is always xfs.
<snip>
> > diff --git a/tests/xfs/1217 b/tests/xfs/1217
> > new file mode 100755
> > index 00000000..012a1f46
> > --- /dev/null
> > +++ b/tests/xfs/1217
> > @@ -0,0 +1,70 @@
> > +#! /bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2025 Oracle. All Rights Reserved.
> > +#
> > +# FS QA Test 1217
> > +#
> > +# Check that software atomic writes can complete an operation after a crash.
> > +#
>
> Could we prove that we get a torn write for a regular non-atomic write also?
Perhaps? But I don't see the point -- non-atomic write completions
could be done atomically.
--D
> > +. ./common/preamble
> > +_begin_fstest auto quick rw atomicwrites
> > +
>
> Thanks,
> John
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 6/6] generic: various atomic write tests with scsi_debug
2025-05-14 16:01 ` Darrick J. Wong
@ 2025-05-14 16:30 ` John Garry
2025-05-14 23:49 ` Catherine Hoang
1 sibling, 0 replies; 29+ messages in thread
From: John Garry @ 2025-05-14 16:30 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: Catherine Hoang, linux-xfs, fstests
On 14/05/2025 17:01, Darrick J. Wong wrote:
>> It seems many sub-tests are same as 1222
>>
>> It is difficult to factor them out?
> Yes. g/1222 will _notrun itself if the scsi_debug module isn't present
> or the fake device cannot be created. Apparently many of the people who
> run fstests also have test infrastructure that cannot handle modules, so
> they don't run anything involving scsi_debug.
ok...
>
> That's why g/1223 only requires that the scratch fs advertises some sort
> of atomic write capability, it doesn't care how it provides that.
>
> <snip>
>
>>> diff --git a/tests/generic/1224 b/tests/generic/1224
>>> new file mode 100644
>>> index 00000000..fb178be4
>>> --- /dev/null
>>> +++ b/tests/generic/1224
> <snip>
>>
>> But we also test RWF_NOWAIT at some stage?
>>
>> RWF_NOWAIT should fail always for filesystem-based atomic write
> It's hard to test NOWAIT because the selected io path might not actually
> encounter contention, and there are various things that NOWAIT will wait
> on anyway (like memory allocation and metadata reads).
The filesystem-based atomic write will always try to allocate blocks,
and this will fail for NOWAIT.
But, come to think of it, this is not even a useful test - so forget the
suggestion. I was just testing this as a sanity check to prove that we
are getting expected behavior.
>
> <snip>
>
>
>>> diff --git a/tests/xfs/1217 b/tests/xfs/1217
>>> new file mode 100755
>>> index 00000000..012a1f46
>>> --- /dev/null
>>> +++ b/tests/xfs/1217
>>> @@ -0,0 +1,70 @@
>>> +#! /bin/bash
>>> +# SPDX-License-Identifier: GPL-2.0
>>> +# Copyright (c) 2025 Oracle. All Rights Reserved.
>>> +#
>>> +# FS QA Test 1217
>>> +#
>>> +# Check that software atomic writes can complete an operation after a crash.
>>> +#
>> Could we prove that we get a torn write for a regular non-atomic write also?
> Perhaps? But I don't see the point -- non-atomic write completions
> could be done atomically.
oh, from my reading of the test, I thought that we were ensuring that we
are writing over many extents, and so could not be completed atomically
for a non-atomic write.
BTW, there is a typo in a comment for that test, please see "ssecond block"
Thanks,
John
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 6/6] generic: various atomic write tests with scsi_debug
2025-05-14 16:01 ` Darrick J. Wong
2025-05-14 16:30 ` John Garry
@ 2025-05-14 23:49 ` Catherine Hoang
1 sibling, 0 replies; 29+ messages in thread
From: Catherine Hoang @ 2025-05-14 23:49 UTC (permalink / raw)
To: Darrick J. Wong
Cc: John Garry, linux-xfs@vger.kernel.org, fstests@vger.kernel.org
> On May 14, 2025, at 9:01 AM, Darrick J. Wong <djwong@kernel.org> wrote:
>
> On Wed, May 14, 2025 at 02:41:40PM +0100, John Garry wrote:
>>
>>> +++ b/tests/generic/1222
>>> @@ -0,0 +1,86 @@
>
> <snip>
>
>>> +# try all of the advertised sizes
>>> +echo "all should work"
>>> +for ((i = min_awu; i <= max_awu; i *= 2)); do
>>> + $XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
>>> + _test_atomic_file_writes $i $testfile
>>> + _simple_atomic_write $i $i $testfile -d
>>> +done
>>> +
>>> +# does not support buffered io
>>> +echo "one EOPNOTSUPP for buffered atomic"
>>> +_simple_atomic_write 0 $min_awu $testfile
>>> +
>>> +# does not support unaligned directio
>>> +echo "one EINVAL for unaligned directio"
>>> +_simple_atomic_write $sector_size $min_awu $testfile -d
>>
>> I figure that $sector_size is default at 512, which would never be equal to
>> fsblocksize (so the test looks ok)
>
> For now, yes -- the only filesystems supporting atomic writes (ext4 and
> XFS v5) don't support 512b fsblocks.
>
> <snip>
>
>>> diff --git a/tests/generic/1223 b/tests/generic/1223
>>> new file mode 100755
>>> index 00000000..8a77386e
>>> --- /dev/null
>>> +++ b/tests/generic/1223
>>> @@ -0,0 +1,66 @@
>>> +#! /bin/bash
>>> +# SPDX-License-Identifier: GPL-2.0
>>> +# Copyright (c) 2025 Oracle. All Rights Reserved.
>>> +#
>>> +# FS QA Test 1223
>>> +#
>>> +# Validate multi-fsblock atomic write support with or without hw support
>>> +#
>>> +. ./common/preamble
>>> +_begin_fstest auto quick rw atomicwrites
>>> +
>>> +. ./common/atomicwrites
>>> +
>>> +_require_scratch
>>> +_require_atomic_write_test_commands
>>> +
>>> +echo "scratch device atomic write properties" >> $seqres.full
>>> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full
>>> +
>>> +_scratch_mkfs >> $seqres.full
>>> +_scratch_mount
>>> +test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
>>> +
>>> +testfile=$SCRATCH_MNT/testfile
>>> +touch $testfile
>>> +
>>> +echo "filesystem atomic write properties" >> $seqres.full
>>> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
>>> +
>>> +sector_size=$(blockdev --getss $SCRATCH_DEV)
>>> +min_awu=$(_get_atomic_write_unit_min $testfile)
>>> +max_awu=$(_get_atomic_write_unit_max $testfile)
>>> +
>>> +$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
>>> +
>>
>> It seems many sub-tests are same as 1222
>>
>> It is difficult to factor them out?
>
> Yes. g/1222 will _notrun itself if the scsi_debug module isn't present
> or the fake device cannot be created. Apparently many of the people who
> run fstests also have test infrastructure that cannot handle modules, so
> they don't run anything involving scsi_debug.
>
> That's why g/1223 only requires that the scratch fs advertises some sort
> of atomic write capability, it doesn't care how it provides that.
>
> <snip>
>
>>> diff --git a/tests/generic/1224 b/tests/generic/1224
>>> new file mode 100644
>>> index 00000000..fb178be4
>>> --- /dev/null
>>> +++ b/tests/generic/1224
>
> <snip>
>
>>> +# atomic write max size
>>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>>> +aw_max=$(_get_atomic_write_unit_max $file1)
>>> +cp $file1 $file1.chk
>>> +$XFS_IO_PROG -dc "pwrite -D -V1 0 $aw_max" $file1 >>$seqres.full 2>&1
>>> +$XFS_IO_PROG -c "pwrite 0 $aw_max" $file1.chk >>$seqres.full 2>&1
>>> +cmp -s $file1 $file1.chk || echo "file1 doesnt match file1.chk"
>>> +#md5sum $file1 | _filter_scratch
>>> +
>>> +# atomic write max size on fragmented fs
>>> +avail=`_get_available_space $SCRATCH_MNT`
>>> +filesizemb=$((avail / 1024 / 1024 - 1))
>>> +fragmentedfile=$SCRATCH_MNT/fragmentedfile
>>> +$XFS_IO_PROG -fc "falloc 0 ${filesizemb}m" $fragmentedfile
>>> +$here/src/punch-alternating $fragmentedfile
>>> +touch $file3
>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file3 >>$seqres.full 2>&1
>>> +md5sum $file3 | _filter_scratch
>>
>> nice :)
>>
>> But we also test RWF_NOWAIT at some stage?
>>
>> RWF_NOWAIT should fail always for filesystem-based atomic write
>
> It's hard to test NOWAIT because the selected io path might not actually
> encounter contention, and there are various things that NOWAIT will wait
> on anyway (like memory allocation and metadata reads).
>
> <snip>
>
>>> diff --git a/tests/generic/1225 b/tests/generic/1225
>>> new file mode 100644
>>> index 00000000..600ada56
>>> --- /dev/null
>>> +++ b/tests/generic/1225
>>
>> I think that we should now omit this test. We don't guarantee serialization
>> of atomic writes, so no point in testing it.
>>
>> I should have confirmed this earlier, sorry
>
> Ok.
>
> <snip>
Ok, I’ll remove this test
>
>>> diff --git a/tests/xfs/1216 b/tests/xfs/1216
>>> new file mode 100755
>>> index 00000000..d9a10ed9
>>> --- /dev/null
>>> +++ b/tests/xfs/1216
>>> @@ -0,0 +1,68 @@
>>> +#! /bin/bash
>>> +# SPDX-License-Identifier: GPL-2.0
>>> +# Copyright (c) 2025 Oracle. All Rights Reserved.
>>> +#
>>> +# FS QA Test 1216
>>> +#
>>> +# Validate multi-fsblock realtime file atomic write support with or without hw
>>> +# support
>>
>> nice to see rtvol being tested.
>
> Thanks. :)
>
>>> +#
>>> +. ./common/preamble
>>> +_begin_fstest auto quick rw atomicwrites
>>> +
>>> +. ./common/atomicwrites
>>> +
>>> +_require_realtime
>>> +_require_scratch
>>> +_require_atomic_write_test_commands
>>> +
>>> +echo "scratch device atomic write properties" >> $seqres.full
>>> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_RTDEV >> $seqres.full
>>> +
>>> +_scratch_mkfs >> $seqres.full
>>> +_scratch_mount
>>> +test "$FSTYP" = "xfs" && _xfs_force_bdev realtime $SCRATCH_MNT
>
> Don't need this FSTYP test here, FSTYP is always xfs.
>
> <snip>
Ok, will remove this as well, thanks!
>
>>> diff --git a/tests/xfs/1217 b/tests/xfs/1217
>>> new file mode 100755
>>> index 00000000..012a1f46
>>> --- /dev/null
>>> +++ b/tests/xfs/1217
>>> @@ -0,0 +1,70 @@
>>> +#! /bin/bash
>>> +# SPDX-License-Identifier: GPL-2.0
>>> +# Copyright (c) 2025 Oracle. All Rights Reserved.
>>> +#
>>> +# FS QA Test 1217
>>> +#
>>> +# Check that software atomic writes can complete an operation after a crash.
>>> +#
>>
>> Could we prove that we get a torn write for a regular non-atomic write also?
>
> Perhaps? But I don't see the point -- non-atomic write completions
> could be done atomically.
>
> --D
>
>>> +. ./common/preamble
>>> +_begin_fstest auto quick rw atomicwrites
>>> +
>>
>> Thanks,
>> John
^ permalink raw reply [flat|nested] 29+ messages in thread