More random fixes
[fio.git] / filesetup.c
index 5134fdbb8af5a52e08e5ad8b60ea820e0caeab9f..76b45a9c76af6762d73521355b031bdc38046c9c 100644 (file)
@@ -44,20 +44,25 @@ static int extend_file(struct thread_data *td, struct fio_file *f)
        if (new_layout)
                flags |= O_TRUNC;
 
+       dprint(FD_FILE, "open file %s, flags %x\n", f->file_name, flags);
        f->fd = open(f->file_name, flags, 0644);
        if (f->fd < 0) {
                td_verror(td, errno, "open");
                return 1;
        }
 
+       if (!new_layout)
+               goto done;
+
+       dprint(FD_FILE, "truncate file %s, size %llu\n", f->file_name,
+                                                       f->real_file_size);
        if (ftruncate(f->fd, f->real_file_size) == -1) {
                td_verror(td, errno, "ftruncate");
                goto err;
        }
 
-       if (!new_layout)
-               goto done;
-
+       dprint(FD_FILE, "fallocate file %s, size %llu\n", f->file_name,
+                                                       f->real_file_size);
        if (posix_fallocate(f->fd, 0, f->real_file_size) < 0) {
                td_verror(td, errno, "posix_fallocate");
                goto err;
@@ -172,6 +177,8 @@ int file_invalidate_cache(struct thread_data *td, struct fio_file *f)
 {
        int ret = 0;
 
+       dprint(FD_IO, "invalidate cache (%d)\n", td->o.odirect);
+
        if (td->o.odirect)
                return 0;
 
@@ -204,6 +211,7 @@ int file_invalidate_cache(struct thread_data *td, struct fio_file *f)
 
 void generic_close_file(struct thread_data fio_unused *td, struct fio_file *f)
 {
+       dprint(FD_FILE, "fd close %s\n", f->file_name);
        close(f->fd);
        f->fd = -1;
 }
@@ -213,6 +221,8 @@ int generic_open_file(struct thread_data *td, struct fio_file *f)
        int is_std = 0;
        int flags = 0;
 
+       dprint(FD_FILE, "fd open %s\n", f->file_name);
+
        if (!strcmp(f->file_name, "-")) {
                if (td_rw(td)) {
                        log_err("fio: can't read/write to stdin/out\n");
@@ -234,6 +244,7 @@ int generic_open_file(struct thread_data *td, struct fio_file *f)
        if (f->filetype != FIO_TYPE_FILE)
                flags |= O_NOATIME;
 
+open_again:
        if (td_write(td)) {
                assert(!read_only);
 
@@ -262,6 +273,11 @@ int generic_open_file(struct thread_data *td, struct fio_file *f)
                char buf[FIO_VERROR_SIZE];
                int __e = errno;
 
+               if (errno == EPERM && (flags & O_NOATIME)) {
+                       flags &= ~O_NOATIME;
+                       goto open_again;
+               }
+
                snprintf(buf, sizeof(buf) - 1, "open(%s)", f->file_name);
 
                td_verror(td, __e, buf);
@@ -282,6 +298,8 @@ int open_files(struct thread_data *td)
        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) {
@@ -345,6 +363,8 @@ int setup_files(struct thread_data *td)
        unsigned int i;
        int err = 0, need_extend;
 
+       dprint(FD_FILE, "setup files\n");
+
        /*
         * if ioengine defines a setup() method, it's responsible for
         * opening the files and setting f->real_file_size to indicate
@@ -374,7 +394,7 @@ int setup_files(struct thread_data *td)
         * device/file sizes are zero and no size given, punt
         */
        if ((!total_size || total_size == -1ULL) && !td->o.size &&
-           !(td->io_ops->flags & FIO_NOIO)) {
+           !(td->io_ops->flags & FIO_NOIO) && !td->o.fill_device) {
                log_err("%s: you need to specify size=\n", td->o.name);
                td_verror(td, EINVAL, "total_file_size");
                return 1;
@@ -397,11 +417,8 @@ 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) {
-                               if (f->file_offset > f->real_file_size)
-                                       goto err_offset;
+                       if (!f->io_size)
                                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) 
@@ -414,9 +431,7 @@ int setup_files(struct thread_data *td)
                                f->io_size = td->o.file_size_low - f->file_offset;
                        else
                                f->io_size = get_rand_file_size(td) - f->file_offset;
-               } else if (f->file_offset > f->real_file_size)
-                       goto err_offset;
-               else
+               } else
                        f->io_size = f->real_file_size - f->file_offset;
 
                if (f->io_size == -1ULL)
@@ -478,7 +493,7 @@ err_offset:
 
 int init_random_map(struct thread_data *td)
 {
-       int num_maps, blocks;
+       unsigned long long blocks, num_maps;
        struct fio_file *f;
        unsigned int i;
 
@@ -486,8 +501,8 @@ int init_random_map(struct thread_data *td)
                return 0;
 
        for_each_file(td, f, i) {
-               blocks = (f->real_file_size + td->o.rw_min_bs - 1) / td->o.rw_min_bs;
-               num_maps = (blocks + BLOCKS_PER_MAP-1)/ BLOCKS_PER_MAP;
+               blocks = (f->real_file_size + td->o.rw_min_bs - 1) / (unsigned long long) td->o.rw_min_bs;
+               num_maps = (blocks + BLOCKS_PER_MAP-1)/ (unsigned long long) BLOCKS_PER_MAP;
                f->file_map = malloc(num_maps * sizeof(long));
                if (!f->file_map) {
                        log_err("fio: failed allocating random map. If running a large number of jobs, try the 'norandommap' option\n");
@@ -505,6 +520,8 @@ void close_files(struct thread_data *td)
        struct fio_file *f;
        unsigned int i;
 
+       dprint(FD_FILE, "close files\n");
+
        for_each_file(td, f, i) {
                if (td->o.unlink && f->filetype == FIO_TYPE_FILE)
                        unlink(f->file_name);
@@ -552,6 +569,8 @@ int add_file(struct thread_data *td, const char *fname)
        struct fio_file *f;
        int len = 0;
 
+       dprint(FD_FILE, "add file %s\n", fname);
+
        td->files = realloc(td->files, (cur_files + 1) * sizeof(*f));
 
        f = &td->files[cur_files];
@@ -581,12 +600,15 @@ int add_file(struct thread_data *td, const char *fname)
 
 void get_file(struct fio_file *f)
 {
+       dprint(FD_FILE, "get file %s, ref=%d\n", f->file_name, f->references);
        assert(f->flags & FIO_FILE_OPEN);
        f->references++;
 }
 
 void put_file(struct thread_data *td, struct fio_file *f)
 {
+       dprint(FD_FILE, "put file %s, ref=%d\n", f->file_name, f->references);
+
        if (!(f->flags & FIO_FILE_OPEN))
                return;