examples: Avoid duplicated items
[fio.git] / filesetup.c
index 76b3f9359bad79b44b21d17a8edb74f869b15b7a..296de5a11a3d015f65ffd28311d0278eca4341f7 100644 (file)
@@ -226,11 +226,16 @@ static int extend_file(struct thread_data *td, struct fio_file *f)
                        if (r < 0) {
                                int __e = errno;
 
-                               if (__e == ENOSPC) {
+                               if (__e == ENOSPC || __e == EDQUOT) {
+                                       const char *__e_name;
                                        if (td->o.fill_device)
                                                break;
-                                       log_info("fio: ENOSPC on laying out "
-                                                "file, stopping\n");
+                                       if (__e == ENOSPC)
+                                               __e_name = "ENOSPC";
+                                       else
+                                               __e_name = "EDQUOT";
+                                       log_info("fio: %s on laying out "
+                                                "file, stopping\n", __e_name);
                                }
                                td_verror(td, errno, "write");
                        } else
@@ -338,6 +343,95 @@ error:
        return ret;
 }
 
+/*
+ * Generic function to prepopulate regular file with data.
+ * Useful if you want to make sure I/O engine has data to read.
+ * Leaves f->fd open on success, caller must close.
+ */
+int generic_prepopulate_file(struct thread_data *td, struct fio_file *f)
+{
+       int flags;
+       unsigned long long left, bs;
+       char *b = NULL;
+
+       /* generic function for regular files only */
+       assert(f->filetype == FIO_TYPE_FILE);
+
+       if (read_only) {
+               log_err("fio: refusing to write a file due to read-only\n");
+               return 0;
+       }
+
+       flags = O_WRONLY;
+       if (td->o.allow_create)
+               flags |= O_CREAT;
+
+#ifdef WIN32
+       flags |= _O_BINARY;
+#endif
+
+       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) {
+               int err = errno;
+
+               if (err == ENOENT && !td->o.allow_create)
+                       log_err("fio: file creation disallowed by "
+                                       "allow_file_create=0\n");
+               else
+                       td_verror(td, err, "open");
+               return 1;
+       }
+
+       left = f->real_file_size;
+       bs = td->o.max_bs[DDIR_WRITE];
+       if (bs > left)
+               bs = left;
+
+       b = malloc(bs);
+       if (!b) {
+               td_verror(td, errno, "malloc");
+               goto err;
+       }
+
+       while (left && !td->terminate) {
+               ssize_t r;
+
+               if (bs > left)
+                       bs = left;
+
+               fill_io_buffer(td, b, bs, bs);
+
+               r = write(f->fd, b, bs);
+
+               if (r > 0) {
+                       left -= r;
+               } else {
+                       td_verror(td, errno, "write");
+                       goto err;
+               }
+       }
+
+       if (td->terminate) {
+               dprint(FD_FILE, "terminate unlink %s\n", f->file_name);
+               td_io_unlink_file(td, f);
+       } else if (td->o.create_fsync) {
+               if (fsync(f->fd) < 0) {
+                       td_verror(td, errno, "fsync");
+                       goto err;
+               }
+       }
+
+       free(b);
+       return 0;
+err:
+       close(f->fd);
+       f->fd = -1;
+       if (b)
+               free(b);
+       return 1;
+}
+
 unsigned long long get_rand_file_size(struct thread_data *td)
 {
        unsigned long long ret, sized;
@@ -1029,6 +1123,13 @@ int setup_files(struct thread_data *td)
        if (o->read_iolog_file)
                goto done;
 
+       if (td->o.zone_mode == ZONE_MODE_ZBD) {
+               err = zbd_init_files(td);
+               if (err)
+                       goto err_out;
+       }
+       zbd_recalc_options_with_zone_granularity(td);
+
        /*
         * check sizes. if the files/devices do not exist and the size
         * isn't passed to fio, abort.
@@ -1254,6 +1355,43 @@ int setup_files(struct thread_data *td)
                temp_stall_ts = 0;
        }
 
+       if (err)
+               goto err_out;
+
+       /*
+        * Prepopulate files with data. It might be expected to read some
+        * "real" data instead of zero'ed files (if no writes to file occurred
+        * prior to a read job). Engine has to provide a way to do that.
+        */
+       if (td->io_ops->prepopulate_file) {
+               temp_stall_ts = 1;
+
+               for_each_file(td, f, i) {
+                       if (output_format & FIO_OUTPUT_NORMAL) {
+                               log_info("%s: Prepopulating IO file (%s)\n",
+                                                       o->name, f->file_name);
+                       }
+
+                       err = td->io_ops->prepopulate_file(td, f);
+                       if (err)
+                               break;
+
+                       err = __file_invalidate_cache(td, f, f->file_offset,
+                                                               f->io_size);
+
+                       /*
+                        * Shut up static checker
+                        */
+                       if (f->fd != -1)
+                               close(f->fd);
+
+                       f->fd = -1;
+                       if (err)
+                               break;
+               }
+               temp_stall_ts = 0;
+       }
+
        if (err)
                goto err_out;
 
@@ -1269,16 +1407,17 @@ int setup_files(struct thread_data *td)
        }
 
 done:
-       if (o->create_only)
-               td->done = 1;
-
-       td_restore_runstate(td, old_state);
-
        if (td->o.zone_mode == ZONE_MODE_ZBD) {
                err = zbd_setup_files(td);
                if (err)
                        goto err_out;
        }
+
+       if (o->create_only)
+               td->done = 1;
+
+       td_restore_runstate(td, old_state);
+
        return 0;
 
 err_offset:
@@ -1319,11 +1458,11 @@ static void __init_rand_distribution(struct thread_data *td, struct fio_file *f)
                seed = td->rand_seeds[4];
 
        if (td->o.random_distribution == FIO_RAND_DIST_ZIPF)
-               zipf_init(&f->zipf, nranges, td->o.zipf_theta.u.f, seed);
+               zipf_init(&f->zipf, nranges, td->o.zipf_theta.u.f, td->o.random_center.u.f, seed);
        else if (td->o.random_distribution == FIO_RAND_DIST_PARETO)
-               pareto_init(&f->zipf, nranges, td->o.pareto_h.u.f, seed);
+               pareto_init(&f->zipf, nranges, td->o.pareto_h.u.f, td->o.random_center.u.f, seed);
        else if (td->o.random_distribution == FIO_RAND_DIST_GAUSS)
-               gauss_init(&f->gauss, nranges, td->o.gauss_dev.u.f, seed);
+               gauss_init(&f->gauss, nranges, td->o.gauss_dev.u.f, td->o.random_center.u.f, seed);
 }
 
 static bool init_rand_distribution(struct thread_data *td)