From 8c43ba6259409244de64f0b1d388a029e38cf3e5 Mon Sep 17 00:00:00 2001 From: Sitsofe Wheeler Date: Mon, 21 Aug 2017 22:15:00 +0100 Subject: [PATCH] filesetup: align layout buffer Since commit 6e344dc3445bfec0583072e82bea728ab8d54d58 ("filesetup: keep OS_O_DIRECT flag when pre-allocating file") when direct=1 fio will set the OS_O_DIRECT flag during file layout. Unfortunately this makes the following job fail with due to an "Invalid argument" on Linux: $ rm -f fiodirect.tmp; ./fio --direct=1 --bs=4k --filename=fiodirect.tmp \ --size=16k --name=directtest directtest: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=psync, iodepth=1 fio-3.0-9-gb427 Starting 1 process directtest: Laying out IO file (1 file / 0MiB) fio: pid=35410, err=22/file:filesetup.c:227, func=write, error=Invalid argument (where fiodirect.tmp is on a filesystem that supports O_DIRECT such as ext4 and the job used to succeed) The open(2) man page for Linux says: "Under Linux 2.4, transfer sizes, and the alignment of the user buffer and the file offset must all be multiples of the logical block size of the filesystem. Since Linux 2.6.0, alignment to the logical block size of the underlying storage (typically 512 bytes) suffices." The above is cryptic but suggests that on Linux 2.6 and above kernels the transfer size, the *memory alignment of the user buffer* and the file offset must all be multiples of the underlying logical block size when using O_DIRECT. This commit forces the memory of fio's layout I/O buffer to be aligned to the system's page size in an attempt to meet the memory alignment requirement. Altough approximate, this should handle all but the most unusual setups for the near future and matches what init_io_u() does in backend.c. v2: - Align buffer pointer to page size rather than maximum block size - Update commit message, include example Fixes https://github.com/axboe/fio/issues/429 . Signed-off-by: Sitsofe Wheeler --- filesetup.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/filesetup.c b/filesetup.c index 0e5599ab..b9d68c45 100644 --- a/filesetup.c +++ b/filesetup.c @@ -15,6 +15,7 @@ #include "os/os.h" #include "hash.h" #include "lib/axmap.h" +#include "lib/memalign.h" #ifdef CONFIG_LINUX_FALLOCATE #include @@ -194,9 +195,9 @@ static int extend_file(struct thread_data *td, struct fio_file *f) if (bs > left) bs = left; - b = malloc(bs); + b = fio_memalign(page_size, bs); if (!b) { - td_verror(td, errno, "malloc"); + td_verror(td, errno, "fio_memalign"); goto err; } @@ -249,14 +250,14 @@ static int extend_file(struct thread_data *td, struct fio_file *f) f->io_size = f->real_file_size; } - free(b); + fio_memfree(b, bs); done: return 0; err: close(f->fd); f->fd = -1; if (b) - free(b); + fio_memfree(b, bs); return 1; } -- 2.25.1