[PATCH] Fix fileoffset option
authorljzhang,Yaxin Hu,Jianchao Tang <nonggia@sjtu.edu.cn>
Fri, 27 Jul 2007 11:28:26 +0000 (13:28 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Fri, 27 Jul 2007 11:28:26 +0000 (13:28 +0200)
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 <jens.axboe@oracle.com>
filesetup.c
io_u.c
ioengines.c

index 62240cd08d6650d85c43a267204aacd4be4914e9..b8b22b5a54da51504b369b67975c46ef10f95084 100644 (file)
@@ -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) {
        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
                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;
                         * 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) {
                } 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)
                        /*
                         * 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
                        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;
 
                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 &&
                        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++;
                    !(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;
                        f->flags |= FIO_FILE_EXTEND;
-               }
+               }       
        }
 
        if (!td->o.size || td->o.size > total_size)
        }
 
        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;
 
                        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;
                        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;
 
        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)
 }
 
 int init_random_map(struct thread_data *td)
diff --git a/io_u.c b/io_u.c
index 55f3c78c72cbd773cf24a503e30814a9c788e1cf..4750ac600a4272142bc85ccf9333382fcb1a4d28 100644 (file)
--- 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;
                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;
        }
 
        io_u->offset = (b * td->o.min_bs[ddir]) + f->file_offset;
index 76e71b9ee4ef1e6cf3c2c23ebc8d036c8d98b04e..8cdabe6f2551dd5217d1927f46a0836b8ac8a053 100644 (file)
@@ -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_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;
 
        f->flags |= FIO_FILE_OPEN;
        f->flags &= ~FIO_FILE_CLOSING;