Fio 1.43
[fio.git] / filesetup.c
index 8aa9fc7461397513fca56b1f58b280a49b210782..5a8105a6032e24b2e45a8a9d028c2a0b7e2552fe 100644 (file)
@@ -71,9 +71,9 @@ static int extend_file(struct thread_data *td, struct fio_file *f)
                                                        f->real_file_size);
 
                r = posix_fallocate(f->fd, 0, f->real_file_size);
-               if (r < 0) {
+               if (r > 0) {
                        log_err("fio: posix_fallocate fails: %s\n",
-                                       strerror(-r));
+                                       strerror(r));
                }
        }
 #endif
@@ -260,6 +260,41 @@ err:
        return 1;
 }
 
+static int char_size(struct thread_data *td, struct fio_file *f)
+{
+#ifdef FIO_HAVE_CHARDEV_SIZE
+       unsigned long long bytes;
+       int r;
+
+       if (td->io_ops->open_file(td, f)) {
+               log_err("fio: failed opening blockdev %s for size check\n",
+                       f->file_name);
+               return 1;
+       }
+
+       r = chardev_size(f->fd, &bytes);
+       if (r) {
+               td_verror(td, r, "chardev_size");
+               goto err;
+       }
+
+       if (!bytes) {
+               log_err("%s: zero sized char device?\n", f->file_name);
+               goto err;
+       }
+
+       f->real_file_size = bytes;
+       td->io_ops->close_file(td, f);
+       return 0;
+err:
+       td->io_ops->close_file(td, f);
+       return 1;
+#else
+       f->real_file_size = -1ULL;
+       return 0;
+#endif
+}
+
 static int get_file_size(struct thread_data *td, struct fio_file *f)
 {
        int ret = 0;
@@ -271,6 +306,8 @@ static int get_file_size(struct thread_data *td, struct fio_file *f)
                ret = file_size(td, f);
        else if (f->filetype == FIO_TYPE_BD)
                ret = bdev_size(td, f);
+       else if (f->filetype == FIO_TYPE_CHAR)
+               ret = char_size(td, f);
        else
                f->real_file_size = -1;
 
@@ -527,8 +564,9 @@ static unsigned long long get_fs_free_counts(struct thread_data *td)
                struct stat sb;
                char buf[256];
 
-               if (f->filetype == FIO_TYPE_BD) {
-                       ret += f->real_file_size;
+               if (f->filetype == FIO_TYPE_BD || f->filetype == FIO_TYPE_CHAR) {
+                       if (f->real_file_size != -1ULL)
+                               ret += f->real_file_size;
                        continue;
                } else if (f->filetype != FIO_TYPE_FILE)
                        continue;
@@ -871,6 +909,7 @@ int add_file(struct thread_data *td, const char *fname)
        }
 
        f->fd = -1;
+       fio_file_reset(f);
 
        if (td->files_size <= td->files_index) {
                int new_size = td->o.nr_files + 1;
@@ -924,6 +963,19 @@ int add_file(struct thread_data *td, const char *fname)
        return cur_files;
 }
 
+int add_file_exclusive(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 add_file(td, fname);
+}
+
 void get_file(struct fio_file *f)
 {
        dprint(FD_FILE, "get file %s, ref=%d\n", f->file_name, f->references);
@@ -1098,6 +1150,7 @@ void dup_files(struct thread_data *td, struct thread_data *org)
                        assert(0);
                }
                __f->fd = -1;
+               fio_file_reset(__f);
 
                if (f->file_name) {
                        __f->file_name = smalloc_strdup(f->file_name);