Add fill_device option
[fio.git] / filesetup.c
index 5134fdbb8af5a52e08e5ad8b60ea820e0caeab9f..210cd2ff7ed437a1f19414a82e20600486cdfbc5 100644 (file)
@@ -234,6 +234,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 +263,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);
@@ -374,7 +380,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,7 +403,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->io_size || f->io_size > f->real_file_size) &&
+                            f->real_file_size) {
                                if (f->file_offset > f->real_file_size)
                                        goto err_offset;
                                f->io_size = f->real_file_size - f->file_offset;
@@ -478,7 +485,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 +493,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");