/*
* glusterfs engine
*
- * IO engine using Glusterfs's gfapi interface
+ * common Glusterfs's gfapi interface
*
*/
-#include <glusterfs/api/glfs.h>
-#include <glusterfs/api/glfs-handles.h>
-#include "../fio.h"
+#include "gfapi.h"
-struct gf_options {
- struct thread_data *td;
- char *gf_vol;
- char *gf_brick;
-};
-
-struct gf_data {
- glfs_t *fs;
- glfs_fd_t *fd;
-};
-
-static struct fio_option options[] = {
+struct fio_option gfapi_options[] = {
{
.name = "volume",
.lname = "Glusterfs volume",
},
};
-static int fio_gf_setup(struct thread_data *td)
+int fio_gf_setup(struct thread_data *td)
{
int r = 0;
struct gf_data *g = NULL;
log_err("malloc failed.\n");
return -ENOMEM;
}
- g->fs = NULL; g->fd = NULL;
+ g->fs = NULL; g->fd = NULL; g->aio_events = NULL;
g->fs = glfs_new (opt->gf_vol);
if (!g->fs){
glfs_fini(g->fs);
}
free(g);
+ td->io_ops->data = NULL;
}
}
return r;
}
-static void fio_gf_cleanup(struct thread_data *td)
+void fio_gf_cleanup(struct thread_data *td)
{
+ struct gf_data *g = td->io_ops->data;
+
+ if (g) {
+ if (g->aio_events)
+ free(g->aio_events);
+ if (g->fd)
+ glfs_close(g->fd);
+ if (g->fs)
+ glfs_fini(g->fs);
+ free(g);
+ td->io_ops->data = NULL;
+ }
}
-static int fio_gf_get_file_size(struct thread_data *td, struct fio_file *f)
+int fio_gf_get_file_size(struct thread_data *td, struct fio_file *f)
{
struct stat buf;
int ret;
}
-static int fio_gf_open_file(struct thread_data *td, struct fio_file *f)
+int fio_gf_open_file(struct thread_data *td, struct fio_file *f)
{
int flags = 0;
return ret;
}
-static int fio_gf_close_file(struct thread_data *td, struct fio_file *f)
+int fio_gf_close_file(struct thread_data *td, struct fio_file *f)
{
int ret = 0;
struct gf_data *g = td->io_ops->data;
dprint(FD_FILE, "fd close %s\n", f->file_name);
- if (g->fd && glfs_close(g->fd) < 0)
- ret = errno;
+ if (g){
+ if (g->fd && glfs_close(g->fd) < 0)
+ ret = errno;
- if (g->fs)
- glfs_fini(g->fs);
+ if (g->fs)
+ glfs_fini(g->fs);
- g->fd = NULL;
- free(g);
+ g->fd = NULL;
+ free(g);
+ }
td->io_ops->data = NULL;
f->engine_data = 0;
return ret;
}
-#define LAST_POS(f) ((f)->engine_data)
-static int fio_gf_prep(struct thread_data *td, struct io_u *io_u)
-{
- struct fio_file *f = io_u->file;
- struct gf_data *g = td->io_ops->data;
-
- dprint(FD_FILE, "fio prep\n");
-
- if (!ddir_rw(io_u->ddir))
- return 0;
-
- if (LAST_POS(f) != -1ULL && LAST_POS(f) == io_u->offset)
- return 0;
-
- if (glfs_lseek(g->fd, io_u->offset, SEEK_SET) < 0) {
- td_verror(td, errno, "lseek");
- return 1;
- }
-
- return 0;
-}
-
-static int fio_gf_queue(struct thread_data *td, struct io_u *io_u)
-{
- struct gf_data *g = td->io_ops->data;
- int ret = 0;
-
- dprint(FD_FILE, "fio queue len %lu\n", io_u->xfer_buflen);
- fio_ro_check(td, io_u);
-
- if (io_u->ddir == DDIR_READ)
- ret = glfs_read(g->fd, io_u->xfer_buf, io_u->xfer_buflen, 0);
- else if (io_u->ddir == DDIR_WRITE)
- ret = glfs_write(g->fd, io_u->xfer_buf, io_u->xfer_buflen, 0);
- else {
- log_err("unsupported operation.\n");
- return -EINVAL;
- }
- dprint(FD_FILE, "fio len %lu ret %d\n", io_u->xfer_buflen, ret);
- if (io_u->file && ret >= 0 && ddir_rw(io_u->ddir))
- LAST_POS(io_u->file) = io_u->offset + ret;
-
- if (ret != (int) io_u->xfer_buflen) {
- if (ret >= 0) {
- io_u->resid = io_u->xfer_buflen - ret;
- io_u->error = 0;
- return FIO_Q_COMPLETED;
- } else
- io_u->error = errno;
- }
-
- if (io_u->error){
- log_err("IO failed.\n");
- td_verror(td, io_u->error, "xfer");
- }
-
- return FIO_Q_COMPLETED;
-
-}
-
-static struct ioengine_ops ioengine = {
- .name = "gfapi",
- .version = FIO_IOOPS_VERSION,
- .init = fio_gf_setup,
- .cleanup = fio_gf_cleanup,
- .prep = fio_gf_prep,
- .queue = fio_gf_queue,
- .open_file = fio_gf_open_file,
- .close_file = fio_gf_close_file,
- .get_file_size = fio_gf_get_file_size,
- .options = options,
- .option_struct_size = sizeof(struct gf_options),
- .flags = FIO_SYNCIO | FIO_DISKLESSIO,
-};
-
-static void fio_init fio_gf_register(void)
-{
- register_ioengine(&ioengine);
-}
-
-static void fio_exit fio_gf_unregister(void)
-{
- unregister_ioengine(&ioengine);
-}