From 76e4bb4f68641458c90b490a9481cf148c10e002 Mon Sep 17 00:00:00 2001 From: Sitsofe Wheeler Date: Sun, 4 Jun 2017 08:22:08 +0100 Subject: [PATCH] filesetup: fix size percentage calculations when using offset "When an fio job uses a non-zero offset value and a non-zero size parameter, the working set size on disk is skewed. For a 64k file, the job provided touches the following blocks: dd if=/dev/zero of=/tmp/fiofile bs=64k count=1 fio --stonewall --filename=/tmp/fiofile --rw=write \ --name=firstquarter --size=25% --offset=0 --buffer_pattern=0x11 \ --name=secondquarter --size=25% --offset=16k --buffer_pattern=0x22 \ --name=thirdquarter --size=25% --offset=32k --buffer_pattern=0x33 |1111111111111111|222222222222----|33333333--------|----------------| 0 16k 32k 48k 64k 1=written by firstquarter, 2=written by secondquarter, 3=written by thirdquarter It seems the expected vs. actual math on working set size is (size_param_percent * size_of_file) vs. (size_param_percent * (size_of_file - offset))." Fix this by always calculating the percentage of the full file's size. Also bound the I/O to be within the existing file's size when using a size percentage to handle the case where the addition of an offset would otherwise force I/O to go beyond the existing file size e.g.: dd if=/dev/zero of=/tmp/fiofile bs=64k count=1 fio --stonewall --filename=/tmp/fiofile --rw=write \ --name=beyond --size=100% --offset=32k --buffer_pattern=0x11 In the above, we ensure we only do 32k of I/O (rather than the 64k implied by size=100%). Fixes: https://github.com/axboe/fio/issues/377 ("Non-zero offset and non-zero size skew disk working set size") Reported-by: Brantley West Signed-off-by: Sitsofe Wheeler --- filesetup.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/filesetup.c b/filesetup.c index 612e7947..8a0968d6 100644 --- a/filesetup.c +++ b/filesetup.c @@ -986,7 +986,14 @@ int setup_files(struct thread_data *td) total_size = -1ULL; else { if (o->size_percent) { - f->io_size = (f->io_size * o->size_percent) / 100; + uint64_t file_size; + + file_size = f->io_size + f->file_offset; + f->io_size = (file_size * + o->size_percent) / 100; + if (f->io_size > (file_size - f->file_offset)) + f->io_size = file_size - f->file_offset; + f->io_size -= (f->io_size % td_min_bs(td)); } total_size += f->io_size; -- 2.25.1