From bcdedd0ac6e9413258b608ecb3511867b1a9c534 Mon Sep 17 00:00:00 2001 From: "ljzhang,Yaxin Hu,Jianchao Tang" Date: Fri, 27 Jul 2007 13:28:26 +0200 Subject: [PATCH] [PATCH] Fix fileoffset option 1. The job file we prepared: ----------offset----------------- [global] filename=./temp/HOWTO nrfiles=1 rw=read size=8K offset=16k bs=1k thread loops=10 [offset] description="Option 'offset' doesn't work." --------------------------------- Besides, we copied the file HOWTO to the directory ./temp/. So we thought fio would read 8K text sequentially from the point 16K off the beginning of HOWTO. we run fio with gdb to see what was read out after the first io, and we got this: --------------------------------- ... ... (gdb) bt from /lib/tls/i686/cmov/libpthread.so.0 (gdb) x/4w io_u->xfer_buf 0x8073f08: 0x6c626154 0x666f2065 0x6e6f6320 0x746e6574 (gdb) --------------------------------- The above was performed after the first io finished by td_io_queue. The contents read out as we can see was the ASCII codes for 'Table of content', which was right from the beginning of file HOWTO. That means fio read from the beginning but not the point 16K off the beginning.Is that right? 2. Reason for the problem: It seems the offset is saved in td->o.start_offset. But it isn't passed to f->file_offset.And the setting up of f->io_size doesn't refer to f->file_offset. -------------------------------------------------------- And now we can check it with gdb: -------------------------------------------------------- ... ... (gdb) bt from /lib/tls/i686/cmov/libpthread.so.0 (gdb) x/4w io_u->xfer_buf 0x8073f08: 0x206b636f 0x7420666f 0x66206568 0x20656c69 (gdb) --------------------------------------------------------- After the first io, I got '0x206b636f 0x7420666f 0x66206568 0x20656c69' read out.And they represent the string 'ock of the file '.Then i search the string in HOWTO and got only one line containing the string: 'norandommap Normally fio will cover every block of the file when doing' I removed the text following that line in HOWTO, and then I found that the size of the rest text in HOWTO was 16K, which equaled to the offset we set in job file. So I think the option 'offset' does work after the changes. In fact, I am not sure of the fix, but i do hope it can help. Signed-off-by: Jens Axboe --- filesetup.c | 32 ++++++++++++++++++++++---------- io_u.c | 5 ++--- ioengines.c | 2 +- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/filesetup.c b/filesetup.c index 62240cd0..b8b22b5a 100644 --- a/filesetup.c +++ b/filesetup.c @@ -378,6 +378,8 @@ int setup_files(struct thread_data *td) extend_size = total_size = 0; need_extend = 0; for_each_file(td, f, i) { + f->file_offset = td->o.start_offset; + if (!td->o.file_size_low) { /* * no file size range given, file size is equal to @@ -385,20 +387,27 @@ int setup_files(struct thread_data *td) * zero, set it to the real file size. */ f->io_size = td->o.size / td->o.nr_files; - if (!f->io_size) - f->io_size = f->real_file_size; + if (!f->io_size) { + if (f->file_offset > f->real_file_size) + goto err_offset; + f->io_size = f->real_file_size - f->file_offset; + } } else if (f->real_file_size < td->o.file_size_low || f->real_file_size > td->o.file_size_high) { + if (f->file_offset > td->o.file_size_low) + goto err_offset; /* * file size given. if it's fixed, use that. if it's a * range, generate a random size in-between. */ if (td->o.file_size_low == td->o.file_size_high) - f->io_size = td->o.file_size_low; + f->io_size = td->o.file_size_low - f->file_offset; else - f->io_size = get_rand_file_size(td); - } else - f->io_size = f->real_file_size; + f->io_size = get_rand_file_size(td) - f->file_offset; + } else if (f->file_offset > f->real_file_size) + goto err_offset; + else + f->io_size = f->real_file_size - f->file_offset; if (f->io_size == -1ULL) total_size = -1ULL; @@ -406,12 +415,12 @@ int setup_files(struct thread_data *td) total_size += f->io_size; if (f->filetype == FIO_TYPE_FILE && - f->io_size > f->real_file_size && + (f->io_size + f->file_offset) > f->real_file_size && !(td->io_ops->flags & FIO_DISKLESSIO)) { need_extend++; - extend_size += f->io_size; + extend_size += (f->io_size + f->file_offset); f->flags |= FIO_FILE_EXTEND; - } + } } if (!td->o.size || td->o.size > total_size) @@ -431,7 +440,7 @@ int setup_files(struct thread_data *td) assert(f->filetype == FIO_TYPE_FILE); f->flags &= ~FIO_FILE_EXTEND; - f->real_file_size = f->io_size; + f->real_file_size = (f->io_size + f->file_offset); err = extend_file(td, f); if (err) break; @@ -447,6 +456,9 @@ int setup_files(struct thread_data *td) td->total_io_size = td->o.size * td->o.loops; return 0; +err_offset: + log_err("%s: you need to specify valid offset=\n", td->o.name); + return 1; } int init_random_map(struct thread_data *td) diff --git a/io_u.c b/io_u.c index 55f3c78c..4750ac60 100644 --- a/io_u.c +++ b/io_u.c @@ -165,9 +165,8 @@ static int get_next_offset(struct thread_data *td, struct io_u *io_u) if (f->last_pos >= f->real_file_size) { if (!td_random(td) || get_next_rand_offset(td, f, ddir, &b)) return 1; - } else { - b = f->last_pos / td->o.min_bs[ddir]; - } + } else + b = (f->last_pos - f->file_offset) / td->o.min_bs[ddir]; } io_u->offset = (b * td->o.min_bs[ddir]) + f->file_offset; diff --git a/ioengines.c b/ioengines.c index 76e71b9e..8cdabe6f 100644 --- a/ioengines.c +++ b/ioengines.c @@ -279,7 +279,7 @@ int td_io_open_file(struct thread_data *td, struct fio_file *f) f->last_free_lookup = 0; f->last_completed_pos = 0; - f->last_pos = 0; + f->last_pos = f->file_offset; f->flags |= FIO_FILE_OPEN; f->flags &= ~FIO_FILE_CLOSING; -- 2.25.1