Hi, guys. Recently I hit a regression during test xfstest. Reverting this commit could fix that error. Reproduce steps (only nfs4.2 has this error): ``` # cat local.config export TEST_DEV=127.0.0.1:/home/nfs/share0 export TEST_DIR=/mnt/test export SCRATCH_DEV=127.0.0.1:/home/nfs/share1 export SCRATCH_MNT=/mnt/scratch export FSX_AVOID="-E" export NFS_MOUNT_OPTIONS="-o rw,relatime,vers=4.2" # ./check -nfs generic/285 FSTYP -- nfs PLATFORM -- Linux/aarch64 hpe-apollo80-01-n00 5.14.0-131.el9.aarch64 #1 SMP PREEMPT_DYNAMIC Mon Jul 18 16:13:44 EDT 2022 MKFS_OPTIONS -- 127.0.0.1:/home/nfs/share1 MOUNT_OPTIONS -- -o rw,relatime,vers=4.2 -o context=system_u:object_r:root_t:s0 127.0.0.1:/home/nfs/share1 /mnt/scratch generic/285 2s ... [failed, exit status 1]- output mismatch (see /root/xfstests/results//generic/285.out.bad) --- tests/generic/285.out 2022-07-27 21:07:43.160268552 -0400 +++ /root/xfstests/results//generic/285.out.bad 2022-07-27 21:31:27.887090532 -0400 @@ -1 +1,3 @@ QA output created by 285 +seek sanity check failed! +(see /root/xfstests/results//generic/285.full for details) ... (Run 'diff -u /root/xfstests/tests/generic/285.out /root/xfstests/results//generic/285.out.bad' to see the entire diff) Ran: generic/285 Failures: generic/285 Failed 1 of 1 tests ``` Reverting this commit then test pass. ``` # git revert e861a30255c9780425ee5193325d30882fbe7410 # make -j && make install -j ---snip--- # ./check -nfs generic/285 FSTYP -- nfs PLATFORM -- Linux/aarch64 hpe-apollo80-01-n00 5.14.0-131.el9.aarch64 #1 SMP PREEMPT_DYNAMIC Mon Jul 18 16:13:44 EDT 2022 MKFS_OPTIONS -- 127.0.0.1:/home/nfs/share1 MOUNT_OPTIONS -- -o rw,relatime,vers=4.2 -o context=system_u:object_r:root_t:s0 127.0.0.1:/home/nfs/share1 /mnt/scratch generic/285 1s ... 1s Ran: generic/285 Passed all 1 tests ``` On 6/29/22 04:21, Darrick J. Wong wrote: > From: Darrick J. Wong <djwong@xxxxxxxxxx> > > The seek sanity test tries to figure out a file space allocation unit by > calling stat and then using an iterative SEEK_DATA method to try to > detect a smaller blocksize based on SEEK_DATA's consultation of the > filesystem's internal block mapping. This was put in (AFAICT) because > XFS' stat implementation returns max(filesystem blocksize, PAGESIZE) for > most regular files. > > Unfortunately, for a realtime file with an extent size larger than a > single filesystem block this doesn't work at all because block mappings > still work at filesystem block granularity, but allocation units do not. > To fix this, detect the specific case where st_blksize != PAGE_SIZE and > trust the fstat results. > > Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> > --- > src/seek_sanity_test.c | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > > diff --git a/src/seek_sanity_test.c b/src/seek_sanity_test.c > index 76587b7f..1030d0c5 100644 > --- a/src/seek_sanity_test.c > +++ b/src/seek_sanity_test.c > @@ -45,6 +45,7 @@ static int get_io_sizes(int fd) > off_t pos = 0, offset = 1; > struct stat buf; > int shift, ret; > + int pagesz = sysconf(_SC_PAGE_SIZE); > > ret = fstat(fd, &buf); > if (ret) { > @@ -53,8 +54,16 @@ static int get_io_sizes(int fd) > return ret; > } > > - /* st_blksize is typically also the allocation size */ > + /* > + * st_blksize is typically also the allocation size. However, XFS > + * rounds this up to the page size, so if the stat blocksize is exactly > + * one page, use this iterative algorithm to see if SEEK_DATA will hint > + * at a more precise answer based on the filesystem's (pre)allocation > + * decisions. > + */ > alloc_size = buf.st_blksize; > + if (alloc_size != pagesz) > + goto done; > > /* try to discover the actual alloc size */ > while (pos == 0 && offset < alloc_size) { > @@ -80,6 +89,7 @@ static int get_io_sizes(int fd) > if (!shift) > offset += pos ? 0 : 1; > alloc_size = offset; > +done: > fprintf(stdout, "Allocation size: %ld\n", alloc_size); > return 0; > >