On NFS, try to discover the allocation size for the exported filesystem. NFS st_blksize is optimized for the network, and will usually be much larger than the allocation size of the exported filesystem, which may trigger preallocation strategies in the exported filesystem causing the seek tests here to fail. Signed-off-by: Benjamin Coddington <bcodding@xxxxxxxxxx> --- src/seek_sanity_test.c | 57 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/src/seek_sanity_test.c b/src/seek_sanity_test.c index 18262c2b0493..5455cdb0824e 100644 --- a/src/seek_sanity_test.c +++ b/src/seek_sanity_test.c @@ -39,21 +39,54 @@ static blksize_t alloc_size; int default_behavior = 0; char *base_file_path; -static void get_file_system(int fd) +/* + * NFS' st_blksize is typically set to maximize network + * efficiency, and will not be indicative of the allocation + * size of the exported filesystem. Try to determine the size + * using SEEK_DATA. + */ +static void get_nfs_alloc_size(int fd) { - struct statfs buf; - - if (!fstatfs(fd, &buf)) { - fprintf(stdout, "File system magic#: 0x%lx\n", - (unsigned long int)buf.f_type); - } + int shift; + off_t pos = 0, offset = 1; + + /* walk up */ + while (pos == 0 && offset < alloc_size) { + offset <<= 1; + ftruncate(fd, 0); + pwrite(fd, "a", 1, offset); + pos = lseek(fd, 0, SEEK_DATA); + } + + /* bisect */ + shift = offset >> 2; + while (shift && offset < alloc_size) { + ftruncate(fd, 0); + pwrite(fd, "a", 1, offset); + pos = lseek(fd, 0, SEEK_DATA); + offset += pos ? -shift : shift; + shift >>= 1; + } + if (!shift) + offset += pos ? 0 : 1; + alloc_size = offset; } -static int get_io_sizes(int fd) +#define NFS_SUPER_MAGIC 0x6969 + +static int get_fs_info(int fd) { struct stat buf; + struct statfs fsbuf; int ret; + ret = fstatfs(fd, &fsbuf); + if (ret) + fprintf(stderr, " ERROR %d: Failed to get fs info\n", + errno); + fprintf(stdout, "File system magic#: 0x%lx\n", + (unsigned long int)fsbuf.f_type); + ret = fstat(fd, &buf); if (ret) fprintf(stderr, " ERROR %d: Failed to find io blocksize\n", @@ -61,6 +94,10 @@ static int get_io_sizes(int fd) /* st_blksize is typically also the allocation size */ alloc_size = buf.st_blksize; + + if (fsbuf.f_type == NFS_SUPER_MAGIC) + get_nfs_alloc_size(fd); + fprintf(stdout, "Allocation size: %ld\n", alloc_size); return ret; @@ -709,9 +746,7 @@ static int test_basic_support(void) if (fd == -1) goto out; - get_file_system(fd); - - ret = get_io_sizes(fd); + ret = get_fs_info(fd); if (ret) goto out; -- 2.5.5 -- To unsubscribe from this list: send the line "unsubscribe fstests" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html