From 6977bcd0e4ee3faa7ffd8f208e4031bdf906ed88 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sat, 1 Mar 2008 15:55:36 +0100 Subject: [PATCH] Update close file handler to return potential error 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 --- engines/mmap.c | 17 +++++++++++++---- engines/sg.c | 2 +- filesetup.c | 20 ++++++++++++++------ fio.h | 10 +++++----- io_u.c | 8 ++++++-- ioengines.c | 4 ++-- 6 files changed, 41 insertions(+), 20 deletions(-) diff --git a/engines/mmap.c b/engines/mmap.c index 604f8b09..3e1e6c8d 100644 --- a/engines/mmap.c +++ b/engines/mmap.c @@ -107,14 +107,23 @@ err: 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) { - munmap(f->mmap, f->io_size); + if (munmap(f->mmap, f->io_size) < 0) + ret = errno; + 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 = { diff --git a/engines/sg.c b/engines/sg.c index a9ff93a3..c50ad55d 100644 --- a/engines/sg.c +++ b/engines/sg.c @@ -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)) { - generic_close_file(td, f); + ret = generic_close_file(td, f); return 1; } diff --git a/filesetup.c b/filesetup.c index 3e11c4c6..c0403d2a 100644 --- a/filesetup.c +++ b/filesetup.c @@ -209,11 +209,16 @@ int file_invalidate_cache(struct thread_data *td, struct fio_file *f) 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); - close(f->fd); + if (close(f->fd) < 0) + ret = errno; + f->fd = -1; + return ret; } 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++; } -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)) - return; + return 0; 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) - td->io_ops->close_file(td, f); + ret = td->io_ops->close_file(td, f); td->nr_open_files--; f->flags &= ~FIO_FILE_OPEN; + return ret; } static int recurse_dir(struct thread_data *td, const char *dirname) diff --git a/fio.h b/fio.h index 4fbc7044..92819349 100644 --- 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 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 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 *); @@ -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 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 @@ -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 *); - void (*close_file)(struct thread_data *, struct fio_file *); + int (*close_file)(struct thread_data *, struct fio_file *); 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 *); diff --git a/io_u.c b/io_u.c index faa1c5e3..0ffae29c 100644 --- 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; - 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); diff --git a/ioengines.c b/ioengines.c index 979ac283..a81c7b88 100644 --- a/ioengines.c +++ b/ioengines.c @@ -344,7 +344,7 @@ err: 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); @@ -354,5 +354,5 @@ void td_io_close_file(struct thread_data *td, struct fio_file *f) */ f->flags |= FIO_FILE_CLOSING; - put_file(td, f); + return put_file(td, f); } -- 2.25.1