return 1;
}
+static int pre_read_file(struct thread_data *td, struct fio_file *f)
+{
+ int r, did_open = 0, old_runstate;
+ unsigned long long left;
+ unsigned int bs;
+ char *b;
+
+ if (!(f->flags & FIO_FILE_OPEN)) {
+ if (td->io_ops->open_file(td, f)) {
+ log_err("fio: cannot pre-read, failed to open file\n");
+ return 1;
+ }
+ did_open = 1;
+ }
+
+ old_runstate = td->runstate;
+ td_set_runstate(td, TD_PRE_READING);
+
+ bs = td->o.max_bs[DDIR_READ];
+ b = malloc(bs);
+ memset(b, 0, bs);
+
+ lseek(f->fd, f->file_offset, SEEK_SET);
+ left = f->io_size;
+
+ while (left && !td->terminate) {
+ if (bs > left)
+ bs = left;
+
+ r = read(f->fd, b, bs);
+
+ if (r == (int) bs) {
+ left -= bs;
+ continue;
+ } else {
+ printf("r=%d\n", r);
+ td_verror(td, EIO, "pre_read");
+ break;
+ }
+ }
+
+ td_set_runstate(td, old_runstate);
+
+ if (did_open)
+ td->io_ops->close_file(td, f);
+ free(b);
+ return 0;
+}
+
static unsigned long long get_rand_file_size(struct thread_data *td)
{
unsigned long long ret, sized;
{
struct stat st;
- if (fstat(f->fd, &st) == -1) {
+ if (stat(f->file_name, &st) == -1) {
td_verror(td, errno, "fstat");
return 1;
}
unsigned long long bytes;
int r;
+ if (td->io_ops->open_file(td, f)) {
+ log_err("fio: failed opening blockdev %s for size check\n",
+ f->file_name);
+ return 1;
+ }
+
r = blockdev_size(f->fd, &bytes);
if (r) {
td_verror(td, r, "blockdev_size");
- return 1;
+ goto err;
}
if (!bytes) {
log_err("%s: zero sized block device?\n", f->file_name);
- return 1;
+ goto err;
}
f->real_file_size = bytes;
return 0;
+err:
+ td->io_ops->close_file(td, f);
+ return 1;
}
static int get_file_size(struct thread_data *td, struct fio_file *f)
td_verror(td, __e, buf);
}
- if (get_file_size(td, f))
- goto err;
-
if (!from_hash && f->fd != -1) {
if (add_file_hash(f)) {
int ret;
}
return 0;
-err:
- close(f->fd);
- return 1;
}
-int open_files(struct thread_data *td)
+int generic_get_file_size(struct thread_data *td, struct fio_file *f)
{
- struct fio_file *f;
- unsigned int i;
- int err = 0;
-
- dprint(FD_FILE, "open files\n");
-
- for_each_file(td, f, i) {
- err = td_io_open_file(td, f);
- if (err) {
- if (td->error == EMFILE) {
- log_err("fio: limited open files to: %d\n",
- td->nr_open_files);
- td->o.open_files = td->nr_open_files;
- err = 0;
- clear_error(td);
- }
- break;
- }
-
- if (td->o.open_files == td->nr_open_files)
- break;
- }
-
- if (!err)
- return 0;
-
- for_each_file(td, f, i)
- td_io_close_file(td, f);
-
- return err;
+ return get_file_size(td, f);
}
/*
dprint(FD_FILE, "get file size for %p/%d/%p\n", f, i,
f->file_name);
- if (td->io_ops->open_file(td, f)) {
+ if (td_io_get_file_size(td, f)) {
if (td->error != ENOENT) {
log_err("%s\n", td->verror);
err = 1;
}
clear_error(td);
- } else {
- if (td->io_ops->close_file)
- td->io_ops->close_file(td, f);
}
if (f->real_file_size == -1ULL && td->o.size)
return 1;
}
+int pre_read_files(struct thread_data *td)
+{
+ struct fio_file *f;
+ unsigned int i;
+
+ dprint(FD_FILE, "pre_read files\n");
+
+ for_each_file(td, f, i) {
+ pre_read_file(td, f);
+ }
+
+ return 1;
+}
+
int init_random_map(struct thread_data *td)
{
unsigned long long blocks, num_maps;
f->fd = -1;
if (td->files_size <= td->files_index) {
- int new_size = td->o.nr_files;
+ int new_size = td->o.nr_files + 1;
dprint(FD_FILE, "resize file array to %d files\n", new_size);