#include "fio.h"
-#define DEF_BS (4096)
-#define DEF_TIMEOUT (0)
-#define DEF_RATE_CYCLE (1000)
-#define DEF_ODIRECT (1)
-#define DEF_IO_ENGINE (FIO_SYNCIO)
+#define DEF_BS (4096)
+#define DEF_TIMEOUT (0)
+#define DEF_RATE_CYCLE (1000)
+#define DEF_ODIRECT (1)
+#define DEF_IO_ENGINE (FIO_SYNCIO)
#define DEF_IO_ENGINE_NAME "sync"
-#define DEF_SEQUENTIAL (1)
-#define DEF_RAND_REPEAT (1)
-#define DEF_OVERWRITE (1)
-#define DEF_CREATE (1)
-#define DEF_INVALIDATE (1)
-#define DEF_SYNCIO (0)
-#define DEF_RANDSEED (0xb1899bedUL)
-#define DEF_BWAVGTIME (500)
-#define DEF_CREATE_SER (1)
+#define DEF_SEQUENTIAL (1)
+#define DEF_RAND_REPEAT (1)
+#define DEF_OVERWRITE (1)
+#define DEF_CREATE (1)
+#define DEF_INVALIDATE (1)
+#define DEF_SYNCIO (0)
+#define DEF_RANDSEED (0xb1899bedUL)
+#define DEF_BWAVGTIME (500)
+#define DEF_CREATE_SER (1)
#define DEF_CREATE_FSYNC (1)
-#define DEF_LOOPS (1)
-#define DEF_VERIFY (0)
-#define DEF_STONEWALL (0)
-#define DEF_NUMJOBS (1)
-#define DEF_USE_THREAD (0)
-#define DEF_FILE_SIZE (1024 * 1024 * 1024UL)
+#define DEF_LOOPS (1)
+#define DEF_VERIFY (0)
+#define DEF_STONEWALL (0)
+#define DEF_NUMJOBS (1)
+#define DEF_USE_THREAD (0)
+#define DEF_FILE_SIZE (1024 * 1024 * 1024UL)
+#define DEF_ZONE_SIZE (0)
+#define DEF_ZONE_SKIP (0)
static char fio_version_string[] = "fio 1.1";
td->invalidate_cache = parent->invalidate_cache;
td->file_size = parent->file_size;
td->file_offset = parent->file_offset;
+ td->zone_size = parent->zone_size;
+ td->zone_skip = parent->zone_skip;
td->rate = parent->rate;
td->ratemin = parent->ratemin;
td->ratecycle = parent->ratecycle;
td->iodepth = 1;
}
+ /*
+ * only really works for sequential io for now
+ */
+ if (td->zone_size && !td->sequential)
+ td->zone_size = 0;
+
td->filetype = FIO_TYPE_FILE;
if (!stat(jobname, &sb) && S_ISBLK(sb.st_mode))
td->filetype = FIO_TYPE_BD;
static int check_strcnv(char *p, char *name, unsigned long long *val)
{
- if (!strstr(p, name))
+ if (strncmp(p, name, strlen(name) - 1))
return 1;
return str_cnv(p, val);
fgetpos(f, &off);
continue;
}
+ if (!check_strcnv(p, "zonesize", &td->zone_size)) {
+ fgetpos(f, &off);
+ continue;
+ }
+ if (!check_strcnv(p, "zoneskip", &td->zone_skip)) {
+ fgetpos(f, &off);
+ continue;
+ }
if (!check_strstore(p, "directory", td->directory)) {
fgetpos(f, &off);
continue;
io_u->buflen = blocks * td->min_bs;
}
-static int get_next_offset(struct thread_data *td, unsigned long long *offset)
-{
- unsigned long long b, rb;
- long r;
-
- if (!td->sequential) {
- unsigned long max_blocks = td->io_size / td->min_bs;
- int loops = 50;
-
- do {
- lrand48_r(&td->random_state, &r);
- b = ((max_blocks - 1) * r / (RAND_MAX+1.0));
- rb = b + (td->file_offset / td->min_bs);
- loops--;
- } while (!random_map_free(td, rb) && loops);
-
- if (!loops) {
- if (get_next_free_block(td, &b))
- return 1;
- }
- } else
- b = td->last_bytes / td->min_bs;
-
- *offset = (b * td->min_bs) + td->file_offset;
- if (*offset > td->file_size)
- return 1;
-
- return 0;
-}
-
-static unsigned int get_next_buflen(struct thread_data *td)
-{
- unsigned int buflen;
- long r;
-
- if (td->min_bs == td->max_bs)
- buflen = td->min_bs;
- else {
- lrand48_r(&td->bsrange_state, &r);
- buflen = (1 + (double) (td->max_bs - 1) * r / (RAND_MAX + 1.0));
- buflen = (buflen + td->min_bs - 1) & ~(td->min_bs - 1);
- }
-
- if (buflen > td->io_size - td->this_io_bytes[td->ddir])
- buflen = td->io_size - td->this_io_bytes[td->ddir];
-
- return buflen;
-}
-
static inline void add_stat_sample(struct io_stat *is, unsigned long val)
{
if (val > is->max_val)
td->stat_io_bytes[ddir] = td->this_io_bytes[ddir];
}
+static int get_next_offset(struct thread_data *td, unsigned long long *offset)
+{
+ unsigned long long b, rb;
+ long r;
+
+ if (!td->sequential) {
+ unsigned long max_blocks = td->io_size / td->min_bs;
+ int loops = 50;
+
+ do {
+ lrand48_r(&td->random_state, &r);
+ b = ((max_blocks - 1) * r / (RAND_MAX+1.0));
+ rb = b + (td->file_offset / td->min_bs);
+ loops--;
+ } while (!random_map_free(td, rb) && loops);
+
+ if (!loops) {
+ if (get_next_free_block(td, &b))
+ return 1;
+ }
+ } else
+ b = td->last_pos / td->min_bs;
+
+ *offset = (b * td->min_bs) + td->file_offset;
+ if (*offset > td->file_size)
+ return 1;
+
+ return 0;
+}
+
+static unsigned int get_next_buflen(struct thread_data *td)
+{
+ unsigned int buflen;
+ long r;
+
+ if (td->min_bs == td->max_bs)
+ buflen = td->min_bs;
+ else {
+ lrand48_r(&td->bsrange_state, &r);
+ buflen = (1 + (double) (td->max_bs - 1) * r / (RAND_MAX + 1.0));
+ buflen = (buflen + td->min_bs - 1) & ~(td->min_bs - 1);
+ }
+
+ if (buflen > td->io_size - td->this_io_bytes[td->ddir])
+ buflen = td->io_size - td->this_io_bytes[td->ddir];
+
+ return buflen;
+}
+
/*
* busy looping version for the last few usec
*/
memcpy(io_u->buf, &hdr, sizeof(hdr));
}
+static int td_io_prep(struct thread_data *td, struct io_u *io_u, int read)
+{
+ if (read)
+ io_u->ddir = DDIR_READ;
+ else
+ io_u->ddir = DDIR_WRITE;
+
+ if (td->io_prep && td->io_prep(td, io_u))
+ return 1;
+
+ return 0;
+}
+
static void put_io_u(struct thread_data *td, struct io_u *io_u)
{
list_del(&io_u->list);
return io_u;
}
-static int td_io_prep(struct thread_data *td, struct io_u *io_u, int read)
-{
- if (read)
- io_u->ddir = DDIR_READ;
- else
- io_u->ddir = DDIR_WRITE;
-
- if (td->io_prep && td->io_prep(td, io_u))
- return 1;
-
- return 0;
-}
-
static struct io_u *get_io_u(struct thread_data *td)
{
struct io_u *io_u;
if (!io_u)
return NULL;
+ if (td->zone_bytes >= td->zone_size) {
+ td->zone_bytes = 0;
+ td->last_pos += td->zone_skip;
+ }
+
if (get_next_offset(td, &io_u->offset)) {
put_io_u(td, io_u);
return NULL;
if (!td->sequential)
mark_random_map(td, io_u);
- td->last_bytes += io_u->buflen;
+ td->last_pos += io_u->buflen;
if (td->verify != VERIFY_NONE)
populate_io_u(td, io_u);
gettimeofday(&e, NULL);
if (!io_u->error) {
+ unsigned int bytes = io_u->buflen - io_u->resid;
int idx = io_u->ddir;
td->io_blocks[idx]++;
- td->io_bytes[idx] += (io_u->buflen - io_u->resid);
- td->this_io_bytes[idx] += (io_u->buflen - io_u->resid);
+ td->io_bytes[idx] += bytes;
+ td->zone_bytes += bytes;
+ td->this_io_bytes[idx] += bytes;
msec = mtime_since(&io_u->issue_time, &e);
if (td_write(td) && io_u->ddir == DDIR_WRITE)
log_io_piece(td, io_u);
- icd->bytes_done[idx] += (io_u->buflen - io_u->resid);
+ icd->bytes_done[idx] += bytes;
} else
icd->error = io_u->error;
}
return 1;
}
+ if (!td->zone_size)
+ td->zone_size = td->io_size;
+
td->total_io_size = td->io_size * td->loops;
return 0;
}
if (td->io_engine == FIO_SYNCIO)
lseek(td->fd, SEEK_SET, 0);
- td->last_bytes = 0;
+ td->last_pos = 0;
td->stat_io_bytes[0] = td->stat_io_bytes[1] = 0;
td->this_io_bytes[0] = td->this_io_bytes[1] = 0;
+ td->zone_bytes = 0;
if (td->file_map)
memset(td->file_map, 0, td->num_maps * sizeof(long));
if (td->verify)
bytes_total += td->total_io_size;
+ if (td->zone_size)
+ bytes_total /= (td->zone_skip / td->zone_size);
+
bytes_done += td->io_bytes[DDIR_READ] +td->io_bytes[DDIR_WRITE];
check_str_update(td);