--- /dev/null
+#ifndef FIO_FILE_H
+#define FIO_FILE_H
+
+#include "io_ddir.h"
+
+/*
+ * The type of object we are working on
+ */
+enum fio_filetype {
+ FIO_TYPE_FILE = 1, /* plain file */
+ FIO_TYPE_BD, /* block device */
+ FIO_TYPE_CHAR, /* character device */
+ FIO_TYPE_PIPE, /* pipe */
+};
+
+enum fio_file_flags {
+ FIO_FILE_open = 1 << 0, /* file is open */
+ FIO_FILE_closing = 1 << 1, /* file being closed */
+ FIO_FILE_extend = 1 << 2, /* needs extend */
+ FIO_FILE_done = 1 << 3, /* io completed to this file */
+ FIO_FILE_size_known = 1 << 4, /* size has been set */
+ FIO_FILE_hashed = 1 << 5, /* file is on hash */
+};
+
+enum file_lock_mode {
+ FILE_LOCK_NONE,
+ FILE_LOCK_EXCLUSIVE,
+ FILE_LOCK_READWRITE,
+};
+
+/*
+ * Each thread_data structure has a number of files associated with it,
+ * this structure holds state information for a single file.
+ */
+struct fio_file {
+ struct flist_head hash_list;
+ enum fio_filetype filetype;
+
+ /*
+ * A file may not be a file descriptor, let the io engine decide
+ */
+ union {
+ unsigned long file_data;
+ int fd;
+ };
+
+ /*
+ * filename and possible memory mapping
+ */
+ char *file_name;
+ unsigned int major, minor;
+
+ void *mmap_ptr;
+ size_t mmap_sz;
+ off_t mmap_off;
+
+ /*
+ * size of the file, offset into file, and io size from that offset
+ */
+ unsigned long long real_file_size;
+ unsigned long long file_offset;
+ unsigned long long io_size;
+
+ unsigned long long last_pos;
+
+ /*
+ * if io is protected by a semaphore, this is set
+ */
+ struct fio_mutex *lock;
+ void *lock_owner;
+ unsigned int lock_batch;
+ enum fio_ddir lock_ddir;
+
+ /*
+ * block map for random io
+ */
+ unsigned int *file_map;
+ unsigned int num_maps;
+ unsigned int last_free_lookup;
+
+ int references;
+ enum fio_file_flags flags;
+
+ struct disk_util *du;
+};
+
+#define FILE_FLAG_FNS(name) \
+static inline void fio_file_set_##name(struct fio_file *f) \
+{ \
+ (f)->flags |= FIO_FILE_##name; \
+} \
+static inline void fio_file_clear_##name(struct fio_file *f) \
+{ \
+ (f)->flags &= ~FIO_FILE_##name; \
+} \
+static inline int fio_file_##name(struct fio_file *f) \
+{ \
+ return ((f)->flags & FIO_FILE_##name) != 0; \
+}
+
+FILE_FLAG_FNS(open);
+FILE_FLAG_FNS(closing);
+FILE_FLAG_FNS(extend);
+FILE_FLAG_FNS(done);
+FILE_FLAG_FNS(size_known);
+FILE_FLAG_FNS(hashed);
+#undef FILE_FLAG_FNS
+
+#endif
{
fio_mutex_down(hash_lock);
- if (f->flags & FIO_FILE_HASHED) {
+ if (fio_file_hashed(f)) {
assert(!flist_empty(&f->hash_list));
flist_del_init(&f->hash_list);
- f->flags &= ~FIO_FILE_HASHED;
+ fio_file_clear_hashed(f);
}
fio_mutex_up(hash_lock);
{
struct fio_file *alias;
- if (f->flags & FIO_FILE_HASHED)
+ if (fio_file_hashed(f))
return NULL;
INIT_FLIST_HEAD(&f->hash_list);
alias = __lookup_file_hash(f->file_name);
if (!alias) {
- f->flags |= FIO_FILE_HASHED;
+ fio_file_set_hashed(f);
flist_add_tail(&f->hash_list, &file_hash[hash(f->file_name)]);
}
}
}
if (td->o.fill_device) {
- f->flags &= ~FIO_SIZE_KNOWN;
+ fio_file_clear_size_known(f);
if (td_io_get_file_size(td, f))
goto err;
if (f->io_size > f->real_file_size)
unsigned int bs;
char *b;
- if (!(f->flags & FIO_FILE_OPEN)) {
+ if (!fio_file_open(f)) {
if (td->io_ops->open_file(td, f)) {
log_err("fio: cannot pre-read, failed to open file\n");
return 1;
{
int ret = 0;
- if (f->flags & FIO_SIZE_KNOWN)
+ if (fio_file_size_known(f))
return 0;
if (f->filetype == FIO_TYPE_FILE)
return 1;
}
- f->flags |= FIO_SIZE_KNOWN;
+ fio_file_set_size_known(f);
return 0;
}
int file_invalidate_cache(struct thread_data *td, struct fio_file *f)
{
- if (!(f->flags & FIO_FILE_OPEN))
+ if (!fio_file_open(f))
return 0;
return __file_invalidate_cache(td, f, -1ULL, -1ULL);
extend_size += (f->io_size + f->file_offset);
} else
f->real_file_size = f->io_size + f->file_offset;
- f->flags |= FIO_FILE_EXTEND;
+ fio_file_set_extend(f);
}
}
for_each_file(td, f, i) {
unsigned long long old_len = -1ULL, extend_len = -1ULL;
- if (!(f->flags & FIO_FILE_EXTEND))
+ if (!fio_file_extend(f))
continue;
assert(f->filetype == FIO_TYPE_FILE);
- f->flags &= ~FIO_FILE_EXTEND;
+ fio_file_clear_extend(f);
if (!td->o.fill_device) {
old_len = f->real_file_size;
extend_len = f->io_size + f->file_offset - old_len;
void get_file(struct fio_file *f)
{
dprint(FD_FILE, "get file %s, ref=%d\n", f->file_name, f->references);
- assert(f->flags & FIO_FILE_OPEN);
+ assert(fio_file_open(f));
f->references++;
}
dprint(FD_FILE, "put file %s, ref=%d\n", f->file_name, f->references);
- if (!(f->flags & FIO_FILE_OPEN))
+ if (!fio_file_open(f))
return 0;
assert(f->references);
ret = f_ret;
td->nr_open_files--;
- f->flags &= ~FIO_FILE_OPEN;
+ fio_file_clear_open(f);
return ret;
}
* read from disk.
*/
for_each_file(td, f, i) {
- if (!(f->flags & FIO_FILE_OPEN))
+ if (!fio_file_open(f))
continue;
if (fio_io_sync(td, f))
break;
td_set_runstate(td, TD_FSYNCING);
for_each_file(td, f, i) {
- if (!(f->flags & FIO_FILE_OPEN))
+ if (!fio_file_open(f))
continue;
fio_io_sync(td, f);
}
close_files(td);
for_each_file(td, f, i)
- f->flags &= ~FIO_FILE_DONE;
+ fio_file_clear_done(f);
}
static int exec_string(const char *string)
#include "mutex.h"
#include "log.h"
#include "debug.h"
+#include "file.h"
+#include "io_ddir.h"
#ifdef FIO_HAVE_GUASI
#include <guasi.h>
#include <sys/asynch.h>
#endif
-enum fio_ddir {
- DDIR_READ = 0,
- DDIR_WRITE,
- DDIR_SYNC,
- DDIR_INVAL = -1,
-};
-
-enum td_ddir {
- TD_DDIR_READ = 1 << 0,
- TD_DDIR_WRITE = 1 << 1,
- TD_DDIR_RAND = 1 << 2,
- TD_DDIR_RW = TD_DDIR_READ | TD_DDIR_WRITE,
- TD_DDIR_RANDREAD = TD_DDIR_READ | TD_DDIR_RAND,
- TD_DDIR_RANDWRITE = TD_DDIR_WRITE | TD_DDIR_RAND,
- TD_DDIR_RANDRW = TD_DDIR_RW | TD_DDIR_RAND,
-};
-
-enum file_lock_mode {
- FILE_LOCK_NONE,
- FILE_LOCK_EXCLUSIVE,
- FILE_LOCK_READWRITE,
-};
-
/*
* Use for maintaining statistics
*/
MEM_MMAPHUGE, /* memory mapped huge file */
};
-/*
- * The type of object we are working on
- */
-enum fio_filetype {
- FIO_TYPE_FILE = 1, /* plain file */
- FIO_TYPE_BD, /* block device */
- FIO_TYPE_CHAR, /* character device */
- FIO_TYPE_PIPE, /* pipe */
-};
-
enum fio_ioengine_flags {
FIO_SYNCIO = 1 << 0, /* io engine has synchronous ->queue */
FIO_RAWIO = 1 << 1, /* some sort of direct/raw io */
FIO_SIGQUIT = 1 << 7, /* needs SIGQUIT to exit */
};
-enum fio_file_flags {
- FIO_FILE_OPEN = 1 << 0, /* file is open */
- FIO_FILE_CLOSING = 1 << 1, /* file being closed */
- FIO_FILE_EXTEND = 1 << 2, /* needs extend */
- FIO_FILE_DONE = 1 << 3, /* io completed to this file */
- FIO_SIZE_KNOWN = 1 << 4, /* size has been set */
- FIO_FILE_HASHED = 1 << 5, /* file is on hash */
-};
-
-/*
- * Each thread_data structure has a number of files associated with it,
- * this structure holds state information for a single file.
- */
-struct fio_file {
- struct flist_head hash_list;
- enum fio_filetype filetype;
-
- /*
- * A file may not be a file descriptor, let the io engine decide
- */
- union {
- unsigned long file_data;
- int fd;
- };
-
- /*
- * filename and possible memory mapping
- */
- char *file_name;
- unsigned int major, minor;
-
- void *mmap_ptr;
- size_t mmap_sz;
- off_t mmap_off;
-
- /*
- * size of the file, offset into file, and io size from that offset
- */
- unsigned long long real_file_size;
- unsigned long long file_offset;
- unsigned long long io_size;
-
- unsigned long long last_pos;
-
- /*
- * if io is protected by a semaphore, this is set
- */
- struct fio_mutex *lock;
- void *lock_owner;
- unsigned int lock_batch;
- enum fio_ddir lock_ddir;
-
- /*
- * block map for random io
- */
- unsigned int *file_map;
- unsigned int num_maps;
- unsigned int last_free_lookup;
-
- int references;
- enum fio_file_flags flags;
-
- struct disk_util *du;
-};
-
/*
* How many depth levels to log
*/
--- /dev/null
+#ifndef FIO_DDIR_H
+#define FIO_DDIR_H
+
+enum fio_ddir {
+ DDIR_READ = 0,
+ DDIR_WRITE,
+ DDIR_SYNC,
+ DDIR_INVAL = -1,
+};
+
+enum td_ddir {
+ TD_DDIR_READ = 1 << 0,
+ TD_DDIR_WRITE = 1 << 1,
+ TD_DDIR_RAND = 1 << 2,
+ TD_DDIR_RW = TD_DDIR_READ | TD_DDIR_WRITE,
+ TD_DDIR_RANDREAD = TD_DDIR_READ | TD_DDIR_RAND,
+ TD_DDIR_RANDWRITE = TD_DDIR_WRITE | TD_DDIR_RAND,
+ TD_DDIR_RANDRW = TD_DDIR_RW | TD_DDIR_RAND,
+};
+
+#endif
/*
* Get next file to service by choosing one at random
*/
-static struct fio_file *get_next_file_rand(struct thread_data *td, int goodf,
- int badf)
+static struct fio_file *get_next_file_rand(struct thread_data *td, enum fio_file_flags goodf,
+ enum fio_file_flags badf)
{
struct fio_file *f;
int fno;
fno = (unsigned int) ((double) td->o.nr_files
* (r / (OS_RAND_MAX + 1.0)));
f = td->files[fno];
- if (f->flags & FIO_FILE_DONE)
+ if (fio_file_done(f))
continue;
- if (!(f->flags & FIO_FILE_OPEN)) {
+ if (!fio_file_open(f)) {
int err;
err = td_io_open_file(td, f);
td->next_file = 0;
dprint(FD_FILE, "trying file %s %x\n", f->file_name, f->flags);
- if (f->flags & FIO_FILE_DONE) {
+ if (fio_file_done(f)) {
f = NULL;
continue;
}
- if (!(f->flags & FIO_FILE_OPEN)) {
+ if (!fio_file_open(f)) {
int err;
err = td_io_open_file(td, f);
}
f = td->file_service_file;
- if (f && (f->flags & FIO_FILE_OPEN) && !(f->flags & FIO_FILE_CLOSING)) {
+ if (f && fio_file_open(f) && !fio_file_closing(f)) {
if (td->o.file_service_type == FIO_FSERVICE_SEQ)
goto out;
if (td->file_service_left--)
if (td->o.file_service_type == FIO_FSERVICE_RR ||
td->o.file_service_type == FIO_FSERVICE_SEQ)
- f = get_next_file_rr(td, FIO_FILE_OPEN, FIO_FILE_CLOSING);
+ f = get_next_file_rr(td, FIO_FILE_open, FIO_FILE_closing);
else
- f = get_next_file_rand(td, FIO_FILE_OPEN, FIO_FILE_CLOSING);
+ f = get_next_file_rand(td, FIO_FILE_open, FIO_FILE_closing);
td->file_service_file = f;
td->file_service_left = td->file_service_nr - 1;
put_file_log(td, f);
td_io_close_file(td, f);
io_u->file = NULL;
- f->flags |= FIO_FILE_DONE;
+ fio_file_set_done(f);
td->nr_done_files++;
dprint(FD_FILE, "%s: is done (%d of %d)\n", f->file_name, td->nr_done_files, td->o.nr_files);
} while (1);
}
f = io_u->file;
- assert(f->flags & FIO_FILE_OPEN);
+ assert(fio_file_open(f));
if (io_u->ddir != DDIR_SYNC) {
if (!io_u->buflen && !(td->io_ops->flags & FIO_NOIO)) {
assert((io_u->flags & IO_U_F_FLIGHT) == 0);
io_u->flags |= IO_U_F_FLIGHT;
- assert(io_u->file->flags & FIO_FILE_OPEN);
+ assert(fio_file_open(io_u->file));
io_u->error = 0;
io_u->resid = 0;
}
fio_file_reset(f);
- f->flags |= FIO_FILE_OPEN;
- f->flags &= ~FIO_FILE_CLOSING;
+ fio_file_set_open(f);
+ fio_file_clear_closing(f);
disk_util_inc(f->du);
td->nr_open_files++;
int td_io_close_file(struct thread_data *td, struct fio_file *f)
{
- if (!(f->flags & FIO_FILE_CLOSING))
+ if (!fio_file_closing(f))
log_file(td, f, FIO_LOG_CLOSE_FILE);
/*
* mark as closing, do real close when last io on it has completed
*/
- f->flags |= FIO_FILE_CLOSING;
+ fio_file_set_closing(f);
disk_util_dec(f->du);
unlock_file_all(td, f);
io_u->buflen = ipo->len;
io_u->file = ipo->file;
- if ((io_u->file->flags & FIO_FILE_OPEN) == 0) {
+ if (!fio_file_open(io_u->file)) {
int r = td_io_open_file(td, io_u->file);
if (r) {
}
get_file(ipo->file);
- assert(io_u->file->flags & FIO_FILE_OPEN);
+ assert(fio_file_open(io_u->file));
io_u->ddir = DDIR_READ;
io_u->xfer_buf = io_u->buf;
io_u->xfer_buflen = io_u->buflen;