summaryrefslogtreecommitdiff
path: root/engines/e4defrag.c
diff options
context:
space:
mode:
Diffstat (limited to 'engines/e4defrag.c')
-rw-r--r--engines/e4defrag.c218
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);
-}