Update close file handler to return potential error
authorJens Axboe <jens.axboe@oracle.com>
Sat, 1 Mar 2008 14:55:36 +0000 (15:55 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Sat, 1 Mar 2008 14:55:36 +0000 (15:55 +0100)
Filesystems like NFS do return errors on close(), up until now we
have been ignoring them. Fix that. Adjust io_ops engine version
to 9, since this is an API change.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
engines/mmap.c
engines/sg.c
filesetup.c
fio.h
io_u.c
ioengines.c

index 604f8b0902e75d9c0af70eca7ad8996b4c77f57d..3e1e6c8d9a38c5e4536cb34985680f6e6c9694cb 100644 (file)
@@ -107,14 +107,23 @@ err:
        return 1;
 }
 
        return 1;
 }
 
-static void fio_mmapio_close(struct thread_data fio_unused *td,
-                            struct fio_file *f)
+static int fio_mmapio_close(struct thread_data fio_unused *td,
+                           struct fio_file *f)
 {
 {
+       int ret = 0, ret2;
+
        if (f->mmap) {
        if (f->mmap) {
-               munmap(f->mmap, f->io_size);
+               if (munmap(f->mmap, f->io_size) < 0)
+                       ret = errno;
+
                f->mmap = NULL;
        }
                f->mmap = NULL;
        }
-       generic_close_file(td, f);
+
+       ret2 = generic_close_file(td, f);
+       if (!ret && ret2)
+               ret = ret2;
+
+       return ret;
 }
 
 static struct ioengine_ops ioengine = {
 }
 
 static struct ioengine_ops ioengine = {
index a9ff93a30280a5b95ceeb68bf04d83ce21bff4fe..c50ad55d764ee3a408f09bbe3637c5eac81ea39c 100644 (file)
@@ -388,7 +388,7 @@ static int fio_sgio_open(struct thread_data *td, struct fio_file *f)
                return ret;
 
        if (sd && !sd->type_checked && fio_sgio_type_check(td, f)) {
                return ret;
 
        if (sd && !sd->type_checked && fio_sgio_type_check(td, f)) {
-               generic_close_file(td, f);
+               ret = generic_close_file(td, f);
                return 1;
        }
 
                return 1;
        }
 
index 3e11c4c651050889457e37ccca6160204e81d0dd..c0403d2a801e863df927ed87a2a935161c7cb394 100644 (file)
@@ -209,11 +209,16 @@ int file_invalidate_cache(struct thread_data *td, struct fio_file *f)
        return ret;
 }
 
        return ret;
 }
 
-void generic_close_file(struct thread_data fio_unused *td, struct fio_file *f)
+int generic_close_file(struct thread_data fio_unused *td, struct fio_file *f)
 {
 {
+       int ret = 0;
+
        dprint(FD_FILE, "fd close %s\n", f->file_name);
        dprint(FD_FILE, "fd close %s\n", f->file_name);
-       close(f->fd);
+       if (close(f->fd) < 0)
+               ret = errno;
+
        f->fd = -1;
        f->fd = -1;
+       return ret;
 }
 
 int generic_open_file(struct thread_data *td, struct fio_file *f)
 }
 
 int generic_open_file(struct thread_data *td, struct fio_file *f)
@@ -614,25 +619,28 @@ void get_file(struct fio_file *f)
        f->references++;
 }
 
        f->references++;
 }
 
-void put_file(struct thread_data *td, struct fio_file *f)
+int put_file(struct thread_data *td, struct fio_file *f)
 {
 {
+       int ret = 0;
+
        dprint(FD_FILE, "put file %s, ref=%d\n", f->file_name, f->references);
 
        if (!(f->flags & FIO_FILE_OPEN))
        dprint(FD_FILE, "put file %s, ref=%d\n", f->file_name, f->references);
 
        if (!(f->flags & FIO_FILE_OPEN))
-               return;
+               return 0;
 
        assert(f->references);
        if (--f->references)
 
        assert(f->references);
        if (--f->references)
-               return;
+               return 0;
 
        if (should_fsync(td) && td->o.fsync_on_close)
                fsync(f->fd);
 
        if (td->io_ops->close_file)
 
        if (should_fsync(td) && td->o.fsync_on_close)
                fsync(f->fd);
 
        if (td->io_ops->close_file)
-               td->io_ops->close_file(td, f);
+               ret = td->io_ops->close_file(td, f);
 
        td->nr_open_files--;
        f->flags &= ~FIO_FILE_OPEN;
 
        td->nr_open_files--;
        f->flags &= ~FIO_FILE_OPEN;
+       return ret;
 }
 
 static int recurse_dir(struct thread_data *td, const char *dirname)
 }
 
 static int recurse_dir(struct thread_data *td, const char *dirname)
