- offset = td->o.start_offset + td->subjob_number * td->o.offset_increment;
- if (offset % td_max_bs(td))
- offset -= (offset % td_max_bs(td));
+ 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 +
+ td->subjob_number * o->offset_increment;
+ }