X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=filesetup.c;h=b8b22b5a54da51504b369b67975c46ef10f95084;hb=bcdedd0ac6e9413258b608ecb3511867b1a9c534;hp=85141dc3725a26b870fe8afe83876199e2142163;hpb=661598287ecc3b8987f312cf8403936552ce686a;p=fio.git diff --git a/filesetup.c b/filesetup.c index 85141dc3..b8b22b5a 100644 --- a/filesetup.c +++ b/filesetup.c @@ -9,6 +9,8 @@ #include "fio.h" +static int root_warn; + static int extend_file(struct thread_data *td, struct fio_file *f) { int r, new_layout = 0, unlink_file = 0, flags; @@ -178,7 +180,10 @@ int file_invalidate_cache(struct thread_data *td, struct fio_file *f) else if (f->filetype == FIO_TYPE_BD) { ret = blockdev_invalidate_cache(f->fd); if (ret < 0 && errno == EACCES && geteuid()) { - log_err("fio: only root may flush block devices. Cache flush bypassed!\n"); + if (!root_warn) { + log_err("fio: only root may flush block devices. Cache flush bypassed!\n"); + root_warn = 1; + } ret = 0; } } else if (f->filetype == FIO_TYPE_CHAR || f->filetype == FIO_TYPE_PIPE) @@ -209,6 +214,12 @@ int generic_open_file(struct thread_data *td, struct fio_file *f) 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) @@ -216,7 +227,7 @@ int generic_open_file(struct thread_data *td, struct fio_file *f) 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) @@ -367,6 +378,8 @@ int setup_files(struct thread_data *td) extend_size = total_size = 0; need_extend = 0; for_each_file(td, f, i) { + f->file_offset = td->o.start_offset; + if (!td->o.file_size_low) { /* * no file size range given, file size is equal to @@ -374,20 +387,27 @@ int setup_files(struct thread_data *td) * zero, set it to the real file size. */ f->io_size = td->o.size / td->o.nr_files; - if (!f->io_size) - f->io_size = f->real_file_size; + if (!f->io_size) { + if (f->file_offset > f->real_file_size) + goto err_offset; + f->io_size = f->real_file_size - f->file_offset; + } } else if (f->real_file_size < td->o.file_size_low || f->real_file_size > td->o.file_size_high) { + if (f->file_offset > td->o.file_size_low) + goto err_offset; /* * file size given. if it's fixed, use that. if it's a * range, generate a random size in-between. */ if (td->o.file_size_low == td->o.file_size_high) - f->io_size = td->o.file_size_low; + f->io_size = td->o.file_size_low - f->file_offset; else - f->io_size = get_rand_file_size(td); - } else - f->io_size = f->real_file_size; + f->io_size = get_rand_file_size(td) - f->file_offset; + } else if (f->file_offset > f->real_file_size) + goto err_offset; + else + f->io_size = f->real_file_size - f->file_offset; if (f->io_size == -1ULL) total_size = -1ULL; @@ -395,15 +415,15 @@ int setup_files(struct thread_data *td) total_size += f->io_size; if (f->filetype == FIO_TYPE_FILE && - f->io_size > f->real_file_size && + (f->io_size + f->file_offset) > f->real_file_size && !(td->io_ops->flags & FIO_DISKLESSIO)) { need_extend++; - extend_size += f->io_size; + extend_size += (f->io_size + f->file_offset); f->flags |= FIO_FILE_EXTEND; - } + } } - if (!td->o.size) + if (!td->o.size || td->o.size > total_size) td->o.size = total_size; /* @@ -420,7 +440,7 @@ int setup_files(struct thread_data *td) assert(f->filetype == FIO_TYPE_FILE); f->flags &= ~FIO_FILE_EXTEND; - f->real_file_size = f->io_size; + f->real_file_size = (f->io_size + f->file_offset); err = extend_file(td, f); if (err) break; @@ -436,6 +456,9 @@ int setup_files(struct thread_data *td) td->total_io_size = td->o.size * td->o.loops; return 0; +err_offset: + log_err("%s: you need to specify valid offset=\n", td->o.name); + return 1; } int init_random_map(struct thread_data *td) @@ -468,8 +491,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); @@ -508,7 +530,7 @@ static void get_file_type(struct fio_file *f) } } -void add_file(struct thread_data *td, const char *fname) +int add_file(struct thread_data *td, const char *fname) { int cur_files = td->files_index; char file_name[PATH_MAX]; @@ -538,10 +560,13 @@ void add_file(struct thread_data *td, const char *fname) td->files_index++; if (f->filetype == FIO_TYPE_FILE) td->nr_normal_files++; + + return cur_files; } void get_file(struct fio_file *f) { + assert(f->flags & FIO_FILE_OPEN); f->references++; } @@ -554,8 +579,7 @@ void put_file(struct thread_data *td, struct fio_file *f) if (--f->references) return; - if (should_fsync(td) && td->o.fsync_on_close && - (f->filetype == FIO_TYPE_FILE || f->filetype == FIO_TYPE_BD)) + if (should_fsync(td) && td->o.fsync_on_close) fsync(f->fd); if (td->io_ops->close_file) @@ -640,3 +664,28 @@ void dup_files(struct thread_data *td, struct thread_data *org) f->file_name = strdup(f->file_name); } } + +/* + * Returns the index that matches the filename, or -1 if not there + */ +int get_fileno(struct thread_data *td, const char *fname) +{ + struct fio_file *f; + unsigned int i; + + for_each_file(td, f, i) + if (!strcmp(f->file_name, fname)) + return i; + + return -1; +} + +/* + * For log usage, where we add/open/close files automatically + */ +void free_release_files(struct thread_data *td) +{ + close_files(td); + td->files_index = 0; + td->nr_normal_files = 0; +}