]> www.infradead.org Git - users/hch/xfstests-dev.git/commitdiff
seek_sanity_test: fix allocation unit detection on XFS realtime
authorDarrick J. Wong <djwong@kernel.org>
Tue, 28 Jun 2022 20:21:23 +0000 (13:21 -0700)
committerZorro Lang <zlang@kernel.org>
Sat, 2 Jul 2022 13:32:43 +0000 (21:32 +0800)
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@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Zorro Lang <zlang@kernel.org>
src/seek_sanity_test.c

index 76587b7f13197d0424183a79434666e7bc0caa1f..1030d0c564bee26c7d5ad636ef7e3305c1b16d5c 100644 (file)
@@ -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;