if (max_size > f->real_file_size)
max_size = f->real_file_size;
- max_blocks = max_size / (unsigned long long) td->o.min_bs[ddir];
+ max_blocks = max_size / (unsigned long long) td->o.ba[ddir];
if (!max_blocks)
return 0;
i = f->last_free_lookup;
*b = (i * BLOCKS_PER_MAP);
- while ((*b) * min_bs < f->real_file_size) {
+ while ((*b) * min_bs < f->real_file_size &&
+ (*b) * min_bs < f->io_size) {
if (f->file_map[i] != (unsigned int) -1) {
*b += ffz(f->file_map[i]);
if (*b > last_block(td, f, ddir))
b = (f->last_pos - f->file_offset) / td->o.min_bs[ddir];
}
- io_u->offset = b * td->o.min_bs[ddir];
+ io_u->offset = b * td->o.ba[ddir];
if (io_u->offset >= f->io_size) {
dprint(FD_IO, "get_next_offset: offset %llu >= io_size %llu\n",
io_u->offset, f->io_size);
buflen = minbs;
else {
r = os_random_long(&td->bsrange_state);
- if (!td->o.bssplit_nr) {
+ if (!td->o.bssplit_nr[ddir]) {
buflen = 1 + (unsigned int) ((double) maxbs *
(r / (OS_RAND_MAX + 1.0)));
if (buflen < minbs)
long perc = 0;
unsigned int i;
- for (i = 0; i < td->o.bssplit_nr; i++) {
- struct bssplit *bsp = &td->o.bssplit[i];
+ for (i = 0; i < td->o.bssplit_nr[ddir]; i++) {
+ struct bssplit *bsp = &td->o.bssplit[ddir][i];
buflen = bsp->bs;
perc += bsp->perc;
do {
long r = os_random_long(&td->next_file_state);
+ int opened = 0;
fno = (unsigned int) ((double) td->o.nr_files
* (r / (OS_RAND_MAX + 1.0)));
if (f->flags & FIO_FILE_DONE)
continue;
+ if (!(f->flags & FIO_FILE_OPEN)) {
+ int err;
+
+ err = td_io_open_file(td, f);
+ if (err)
+ continue;
+ opened = 1;
+ }
+
if ((!goodf || (f->flags & goodf)) && !(f->flags & badf)) {
dprint(FD_FILE, "get_next_file_rand: %p\n", f);
return f;
}
+ if (opened)
+ td_io_close_file(td, f);
} while (1);
}
struct fio_file *f;
do {
+ int opened = 0;
+
f = td->files[td->next_file];
td->next_file++;
if (td->next_file >= td->o.nr_files)
td->next_file = 0;
+ dprint(FD_FILE, "trying file %s %x\n", f->file_name, f->flags);
if (f->flags & FIO_FILE_DONE) {
f = NULL;
continue;
}
+ if (!(f->flags & FIO_FILE_OPEN)) {
+ int err;
+
+ err = td_io_open_file(td, f);
+ if (err) {
+ dprint(FD_FILE, "error %d on open of %s\n",
+ err, f->file_name);
+ continue;
+ }
+ opened = 1;
+ }
+
+ dprint(FD_FILE, "goodf=%x, badf=%x, ff=%x\n", goodf, badf, f->flags);
if ((!goodf || (f->flags & goodf)) && !(f->flags & badf))
break;
+ if (opened)
+ td_io_close_file(td, f);
+
f = NULL;
} while (td->next_file != old_next_file);
assert(td->o.nr_files <= td->files_index);
- if (!td->nr_open_files || td->nr_done_files >= td->o.nr_files) {
+ if (td->nr_done_files >= td->o.nr_files) {
dprint(FD_FILE, "get_next_file: nr_open=%d, nr_done=%d,"
" nr_files=%d\n", td->nr_open_files,
td->nr_done_files,
return f;
}
-static struct fio_file *find_next_new_file(struct thread_data *td)
-{
- struct fio_file *f;
-
- if (!td->nr_open_files || td->nr_done_files >= td->o.nr_files)
- return NULL;
-
- if (td->o.file_service_type == FIO_FSERVICE_RR)
- f = get_next_file_rr(td, 0, FIO_FILE_OPEN);
- else
- f = get_next_file_rand(td, 0, FIO_FILE_OPEN);
-
- return f;
-}
-
static int set_io_u_file(struct thread_data *td, struct io_u *io_u)
{
struct fio_file *f;
if (!f)
return 1;
-set_file:
io_u->file = f;
get_file(f);
if (!fill_io_u(td, io_u))
break;
- /*
- * optimization to prevent close/open of the same file. This
- * way we preserve queueing etc.
- */
- if (td->o.nr_files == 1 && td->o.time_based) {
- put_file_log(td, f);
- fio_file_reset(f);
- goto set_file;
- }
-
- /*
- * td_io_close() does a put_file() as well, so no need to
- * do that here.
- */
- dprint(FD_FILE, "%s: is done\n", f->file_name);
- io_u->file = NULL;
+ put_file_log(td, f);
td_io_close_file(td, f);
+ io_u->file = NULL;
f->flags |= FIO_FILE_DONE;
td->nr_done_files++;
-
- /*
- * probably not the right place to do this, but see
- * if we need to open a new file
- */
- if (td->nr_open_files < td->o.open_files &&
- td->o.open_files != td->o.nr_files) {
- f = find_next_new_file(td);
-
- if (!f || td_io_open_file(td, f))
- return 1;
-
- goto set_file;
- }
+ dprint(FD_FILE, "%s: is done (%d of %d)\n", f->file_name, td->nr_done_files, td->o.nr_files);
} while (1);
return 0;
f->last_pos = io_u->offset + io_u->buflen;
- if (td->o.verify != VERIFY_NONE)
+ if (td->o.verify != VERIFY_NONE && io_u->ddir == DDIR_WRITE)
populate_verify_io_u(td, io_u);
else if (td->o.refill_buffers && io_u->ddir == DDIR_WRITE)
io_u_fill_buffer(td, io_u, io_u->xfer_buflen);
&icd->time);
if (!td->o.disable_clat) {
- add_clat_sample(td, idx, usec);
+ add_clat_sample(td, idx, usec, bytes);
io_u_mark_latency(td, usec);
}
if (!td->o.disable_bw)
- add_bw_sample(td, idx, &icd->time);
+ add_bw_sample(td, idx, bytes, &icd->time);
}
if (td_write(td) && idx == DDIR_WRITE &&
unsigned long slat_time;
slat_time = utime_since(&io_u->start_time, &io_u->issue_time);
- add_slat_sample(td, io_u->ddir, slat_time);
+ add_slat_sample(td, io_u->ddir, io_u->xfer_buflen, slat_time);
}
}