X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=filesetup.c;h=d79fc61081278c934fd1c4aecbfe344666c75811;hp=2da29d1510ad2ed5cccba9d6d38ccd7d15322ec8;hb=fdefd987d7ba284c7a9e101911c4b8e72fe326ad;hpb=507a702f6a61fa461c2566d01dcc46380ee7dffa diff --git a/filesetup.c b/filesetup.c index 2da29d15..d79fc610 100644 --- a/filesetup.c +++ b/filesetup.c @@ -8,11 +8,10 @@ #include #include "fio.h" -#include "os.h" static int extend_file(struct thread_data *td, struct fio_file *f) { - int r, new_layout = 0, flags; + int r, new_layout = 0, unlink_file = 0, flags; unsigned long long left; unsigned int bs; char *b; @@ -24,8 +23,10 @@ static int extend_file(struct thread_data *td, struct fio_file *f) */ if (td_read(td) || (td_write(td) && td->o.overwrite)) new_layout = 1; + if (td_write(td) && !td->o.overwrite) + unlink_file = 1; - if (new_layout && (f->flags & FIO_FILE_EXISTS)) { + if ((unlink_file || new_layout) && (f->flags & FIO_FILE_EXISTS)) { if (unlink(f->file_name) < 0) { td_verror(td, errno, "unlink"); return 1; @@ -47,14 +48,14 @@ static int extend_file(struct thread_data *td, struct fio_file *f) goto err; } + if (!new_layout) + goto done; + if (posix_fallocate(f->fd, 0, f->real_file_size) < 0) { td_verror(td, errno, "posix_fallocate"); goto err; } - if (!new_layout) - goto done; - b = malloc(td->o.max_bs[DDIR_WRITE]); memset(b, 0, td->o.max_bs[DDIR_WRITE]); @@ -138,6 +139,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) @@ -153,6 +157,7 @@ static int get_file_size(struct thread_data *td, struct fio_file *f) return 1; } + f->flags |= FIO_SIZE_KNOWN; return 0; } @@ -176,7 +181,7 @@ int file_invalidate_cache(struct thread_data *td, struct fio_file *f) log_err("fio: only root may flush block devices. Cache flush bypassed!\n"); ret = 0; } - } else if (f->filetype == FIO_TYPE_CHAR) + } else if (f->filetype == FIO_TYPE_CHAR || f->filetype == FIO_TYPE_PIPE) ret = 0; if (ret < 0) { @@ -195,27 +200,48 @@ void generic_close_file(struct thread_data fio_unused *td, struct fio_file *f) int generic_open_file(struct thread_data *td, struct fio_file *f) { + int is_std = 0; int flags = 0; + if (!strcmp(f->file_name, "-")) { + if (td_rw(td)) { + log_err("fio: can't read/write to stdin/out\n"); + return 1; + } + is_std = 1; + + /* + * move output logging to stderr, if we are writing to stdout + */ + if (td_write(td)) + f_out = stderr; + } + if (td->o.odirect) flags |= OS_O_DIRECT; if (td->o.sync_io) flags |= O_SYNC; - if (td_write(td) || td_rw(td)) { + if (td_write(td)) { flags |= O_RDWR; if (f->filetype == FIO_TYPE_FILE) flags |= O_CREAT; - f->fd = open(f->file_name, flags, 0600); + if (is_std) + f->fd = dup(STDOUT_FILENO); + else + f->fd = open(f->file_name, flags, 0600); } else { if (f->filetype == FIO_TYPE_CHAR) flags |= O_RDWR; else flags |= O_RDONLY; - f->fd = open(f->file_name, flags); + if (is_std) + f->fd = dup(STDIN_FILENO); + else + f->fd = open(f->file_name, flags); } if (f->fd == -1) { @@ -244,8 +270,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; @@ -270,15 +303,19 @@ static int get_file_sizes(struct thread_data *td) 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)) { + 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); } - 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; @@ -292,7 +329,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 @@ -322,7 +359,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; @@ -387,6 +424,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); @@ -436,8 +474,7 @@ void close_files(struct thread_data *td) unsigned int i; for_each_file(td, f, i) { - if ((f->flags & FIO_FILE_UNLINK) && - f->filetype == FIO_TYPE_FILE) + if (td->o.unlink && f->filetype == FIO_TYPE_FILE) unlink(f->file_name); td_io_close_file(td, f); @@ -461,13 +498,18 @@ static void get_file_type(struct fio_file *f) { struct stat sb; - f->filetype = FIO_TYPE_FILE; + if (!strcmp(f->file_name, "-")) + f->filetype = FIO_TYPE_PIPE; + else + f->filetype = FIO_TYPE_FILE; if (!lstat(f->file_name, &sb)) { if (S_ISBLK(sb.st_mode)) f->filetype = FIO_TYPE_BD; else if (S_ISCHR(sb.st_mode)) f->filetype = FIO_TYPE_CHAR; + else if (S_ISFIFO(sb.st_mode)) + f->filetype = FIO_TYPE_PIPE; } } @@ -484,6 +526,12 @@ void add_file(struct thread_data *td, const char *fname) memset(f, 0, sizeof(*f)); f->fd = -1; + /* + * init function, io engine may not be loaded yet + */ + if (td->io_ops && (td->io_ops->flags & FIO_DISKLESSIO)) + f->real_file_size = -1ULL; + if (td->o.directory) len = sprintf(file_name, "%s/", td->o.directory); @@ -516,6 +564,7 @@ void put_file(struct thread_data *td, struct fio_file *f) if (td->io_ops->close_file) td->io_ops->close_file(td, f); + td->nr_open_files--; f->flags &= ~FIO_FILE_OPEN; } @@ -528,7 +577,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; } @@ -553,6 +605,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; @@ -564,7 +618,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)