Add unlink hook to ioengine API, gluster ioengine
authorCastor Fu <castor@alumni.caltech.edu>
Tue, 19 Aug 2014 16:28:53 +0000 (09:28 -0700)
committerJens Axboe <axboe@fb.com>
Tue, 19 Aug 2014 20:15:19 +0000 (15:15 -0500)
fio would just call unlink even with engines that are not using the
operating systems file namespace... This provides a hook to allow
overriding that, with a default handler, and implements it for the
gluster ioengine.

There are others which it'd probably make sense I'm sure.

Huamin Chen looked over my changes to the gluster code earlier...
>I like this unlink idea, it would be great if you can also make unlink optional (if my coding reading is correct). This looks a great pull request candidate to fio. Please ping Axboe after you are done. He is not actively watching pull requests.

>Please also feel free to augment gluster code and pull me for review if necessary.

-castor

Signed-off-by: Jens Axboe <axboe@fb.com>
engines/gfapi.h
engines/glusterfs.c
engines/glusterfs_async.c
engines/glusterfs_sync.c
filesetup.c
ioengine.h
ioengines.c
iolog.c

index c79838b7d61c28f08e6108dd3a17e4f1da792454..0da471c7499b5e4811f7c289b0930e14959ba6ac 100644 (file)
@@ -19,3 +19,4 @@ extern void fio_gf_cleanup(struct thread_data *td);
 extern int fio_gf_get_file_size(struct thread_data *td, struct fio_file *f);
 extern int fio_gf_open_file(struct thread_data *td, struct fio_file *f);
 extern int fio_gf_close_file(struct thread_data *td, struct fio_file *f);
+extern int fio_gf_unlink_file(struct thread_data *td, struct fio_file *f);
index 52df9e8a0608f2d73b89a70c962a52cfe79abd63..507cd25dc89d0c638193134d0543b0670da0ed50 100644 (file)
@@ -223,10 +223,10 @@ int fio_gf_open_file(struct thread_data *td, struct fio_file *f)
                                        free(b);
                                glfs_lseek(g->fd, 0, SEEK_SET);
 
