X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=io_u.c;h=0f455cfd916d7ac5c8c6b3a69f7d83f66c8a24a3;hp=a56a6f2d32af8d5a49ba54bd186ba9ed1e235c5f;hb=126d65c6fc97d6acdc568aa5a969c012018daf15;hpb=b9c5b64452f483162cf9841cbdd44db6b72fd67c diff --git a/io_u.c b/io_u.c index a56a6f2d..0f455cfd 100644 --- a/io_u.c +++ b/io_u.c @@ -25,11 +25,13 @@ struct io_completion_data { * to yet. Used to make sure we cover the entire range in a fair fashion. */ static int random_map_free(struct thread_data *td, struct fio_file *f, - unsigned long long block) + const unsigned long long block) { unsigned int idx = RAND_MAP_IDX(td, f, block); unsigned int bit = RAND_MAP_BIT(td, f, block); + dprint(FD_RANDOM, "free: b=%llu, idx=%u, bit=%u\n", block, idx, bit); + return (f->file_map[idx] & (1UL << bit)) == 0; } @@ -55,7 +57,7 @@ static void mark_random_map(struct thread_data *td, struct io_u *io_u) * If we have a mixed random workload, we may * encounter blocks we already did IO to. */ - if (!td->o.ddir_nr == 1 && !random_map_free(td, f, block)) + if ((td->o.ddir_nr == 1) && !random_map_free(td, f, block)) break; idx = RAND_MAP_IDX(td, f, block); @@ -78,7 +80,7 @@ static inline unsigned long long last_block(struct thread_data *td, { unsigned long long max_blocks; - max_blocks = f->io_size / td->o.min_bs[ddir]; + max_blocks = f->io_size / (unsigned long long) td->o.min_bs[ddir]; if (!max_blocks) return 0; @@ -91,11 +93,12 @@ static inline unsigned long long last_block(struct thread_data *td, static int get_next_free_block(struct thread_data *td, struct fio_file *f, enum fio_ddir ddir, unsigned long long *b) { + unsigned long long min_bs = td->o.rw_min_bs; int i; i = f->last_free_lookup; *b = (i * BLOCKS_PER_MAP); - while ((*b) * td->o.rw_min_bs < f->real_file_size) { + while ((*b) * min_bs < f->real_file_size) { if (f->file_map[i] != -1UL) { *b += fio_ffz(f->file_map[i]); if (*b > last_block(td, f, ddir)) @@ -115,12 +118,13 @@ static int get_next_free_block(struct thread_data *td, struct fio_file *f, static int get_next_rand_offset(struct thread_data *td, struct fio_file *f, enum fio_ddir ddir, unsigned long long *b) { - unsigned long long r, rb; + unsigned long long r; int loops = 5; do { r = os_random_long(&td->random_state); - *b = last_block(td, f, ddir); + dprint(FD_RANDOM, "off rand %llu\n", r); + *b = (last_block(td, f, ddir) - 1) * (r / ((unsigned long long) RAND_MAX + 1.0)); /* * if we are not maintaining a random map, we are done. @@ -129,12 +133,13 @@ static int get_next_rand_offset(struct thread_data *td, struct fio_file *f, return 0; /* - * calculate map offset and chec if it's free + * calculate map offset and check if it's free */ - rb = *b; - if (random_map_free(td, f, rb)) + if (random_map_free(td, f, *b)) return 0; + dprint(FD_RANDOM, "get_next_rand_offset: offset %llu busy\n", + *b); } while (--loops); /* @@ -323,8 +328,12 @@ void put_io_u(struct thread_data *td, struct io_u *io_u) assert((io_u->flags & IO_U_F_FREE) == 0); io_u->flags |= IO_U_F_FREE; - if (io_u->file) - put_file(td, io_u->file); + if (io_u->file) { + int ret = put_file(td, io_u->file); + + if (ret) + td_verror(td, ret, "file close"); + } io_u->file = NULL; list_del(&io_u->list); @@ -552,7 +561,7 @@ static struct fio_file *get_next_file_rand(struct thread_data *td, int goodf, long r = os_random_long(&td->next_file_state); fno = (unsigned int) ((double) td->o.nr_files * (r / (RAND_MAX + 1.0))); - f = &td->files[fno]; + f = td->files[fno]; if (f->flags & FIO_FILE_DONE) continue; @@ -573,7 +582,7 @@ static struct fio_file *get_next_file_rr(struct thread_data *td, int goodf, struct fio_file *f; do { - f = &td->files[td->next_file]; + f = td->files[td->next_file]; td->next_file++; if (td->next_file >= td->o.nr_files) @@ -759,10 +768,9 @@ struct io_u *get_io_u(struct thread_data *td) * Set io data pointers. */ io_u->endpos = io_u->offset + io_u->buflen; -out: io_u->xfer_buf = io_u->buf; io_u->xfer_buflen = io_u->buflen; - +out: if (!td_io_prep(td, io_u)) { fio_gettime(&io_u->start_time, NULL); return io_u;