X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=filesetup.c;h=161f63e7d1a5aee2597e146513396406784fd4c2;hp=f6b4855bbe7a845a9549fd45e65b99aed2477d41;hb=409b3417e46cc3ce7041f042bcc26c3feb46e9e9;hpb=413d669320995eaef092c58e67cdb7b500134551 diff --git a/filesetup.c b/filesetup.c index f6b4855b..161f63e7 100644 --- a/filesetup.c +++ b/filesetup.c @@ -12,19 +12,31 @@ 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; @@ -40,6 +52,9 @@ static int extend_file(struct thread_data *td, struct fio_file *f) goto err; } + if (!new_layout) + goto done; + b = malloc(td->o.max_bs[DDIR_WRITE]); memset(b, 0, td->o.max_bs[DDIR_WRITE]); @@ -70,6 +85,7 @@ static int extend_file(struct thread_data *td, struct fio_file *f) fsync(f->fd); free(b); +done: close(f->fd); f->fd = -1; return 0; @@ -122,6 +138,9 @@ static int get_file_size(struct thread_data *td, struct fio_file *f) { int ret = 0; + if (f->flags & FIO_SIZE_KNOWN) + return 0; + if (f->filetype == FIO_TYPE_FILE) ret = file_size(td, f); else if (f->filetype == FIO_TYPE_BD) @@ -137,6 +156,7 @@ static int get_file_size(struct thread_data *td, struct fio_file *f) return 1; } + f->flags |= FIO_SIZE_KNOWN; return 0; } @@ -228,8 +248,15 @@ int open_files(struct thread_data *td) 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; @@ -247,25 +274,20 @@ int open_files(struct thread_data *td) /* * 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; - } + if (td->io_ops->open_file(td, f)) + clear_error(td); + else + td->io_ops->close_file(td, f); - td->io_ops->close_file(td, f); + if (f->real_file_size == -1ULL && td->o.size) + f->real_file_size = td->o.size / td->o.nr_files; } - - return err; } /* @@ -276,7 +298,7 @@ int setup_files(struct thread_data *td) 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 @@ -286,7 +308,7 @@ int setup_files(struct thread_data *td) 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; @@ -306,7 +328,7 @@ int setup_files(struct thread_data *td) /* * device/file sizes are zero and no size given, punt */ - if (!total_size && !td->o.size) { + if ((!total_size || total_size == -1ULL) && !td->o.size) { log_err("%s: you need to specify size=\n", td->o.name); td_verror(td, EINVAL, "total_file_size"); return 1; @@ -371,6 +393,7 @@ int setup_files(struct thread_data *td) if (!(f->flags & FIO_FILE_EXTEND)) continue; + assert(f->filetype == FIO_TYPE_FILE); f->flags &= ~FIO_FILE_EXTEND; f->real_file_size = f->io_size; err = extend_file(td, f); @@ -512,7 +535,10 @@ static int recurse_dir(struct thread_data *td, const char *dirname) 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; } @@ -537,6 +563,8 @@ static int recurse_dir(struct thread_data *td, const char *dirname) td->o.nr_files++; continue; } + if (!S_ISDIR(sb.st_mode)) + continue; if ((ret = recurse_dir(td, full_path)) != 0) break; @@ -548,7 +576,12 @@ static int recurse_dir(struct thread_data *td, const char *dirname) 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)