allow a percent value for the offset parameter
[fio.git] / filesetup.c
index cd486eaa41186ec3668e22b687ec868962b2a571..25ce0c0d88852a162d7afcc1f02952116f7cf842 100644 (file)
@@ -239,6 +239,9 @@ static int pre_read_file(struct thread_data *td, struct fio_file *f)
            td_ioengine_flagged(td, FIO_NOIO))
                return 0;
 
+       if (f->filetype == FIO_TYPE_CHAR)
+               return 0;
+
        if (!fio_file_open(f)) {
                if (td->io_ops->open_file(td, f)) {
                        log_err("fio: cannot pre-read, failed to open file\n");
@@ -830,12 +833,35 @@ static unsigned long long get_fs_free_counts(struct thread_data *td)
 uint64_t get_start_offset(struct thread_data *td, struct fio_file *f)
 {
        struct thread_options *o = &td->o;
+       unsigned long long align_bs;  /* align the offset to this block size */
+       unsigned long long offset;  /* align_bs-aligned offset */
 
        if (o->file_append && f->filetype == FIO_TYPE_FILE)
                return f->real_file_size;
 
-       return td->o.start_offset +
-               td->subjob_number * td->o.offset_increment;
+       if (o->start_offset_percent > 0) {
+
+               /* if blockalign is provided, find the min across read, write, and trim */
+               if (fio_option_is_set(o, ba)) {
+                       align_bs = (unsigned long long) min(o->ba[DDIR_READ], o->ba[DDIR_WRITE]);
+                       align_bs = min((unsigned long long) o->ba[DDIR_TRIM], align_bs);
+               } else {  /* else take the minimum block size */
+                       align_bs = td_min_bs(td);
+               }
+
+               /* calculate the raw offset */
+               offset = (f->real_file_size * o->start_offset_percent / 100) +
+                       (td->subjob_number * o->offset_increment);
+
+               /* block align the offset at the next available boundary at
+                  ceiling(offset / align_bs) * align_bs */
+               offset = (offset / align_bs + (offset % align_bs != 0)) * align_bs;
+
+       } else {  /* start_offset_percent not set */
+               offset = o->start_offset + o->start_offset +
+                       td->subjob_number * o->offset_increment;
+       }
+       return offset;
 }
 
 /*