diff options
Diffstat (limited to 'engines/e4defrag.c')
-rw-r--r-- | engines/e4defrag.c | 218 |
1 files changed, 0 insertions, 218 deletions
diff --git a/engines/e4defrag.c b/engines/e4defrag.c deleted file mode 100644 index 4b444888..00000000 --- a/engines/e4defrag.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * ioe_e4defrag: ioengine for git://git.kernel.dk/fio.git - * - * IO engine that does regular EXT4_IOC_MOVE_EXT ioctls to simulate - * defragment activity - * - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/uio.h> -#include <errno.h> -#include <assert.h> -#include <fcntl.h> - -#include "../fio.h" -#include "../optgroup.h" - -#ifndef EXT4_IOC_MOVE_EXT -#define EXT4_IOC_MOVE_EXT _IOWR('f', 15, struct move_extent) -struct move_extent { - __u32 reserved; /* should be zero */ - __u32 donor_fd; /* donor file descriptor */ - __u64 orig_start; /* logical start offset in block for orig */ - __u64 donor_start; /* logical start offset in block for donor */ - __u64 len; /* block length to be moved */ - __u64 moved_len; /* moved block length */ -}; -#endif - -struct e4defrag_data { - int donor_fd; - int bsz; -}; - -struct e4defrag_options { - void *pad; - unsigned int inplace; - char * donor_name; -}; - -static struct fio_option options[] = { - { - .name = "donorname", - .lname = "Donor Name", - .type = FIO_OPT_STR_STORE, - .off1 = offsetof(struct e4defrag_options, donor_name), - .help = "File used as a block donor", - .category = FIO_OPT_C_ENGINE, - .group = FIO_OPT_G_E4DEFRAG, - }, - { - .name = "inplace", - .lname = "In Place", - .type = FIO_OPT_INT, - .off1 = offsetof(struct e4defrag_options, inplace), - .minval = 0, - .maxval = 1, - .help = "Alloc and free space inside defrag event", - .category = FIO_OPT_C_ENGINE, - .group = FIO_OPT_G_E4DEFRAG, - }, - { - .name = NULL, - }, -}; - -static int fio_e4defrag_init(struct thread_data *td) -{ - int r, len = 0; - struct e4defrag_options *o = td->eo; - struct e4defrag_data *ed; - struct stat stub; - char donor_name[PATH_MAX]; - - if (!strlen(o->donor_name)) { - log_err("'donorname' options required\n"); - return 1; - } - - ed = malloc(sizeof(*ed)); - if (!ed) { - td_verror(td, ENOMEM, "io_queue_init"); - return 1; - } - memset(ed, 0 ,sizeof(*ed)); - - if (td->o.directory) - len = sprintf(donor_name, "%s/", td->o.directory); - sprintf(donor_name + len, "%s", o->donor_name); - - ed->donor_fd = open(donor_name, O_CREAT|O_WRONLY, 0644); - if (ed->donor_fd < 0) { - td_verror(td, errno, "io_queue_init"); - log_err("Can't open donor file %s err:%d\n", donor_name, ed->donor_fd); - free(ed); - return 1; - } - - if (!o->inplace) { - long long __len = td->o.file_size_high - td->o.start_offset; - r = fallocate(ed->donor_fd, 0, td->o.start_offset, __len); - if (r) - goto err; - } - r = fstat(ed->donor_fd, &stub); - if (r) - goto err; - - ed->bsz = stub.st_blksize; - td->io_ops_data = ed; - return 0; -err: - td_verror(td, errno, "io_queue_init"); - close(ed->donor_fd); - free(ed); - return 1; -} - -static void fio_e4defrag_cleanup(struct thread_data *td) -{ - struct e4defrag_data *ed = td->io_ops_data; - if (ed) { - if (ed->donor_fd >= 0) - close(ed->donor_fd); - free(ed); - } -} - - -static int fio_e4defrag_queue(struct thread_data *td, struct io_u *io_u) -{ - - int ret; - unsigned long long len; - struct move_extent me; - struct fio_file *f = io_u->file; - struct e4defrag_data *ed = td->io_ops_data; - struct e4defrag_options *o = td->eo; - - fio_ro_check(td, io_u); - - /* Theoretically defragmentation should not change data, but it - * changes data layout. So this function handle only DDIR_WRITE - * in order to satisfy strict read only access pattern - */ - if (io_u->ddir != DDIR_WRITE) { - io_u->error = EINVAL; - return FIO_Q_COMPLETED; - } - - if (o->inplace) { - ret = fallocate(ed->donor_fd, 0, io_u->offset, io_u->xfer_buflen); - if (ret) - goto out; - } - - memset(&me, 0, sizeof(me)); - me.donor_fd = ed->donor_fd; - me.orig_start = io_u->offset / ed->bsz; - me.donor_start = me.orig_start; - len = (io_u->offset + io_u->xfer_buflen + ed->bsz -1); - me.len = len / ed->bsz - me.orig_start; - - ret = ioctl(f->fd, EXT4_IOC_MOVE_EXT, &me); - len = me.moved_len * ed->bsz; - - if (len > io_u->xfer_buflen) - len = io_u->xfer_buflen; - - if (len != io_u->xfer_buflen) { - if (len) { - io_u->resid = io_u->xfer_buflen - len; - io_u->error = 0; - } else { - /* access beyond i_size */ - io_u->error = EINVAL; - } - } - if (ret) - io_u->error = errno; - - if (o->inplace) - ret = ftruncate(ed->donor_fd, 0); -out: - if (ret && !io_u->error) - io_u->error = errno; - - return FIO_Q_COMPLETED; -} - -static struct ioengine_ops ioengine = { - .name = "e4defrag", - .version = FIO_IOOPS_VERSION, - .init = fio_e4defrag_init, - .queue = fio_e4defrag_queue, - .open_file = generic_open_file, - .close_file = generic_close_file, - .get_file_size = generic_get_file_size, - .flags = FIO_SYNCIO, - .cleanup = fio_e4defrag_cleanup, - .options = options, - .option_struct_size = sizeof(struct e4defrag_options), - -}; - -static void fio_init fio_syncio_register(void) -{ - register_ioengine(&ioengine); -} - -static void fio_exit fio_syncio_unregister(void) -{ - unregister_ioengine(&ioengine); -} |