diff --git a/fio.h b/fio.h
index 4fbc704498aa521519c903cfea88466daa2e25cc..92819349dabedde6c95d69d8f843edb1a1078d11 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -805,10 +805,10 @@ extern int __must_check setup_files(struct thread_data *);
 extern int __must_check open_files(struct thread_data *);
 extern int __must_check file_invalidate_cache(struct thread_data *, struct fio_file *);
 extern int __must_check generic_open_file(struct thread_data *, struct fio_file *);
 extern int __must_check open_files(struct thread_data *);
 extern int __must_check file_invalidate_cache(struct thread_data *, struct fio_file *);
 extern int __must_check generic_open_file(struct thread_data *, struct fio_file *);
-extern void generic_close_file(struct thread_data *, struct fio_file *);
+extern int __must_check generic_close_file(struct thread_data *, struct fio_file *);
 extern int add_file(struct thread_data *, const char *);
 extern void get_file(struct fio_file *);
 extern int add_file(struct thread_data *, const char *);
 extern void get_file(struct fio_file *);
-extern void put_file(struct thread_data *, struct fio_file *);
+extern int __must_check put_file(struct thread_data *, struct fio_file *);
 extern int add_dir_files(struct thread_data *, const char *);
 extern int init_random_map(struct thread_data *);
 extern void dup_files(struct thread_data *, struct thread_data *);
 extern int add_dir_files(struct thread_data *, const char *);
 extern int init_random_map(struct thread_data *);
 extern void dup_files(struct thread_data *, struct thread_data *);
@@ -894,7 +894,7 @@ extern int __must_check td_io_sync(struct thread_data *, struct fio_file *);
 extern int __must_check td_io_getevents(struct thread_data *, unsigned int, unsigned int, struct timespec *);
 extern int __must_check td_io_commit(struct thread_data *);
 extern int __must_check td_io_open_file(struct thread_data *, struct fio_file *);
 extern int __must_check td_io_getevents(struct thread_data *, unsigned int, unsigned int, struct timespec *);
 extern int __must_check td_io_commit(struct thread_data *);
 extern int __must_check td_io_open_file(struct thread_data *, struct fio_file *);
-extern void td_io_close_file(struct thread_data *, struct fio_file *);
+extern int td_io_close_file(struct thread_data *, struct fio_file *);
 
 /*
  * blktrace support
 
 /*
  * blktrace support
@@ -919,12 +919,12 @@ struct ioengine_ops {
        int (*cancel)(struct thread_data *, struct io_u *);
        void (*cleanup)(struct thread_data *);
        int (*open_file)(struct thread_data *, struct fio_file *);
        int (*cancel)(struct thread_data *, struct io_u *);
        void (*cleanup)(struct thread_data *);
        int (*open_file)(struct thread_data *, struct fio_file *);
-       void (*close_file)(struct thread_data *, struct fio_file *);
+       int (*close_file)(struct thread_data *, struct fio_file *);
        void *data;
        void *dlhandle;
 };
 
        void *data;
        void *dlhandle;
 };
 
-#define FIO_IOOPS_VERSION      8
+#define FIO_IOOPS_VERSION      9
 
 extern struct ioengine_ops *load_ioengine(struct thread_data *, const char *);
 extern void register_ioengine(struct ioengine_ops *);
 
 extern struct ioengine_ops *load_ioengine(struct thread_data *, const char *);
 extern void register_ioengine(struct ioengine_ops *);
diff --git a/io_u.c b/io_u.c
index faa1c5e36a8d84ac558d6867a7e796ec5a71d8fe..0ffae29c9f035a2d387ad00b0ae7d882ac0515b3 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -328,8 +328,12 @@ void put_io_u(struct thread_data *td, struct io_u *io_u)
        assert((io_u->flags & IO_U_F_FREE) == 0);
        io_u->flags |= IO_U_F_FREE;
 
        assert((io_u->flags & IO_U_F_FREE) == 0);
        io_u->flags |= IO_U_F_FREE;
 
-       if (io_u->file)
-               put_file(td, io_u->file);
+       if (io_u->file) {
+               int ret = put_file(td, io_u->file);
+
+               if (ret)
+                       td_verror(td, ret, "file close");
+       }
 
        io_u->file = NULL;
        list_del(&io_u->list);
 
        io_u->file = NULL;
        list_del(&io_u->list);
index 979ac28322fdff473b31dbda5a3240cced718324..a81c7b884b5df6352cca79d5e47bb5eae47b2973 100644 (file)
@@ -344,7 +344,7 @@ err:
        return 1;
 }
 
        return 1;
 }
 
-void td_io_close_file(struct thread_data *td, struct fio_file *f)
+int td_io_close_file(struct thread_data *td, struct fio_file *f)
 {
        if (!(f->flags & FIO_FILE_CLOSING))
                log_file(td, f, FIO_LOG_CLOSE_FILE);
 {
        if (!(f->flags & FIO_FILE_CLOSING))
                log_file(td, f, FIO_LOG_CLOSE_FILE);
@@ -354,5 +354,5 @@ void td_io_close_file(struct thread_data *td, struct fio_file *f)
         */
        f->flags |= FIO_FILE_CLOSING;
 
         */
        f->flags |= FIO_FILE_CLOSING;
 
-       put_file(td, f);
+       return put_file(td, f);
 }
 }