Merge branch 'master' into gfio
authorJens Axboe <axboe@kernel.dk>
Fri, 14 Dec 2012 19:37:21 +0000 (20:37 +0100)
committerJens Axboe <axboe@kernel.dk>
Fri, 14 Dec 2012 19:37:21 +0000 (20:37 +0100)
engines/binject.c
engines/e4defrag.c
engines/falloc.c
engines/fusion-aw.c
engines/sync.c
file.h
filesetup.c
gettime.c
gettime.h
options.c

index 47d40fefbb3f6d8fd0a2037d22da60a5f21cbdfb..f78d8559a84572f7866073204002d3fb62139051 100644 (file)
@@ -69,7 +69,7 @@ static unsigned int binject_read_commands(struct thread_data *td, void *p,
 one_more:
        events = 0;
        for_each_file(td, f, i) {
-               bf = f->file_data;
+               bf = (void *) f->engine_data;
                ret = read(bf->fd, p, left * sizeof(struct b_user_cmd));
                if (ret < 0) {
                        if (errno == EAGAIN)
@@ -104,7 +104,7 @@ static int fio_binject_getevents(struct thread_data *td, unsigned int min,
         * Fill in the file descriptors
         */
        for_each_file(td, f, i) {
-               bf = f->file_data;
+               bf = (void *) f->engine_data;
 
                /*
                 * don't block for min events == 0
@@ -153,7 +153,7 @@ static int fio_binject_getevents(struct thread_data *td, unsigned int min,
 
        if (!min) {
                for_each_file(td, f, i) {
-                       bf = f->file_data;
+                       bf = (void *) f->engine_data;
                        fcntl(bf->fd, F_SETFL, bd->fd_flags[i]);
                }
        }
@@ -167,7 +167,7 @@ static int fio_binject_getevents(struct thread_data *td, unsigned int min,
 static int fio_binject_doio(struct thread_data *td, struct io_u *io_u)
 {
        struct b_user_cmd *buc = &io_u->buc;
-       struct binject_file *bf = io_u->file->file_data;
+       struct binject_file *bf = (void *) io_u->file->engine_data;
        int ret;
 
        ret = write(bf->fd, buc, sizeof(*buc));
@@ -181,7 +181,7 @@ static int fio_binject_prep(struct thread_data *td, struct io_u *io_u)
 {
        struct binject_data *bd = td->io_ops->data;
        struct b_user_cmd *buc = &io_u->buc;
-       struct binject_file *bf = io_u->file->file_data;
+       struct binject_file *bf = (void *) io_u->file->engine_data;
 
        if (io_u->xfer_buflen & (bf->bs - 1)) {
                log_err("read/write not sector aligned\n");
@@ -323,12 +323,12 @@ err_unmap:
 
 static int fio_binject_close_file(struct thread_data *td, struct fio_file *f)
 {
-       struct binject_file *bf = f->file_data;
+       struct binject_file *bf = (void *) f->engine_data;
 
        if (bf) {
                binject_unmap_dev(td, bf);
                free(bf);
-               f->file_data = NULL;
+               f->engine_data = 0;
                return generic_close_file(td, f);
        }
 
@@ -357,7 +357,7 @@ static int fio_binject_open_file(struct thread_data *td, struct fio_file *f)
        bf = malloc(sizeof(*bf));
        bf->bs = bs;
        bf->minor = bf->fd = -1;
-       f->file_data = bf;
+       f->engine_data = (uint64_t) bf;
 
        if (binject_map_dev(td, bf, f->fd)) {
 err_close:
index e10cf36a146c333cddddacb9df0b4f43b2d26ae1..6063e6c80c01dc36f82779297a28462e2ddff7a0 100644 (file)
@@ -161,9 +161,6 @@ static int fio_e4defrag_queue(struct thread_data *td, struct io_u *io_u)
        ret = ioctl(f->fd, EXT4_IOC_MOVE_EXT, &me);
        len = me.moved_len * ed->bsz;
 
-       if (io_u->file && len && ddir_rw(io_u->ddir))
-               io_u->file->file_pos = io_u->offset + len;
-
        if (len > io_u->xfer_buflen)
                len = io_u->xfer_buflen;
 
index bc5ebd716e7a072916cb47b5cabdae756328bf6a..525a0aae922d0e2d024122ba5e23ebcb24cbaf83 100644 (file)
@@ -89,9 +89,6 @@ static int fio_fallocate_queue(struct thread_data *td, struct io_u *io_u)
        if (ret)
                io_u->error = errno;
 
-       if (io_u->file && ret == 0 && ddir_rw(io_u->ddir))
-               io_u->file->file_pos = io_u->offset + ret;
-
        return FIO_Q_COMPLETED;
 }
 
index 9aac43a9af3216300bf5fd2ac50cb81a0384cd56..118c6dd5a0cc599ca2d36572eb86bcf92fec0e24 100644 (file)
@@ -88,7 +88,6 @@ static int queue(struct thread_data *td, struct io_u *io_u)
                goto out;
        } else {
                io_u->error = 0;
-               io_u->file->file_pos = io_u->offset + rc;
                rc = FIO_Q_COMPLETED;
        }
 
index bd912e7b5f808a2d7f1aa3c511802845a4510f01..87796289dcc9ca0591e265d1eee83696bd2eb034 100644 (file)
 
 #include "../fio.h"
 
+/*
+ * Sync engine uses engine_data to store last offset
+ */
+#define LAST_POS(f)    ((f)->engine_data)
+
 struct syncio_data {
        struct iovec *iovecs;
        struct io_u **io_us;
@@ -33,7 +38,7 @@ static int fio_syncio_prep(struct thread_data *td, struct io_u *io_u)
        if (!ddir_rw(io_u->ddir))
                return 0;
 
-       if (f->file_pos != -1ULL && f->file_pos == io_u->offset)
+       if (LAST_POS(f) != -1ULL && LAST_POS(f) == io_u->offset)
                return 0;
 
        if (lseek(f->fd, io_u->offset, SEEK_SET) == -1) {
@@ -47,7 +52,7 @@ static int fio_syncio_prep(struct thread_data *td, struct io_u *io_u)
 static int fio_io_end(struct thread_data *td, struct io_u *io_u, int ret)
 {
        if (io_u->file && ret >= 0 && ddir_rw(io_u->ddir))
-               io_u->file->file_pos = io_u->offset + ret;
+               LAST_POS(io_u->file) = io_u->offset + ret;
 
        if (ret != (int) io_u->xfer_buflen) {
                if (ret >= 0) {
diff --git a/file.h b/file.h
index 3024c5440094f4a711b993e80dc6b81264f42893..e57bebcffff605c4c5996b88287cb40ff9c9254d 100644 (file)
--- a/file.h
+++ b/file.h
@@ -63,8 +63,8 @@ struct fio_file {
        struct flist_head hash_list;
        enum fio_filetype filetype;
 
-       void *file_data;
        int fd;
+       int shadow_fd;
 #ifdef WIN32
        HANDLE hFile;
        HANDLE ioCP;
@@ -97,7 +97,7 @@ struct fio_file {
        /*
         * For use by the io engine
         */
-       unsigned long long file_pos;
+       uint64_t engine_data;
 
        /*
         * if io is protected by a semaphore, this is set
@@ -180,7 +180,6 @@ static inline void fio_file_reset(struct fio_file *f)
 {
        f->last_pos = f->file_offset;
        f->last_start = -1ULL;
-       f->file_pos = -1ULL;
        if (f->io_axmap)
                axmap_reset(f->io_axmap);
 }
index 3462a03d035d90d935e82994dce2787af4e98b5b..60894c4e10ee99184519f784cc5a866a667d2452 100644 (file)
@@ -434,6 +434,12 @@ int generic_close_file(struct thread_data fio_unused *td, struct fio_file *f)
                ret = errno;
 
        f->fd = -1;
+
+       if (f->shadow_fd != -1) {
+               close(f->shadow_fd);
+               f->shadow_fd = -1;
+       }
+
        return ret;
 }
 
@@ -462,6 +468,24 @@ int file_lookup_open(struct fio_file *f, int flags)
        return from_hash;
 }
 
+static int file_close_shadow_fds(struct thread_data *td)
+{
+       struct fio_file *f;
+       int num_closed = 0;
+       unsigned int i;
+
+       for_each_file(td, f, i) {
+               if (f->shadow_fd == -1)
+                       continue;
+
+               close(f->shadow_fd);
+               f->shadow_fd = -1;
+               num_closed++;
+       }
+
+       return num_closed;
+}
+
 int generic_open_file(struct thread_data *td, struct fio_file *f)
 {
        int is_std = 0;
@@ -536,6 +560,8 @@ open_again:
                        flags &= ~FIO_O_NOATIME;
                        goto open_again;
                }
+               if (__e == EMFILE && file_close_shadow_fds(td))
+                       goto open_again;
 
                snprintf(buf, sizeof(buf) - 1, "open(%s)", f->file_name);
 
@@ -552,9 +578,22 @@ open_again:
                        int fio_unused ret;
 
                        /*
-                        * OK to ignore, we haven't done anything with it
+                        * Stash away descriptor for later close. This is to
+                        * work-around a "feature" on Linux, where a close of
+                        * an fd that has been opened for write will trigger
+                        * udev to call blkid to check partitions, fs id, etc.
+                        * That polutes the device cache, which can slow down
+                        * unbuffered accesses.
                         */
-                       ret = generic_close_file(td, f);
+                       if (f->shadow_fd == -1)
+                               f->shadow_fd = f->fd;
+                       else {
+                               /*
+                                * OK to ignore, we haven't done anything
+                                * with it
+                                */
+                               ret = generic_close_file(td, f);
+                       }
                        goto open_again;
                }
        }
@@ -1029,6 +1068,7 @@ int add_file(struct thread_data *td, const char *fname)
        }
 
        f->fd = -1;
+       f->shadow_fd = -1;
        fio_file_reset(f);
 
        if (td->files_size <= td->files_index) {
index 1ba18e99877f3fc6cc5f07e8bd2185f8fadd93e0..9f23e3fff526e0611df0dd1c9d6dc1b62d059916 100644 (file)
--- a/gettime.c
+++ b/gettime.c
@@ -22,6 +22,7 @@ static int last_tv_valid;
 
 enum fio_cs fio_clock_source = FIO_PREFERRED_CLOCK_SOURCE;
 int fio_clock_source_set = 0;
+enum fio_cs fio_clock_source_inited = CS_INVAL;
 
 #ifdef FIO_DEBUG_TIME
 
@@ -262,7 +263,11 @@ static void calibrate_cpu_clock(void)
 
 void fio_clock_init(void)
 {
+       if (fio_clock_source == fio_clock_source_inited)
+               return;
+
        last_tv_valid = 0;
+       fio_clock_source_inited = fio_clock_source;
        calibrate_cpu_clock();
 
        /*
index 309ef2108a646e764b9e3e120cfecd7d8e9cf802..64651a1badb35ef2112e30cd46c69c857b9e4264 100644 (file)
--- a/gettime.h
+++ b/gettime.h
@@ -8,6 +8,7 @@ enum fio_cs {
        CS_GTOD         = 1,
        CS_CGETTIME,
        CS_CPUCLOCK,
+       CS_INVAL,
 };
 
 extern void fio_gettime(struct timeval *, void *);
index 917dbf0e3e9e41e8426e0639b910ec2094fd5a81..a7a133f834b169658a50734868e5df3c95ff4149 100644 (file)
--- a/options.c
+++ b/options.c
@@ -360,6 +360,7 @@ static int fio_clock_source_cb(void *data, const char *str)
 
        fio_clock_source = td->o.clocksource;
        fio_clock_source_set = 1;
+       fio_clock_init();
        return 0;
 }