-                               if (td->terminate) {
+                               if (td->terminate && td->o.unlink) {
                                        dprint(FD_FILE, "terminate unlink %s\n",
                                               f->file_name);
-                                       unlink(f->file_name);
+                                       glfs_unlink(g->fs, f->file_name);
                                } else if (td->o.create_fsync) {
                                        if (glfs_fsync(g->fd) < 0) {
                                                dprint(FD_FILE,
@@ -274,6 +274,24 @@ int fio_gf_close_file(struct thread_data *td, struct fio_file *f)
        if (g) {
                if (g->fd && glfs_close(g->fd) < 0)
                        ret = errno;
+               g->fd = NULL;
+       }
+
+       return ret;
+}
+
+int fio_gf_unlink_file(struct thread_data *td, struct fio_file *f)
+{
+       int ret = 0;
+       struct gf_data *g = td->io_ops->data;
+
+       dprint(FD_FILE, "fd unlink %s\n", f->file_name);
+
+       if (g) {
+               if (g->fd && glfs_close(g->fd) < 0)
+                       ret = errno;
+
+               glfs_unlink(g->fs, f->file_name);
 
                if (g->fs)
                        glfs_fini(g->fs);
@@ -282,7 +300,6 @@ int fio_gf_close_file(struct thread_data *td, struct fio_file *f)
                free(g);
        }
        td->io_ops->data = NULL;
-       f->engine_data = 0;
 
        return ret;
 }
index 30f1719df6177b3166b87976cb68155719958953..7b0b30a747fc460c921b4ee0776abfaed5cce4d9 100644 (file)
@@ -186,6 +186,7 @@ static struct ioengine_ops ioengine = {
        .queue = fio_gf_async_queue,
        .open_file = fio_gf_open_file,
        .close_file = fio_gf_close_file,
+       .unlink_file = fio_gf_unlink_file,
        .get_file_size = fio_gf_get_file_size,
        .getevents = fio_gf_getevents,
        .event = fio_gf_event,
index 938baf46d0eeac32ac9b7178ece129d8c17581a7..235d74f64e1e3c9cfed9067d4ed75cff608e97eb 100644 (file)
@@ -76,6 +76,7 @@ static struct ioengine_ops ioengine = {
        .queue = fio_gf_queue,
        .open_file = fio_gf_open_file,
        .close_file = fio_gf_close_file,
+       .unlink_file = fio_gf_unlink_file,
        .get_file_size = fio_gf_get_file_size,
        .options = gfapi_options,
        .option_struct_size = sizeof(struct gf_options),
index 12a43b1fa14459439dd73013dd4ef018e5f6bfba..29a76c0c3f5a52d60d18cb9775ec8b99bc603a1a 100644 (file)
@@ -59,7 +59,7 @@ static int extend_file(struct thread_data *td, struct fio_file *f)
 
        if (unlink_file || new_layout) {
                dprint(FD_FILE, "layout unlink %s\n", f->file_name);
-               if ((unlink(f->file_name) < 0) && (errno != ENOENT)) {
+               if ((td_io_unlink_file(td, f) < 0) && (errno != ENOENT)) {
                        td_verror(td, errno, "unlink");
                        return 1;
                }
@@ -172,7 +172,7 @@ static int extend_file(struct thread_data *td, struct fio_file *f)
 
        if (td->terminate) {
                dprint(FD_FILE, "terminate unlink %s\n", f->file_name);
-               unlink(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");
@@ -1100,6 +1100,11 @@ void close_and_free_files(struct thread_data *td)
        dprint(FD_FILE, "close files\n");
 
        for_each_file(td, f, i) {
+               if (td->o.unlink && f->filetype == FIO_TYPE_FILE) {
+                       dprint(FD_FILE, "free unlink %s\n", f->file_name);
+                       td_io_unlink_file(td, f);
+               }
+
                if (fio_file_open(f))
                        td_io_close_file(td, f);
 
@@ -1107,7 +1112,7 @@ void close_and_free_files(struct thread_data *td)
 
                if (td->o.unlink && f->filetype == FIO_TYPE_FILE) {
                        dprint(FD_FILE, "free unlink %s\n", f->file_name);
-                       unlink(f->file_name);
+                       td_io_unlink_file(td, f);
                }
 
                sfree(f->file_name);
index ebe0ebe9afb5338e3ab5e08e4087418a308adbdd..a8af6b0a2e4df5a118be8f0300cd72ca7b4dd407 100644 (file)
@@ -144,6 +144,7 @@ struct ioengine_ops {
        int (*open_file)(struct thread_data *, struct fio_file *);
        int (*close_file)(struct thread_data *, struct fio_file *);
        int (*invalidate)(struct thread_data *, struct fio_file *);
+       int (*unlink_file)(struct thread_data *, struct fio_file *);
        int (*get_file_size)(struct thread_data *, struct fio_file *);
        void (*terminate)(struct thread_data *);
        int (*io_u_init)(struct thread_data *, struct io_u *);
@@ -185,6 +186,7 @@ extern int __must_check td_io_getevents(struct thread_data *, unsigned int, unsi
 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 td_io_close_file(struct thread_data *, struct fio_file *);
+extern int td_io_unlink_file(struct thread_data *, struct fio_file *);
 extern int __must_check td_io_get_file_size(struct thread_data *, struct fio_file *);
 
 extern struct ioengine_ops *load_ioengine(struct thread_data *, const char *);
index 0f94d0d9513da64337bbb23284ebb09001b2ebd9..3010f6c146c4dbbcf0f9d191d0f44f22dfaa46d2 100644 (file)
@@ -506,6 +506,14 @@ int td_io_close_file(struct thread_data *td, struct fio_file *f)
        return put_file(td, f);
 }
 
+int td_io_unlink_file(struct thread_data *td, struct fio_file *f)
+{
+       if (td->io_ops->unlink_file)
+               return td->io_ops->unlink_file(td, f);
+       else
+               return unlink(f->file_name);
+}
+
 int td_io_get_file_size(struct thread_data *td, struct fio_file *f)
 {
        if (!td->io_ops->get_file_size)
diff --git a/iolog.c b/iolog.c
index 70ccfba482204e123ebfbda8187977486f92b8eb..f9e835d4b087aa17755d41f76a59d6cf0bb95c7e 100644 (file)
--- a/iolog.c
+++ b/iolog.c
@@ -107,7 +107,7 @@ static int ipo_special(struct thread_data *td, struct io_piece *ipo)
                td_io_close_file(td, f);
                break;
        case FIO_LOG_UNLINK_FILE:
-               unlink(f->file_name);
+               td_io_unlink_file(td, f);
                break;
        default:
                log_err("fio: bad file action %d\n", ipo->file_action);