summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2022-07-28 11:17:26 -0700
committerZorro Lang <zlang@kernel.org>2022-07-31 22:06:46 +0800
commitb91889d79e1d92e22860504e40108a2e4d054c33 (patch)
tree57863fcb059d7bcf0ad75710c132296287e2a1d6 /src
parent91f2a0f472e6a247a68b00585871ac5e247543e1 (diff)
seek_sanity_test: use XFS ioctls to determine file allocation unit sizev2022.07.31
liuyd.fnst@fujitsu.com reported that my recent change to the seek sanity test broke NFS. I foolishly thought that st_blksize was sufficient to find the file allocation unit size so that applications could figure out the SEEK_HOLE granularity. Replace that with an explicit callout to XFS ioctls so that xfs realtime will work again. Fixes: e861a302 ("seek_sanity_test: fix allocation unit detection on XFS realtime") Reported-by: liuyd.fnst@fujitsu.com Tested-by: liuyd.fnst@fujitsu.com Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Zorro Lang <zlang@redhat.com> Signed-off-by: Zorro Lang <zlang@kernel.org>
Diffstat (limited to 'src')
-rw-r--r--src/seek_sanity_test.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/src/seek_sanity_test.c b/src/seek_sanity_test.c
index 1030d0c5..78f835e8 100644
--- a/src/seek_sanity_test.c
+++ b/src/seek_sanity_test.c
@@ -40,6 +40,28 @@ static void get_file_system(int fd)
}
}
+/* Compute the file allocation unit size for an XFS file. */
+static int detect_xfs_alloc_unit(int fd)
+{
+ struct fsxattr fsx;
+ struct xfs_fsop_geom fsgeom;
+ int ret;
+
+ ret = ioctl(fd, XFS_IOC_FSGEOMETRY, &fsgeom);
+ if (ret)
+ return -1;
+
+ ret = ioctl(fd, XFS_IOC_FSGETXATTR, &fsx);
+ if (ret)
+ return -1;
+
+ alloc_size = fsgeom.blocksize;
+ if (fsx.fsx_xflags & XFS_XFLAG_REALTIME)
+ alloc_size *= fsgeom.rtextsize;
+
+ return 0;
+}
+
static int get_io_sizes(int fd)
{
off_t pos = 0, offset = 1;
@@ -47,6 +69,10 @@ static int get_io_sizes(int fd)
int shift, ret;
int pagesz = sysconf(_SC_PAGE_SIZE);
+ ret = detect_xfs_alloc_unit(fd);
+ if (!ret)
+ goto done;
+
ret = fstat(fd, &buf);
if (ret) {
fprintf(stderr, " ERROR %d: Failed to find io blocksize\n",
@@ -54,16 +80,8 @@ static int get_io_sizes(int fd)
return ret;
}
- /*
- * 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.
- */
+ /* st_blksize is typically also the allocation size */
alloc_size = buf.st_blksize;
- if (alloc_size != pagesz)
- goto done;
/* try to discover the actual alloc size */
while (pos == 0 && offset < alloc_size) {