static int extend_file(struct thread_data *td, struct fio_file *f)
{
+ int r, new_layout = 0, flags;
unsigned long long left;
unsigned int bs;
char *b;
- int r;
- if (f->flags & FIO_FILE_EXISTS) {
+ /*
+ * check if we need to lay the file out complete again. fio
+ * does that for operations involving reads, or for writes
+ * where overwrite is set
+ */
+ if (td_read(td) || (td_write(td) && td->o.overwrite))
+ new_layout = 1;
+
+ if (new_layout && (f->flags & FIO_FILE_EXISTS)) {
if (unlink(f->file_name) < 0) {
td_verror(td, errno, "unlink");
return 1;
}
}
- f->fd = open(f->file_name, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ flags = O_WRONLY | O_CREAT;
+ if (new_layout)
+ flags |= O_TRUNC;
+
+ f->fd = open(f->file_name, flags, 0644);
if (f->fd < 0) {
td_verror(td, errno, "open");
return 1;
goto err;
}
+ if (!new_layout)
+ goto done;
+
b = malloc(td->o.max_bs[DDIR_WRITE]);
memset(b, 0, td->o.max_bs[DDIR_WRITE]);
fsync(f->fd);
free(b);
+done:
close(f->fd);
f->fd = -1;
return 0;
if (get_file_size(td, f))
goto err;
- if (td->o.invalidate_cache && file_invalidate_cache(td, f))
- goto err;
-
- if (td->o.fadvise_hint) {
- if (td_random(td))
- flags = POSIX_FADV_RANDOM;
- else
- flags = POSIX_FADV_SEQUENTIAL;
-
- if (fadvise(f->fd, f->file_offset, f->io_size, flags) < 0) {
- td_verror(td, errno, "fadvise");
- goto err;
- }
- }
-
return 0;
err:
close(f->fd);
for_each_file(td, f, i) {
err = td_io_open_file(td, f);
- if (err)
+ 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;
/*
* open/close all files, so that ->real_file_size gets set
*/
-static int get_file_sizes(struct thread_data *td)
+static void get_file_sizes(struct thread_data *td)
{
struct fio_file *f;
unsigned int i;
- int err = 0;
for_each_file(td, f, i) {
- err = td->io_ops->open_file(td, f);
- if (err) {
- td->error = 0;
- memset(td->verror, 0, sizeof(td->verror));
- err = 0;
- continue;
- }
-
- td->io_ops->close_file(td, f);
+ if (td->io_ops->open_file(td, f))
+ clear_error(td);
+ else
+ td->io_ops->close_file(td, f);
}
-
- return err;
}
/*
unsigned long long total_size, extend_size;
struct fio_file *f;
unsigned int i;
- int err, need_extend;
+ int err = 0, need_extend;
/*
* if ioengine defines a setup() method, it's responsible for
if (td->io_ops->setup)
err = td->io_ops->setup(td);
else
- err = get_file_sizes(td);
+ get_file_sizes(td);
if (err)
return err;
D = opendir(dirname);
if (!D) {
- td_verror(td, errno, "opendir");
+ char buf[FIO_VERROR_SIZE];
+
+ snprintf(buf, FIO_VERROR_SIZE - 1, "opendir(%s)", dirname);
+ td_verror(td, errno, buf);
return 1;
}
td->o.nr_files++;
continue;
}
+ if (!S_ISDIR(sb.st_mode))
+ continue;
if ((ret = recurse_dir(td, full_path)) != 0)
break;
int add_dir_files(struct thread_data *td, const char *path)
{
- return recurse_dir(td, path);
+ int ret = recurse_dir(td, path);
+
+ if (!ret)
+ log_info("fio: opendir added %d files\n", td->o.nr_files);
+
+ return ret;
}
void dup_files(struct thread_data *td, struct thread_data *org)