engines: add engine for file delete
authorFriendy.Su@sony.com <Friendy.Su@sony.com>
Wed, 14 Apr 2021 03:57:09 +0000 (03:57 +0000)
committerJens Axboe <axboe@kernel.dk>
Fri, 16 Apr 2021 11:56:19 +0000 (05:56 -0600)
This engine is to measure the performance of deleting files.

In practice, it is an important benchmark for a file system that
how quick it can release the disk space of deleted files.

Signed-off-by: friendy-su <friendy.su@sony.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
HOWTO
Makefile
engines/filedelete.c [new file with mode: 0644]
examples/filedelete-ioengine.fio [new file with mode: 0644]
fio.1

diff --git a/HOWTO b/HOWTO
index 2788670ddb8df32e74569fe723cca58489fe8beb..e6078c5f1e16e1143d4057b9a1e03bad21954d1f 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -2055,6 +2055,11 @@ I/O engine
                        and 'nrfiles', so that files will be created.
                        This engine is to measure file lookup and meta data access.
 
+               **filedelete**
+                       Simply delete the files by unlink() and do no I/O to them. You need to set 'filesize'
+                       and 'nrfiles', so that the files will be created.
+                       This engine is to measure file delete.
+
                **libpmem**
                        Read and write using mmap I/O to a file on a filesystem
                        mounted with DAX on a persistent memory device through the PMDK
index fce3d0d134cffad9643615988e50c308057ad2a5..ba027b2e1a7110ee58591a874a61119507da1bf6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -51,7 +51,7 @@ SOURCE :=     $(sort $(patsubst $(SRCDIR)/%,%,$(wildcard $(SRCDIR)/crc/*.c)) \
                pshared.c options.c \
                smalloc.c filehash.c profile.c debug.c engines/cpu.c \
                engines/mmap.c engines/sync.c engines/null.c engines/net.c \
-               engines/ftruncate.c engines/filecreate.c engines/filestat.c \
+               engines/ftruncate.c engines/filecreate.c engines/filestat.c engines/filedelete.c \
                server.c client.c iolog.c backend.c libfio.c flow.c cconv.c \
                gettime-thread.c helpers.c json.c idletime.c td_error.c \
                profiles/tiobench.c profiles/act.c io_u_queue.c filelock.c \
diff --git a/engines/filedelete.c b/engines/filedelete.c
new file mode 100644 (file)
index 0000000..64c5863
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * file delete engine
+ *
+ * IO engine that doesn't do any IO, just delete files and track the latency
+ * of the file deletion.
+ */
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "../fio.h"
+
+struct fc_data {
+       enum fio_ddir stat_ddir;
+};
+
+static int delete_file(struct thread_data *td, struct fio_file *f)
+{
+       struct timespec start;
+       int do_lat = !td->o.disable_lat;
+       int ret;
+
+       dprint(FD_FILE, "fd delete %s\n", f->file_name);
+
+       if (f->filetype != FIO_TYPE_FILE) {
+               log_err("fio: only files are supported\n");
+               return 1;
+       }
+       if (!strcmp(f->file_name, "-")) {
+               log_err("fio: can't read/write to stdin/out\n");
+               return 1;
+       }
+
+       if (do_lat)
+               fio_gettime(&start, NULL);
+
+       ret = unlink(f->file_name);
+
+       if (ret == -1) {
+               char buf[FIO_VERROR_SIZE];
+               int e = errno;
+
+               snprintf(buf, sizeof(buf), "delete(%s)", f->file_name);
+               td_verror(td, e, buf);
+               return 1;
+       }
+
+       if (do_lat) {
+               struct fc_data *data = td->io_ops_data;
+               uint64_t nsec;
+
+               nsec = ntime_since_now(&start);
+               add_clat_sample(td, data->stat_ddir, nsec, 0, 0, 0);
+       }
+
+       return 0;
+}
+
+
+static enum fio_q_status queue_io(struct thread_data *td, struct io_u fio_unused *io_u)
+{
+       return FIO_Q_COMPLETED;
+}
+
+static int init(struct thread_data *td)
+{
+       struct fc_data *data;
+
+       data = calloc(1, sizeof(*data));
+
+       if (td_read(td))
+               data->stat_ddir = DDIR_READ;
+       else if (td_write(td))
+               data->stat_ddir = DDIR_WRITE;
+
+       td->io_ops_data = data;
+       return 0;
+}
+
+static int delete_invalidate(struct thread_data *td, struct fio_file *f)
+{
+    /* do nothing because file not opened */
+    return 0;
+}
+
+static void cleanup(struct thread_data *td)
+{
+       struct fc_data *data = td->io_ops_data;
+
+       free(data);
+}
+
+static struct ioengine_ops ioengine = {
+       .name           = "filedelete",
+       .version        = FIO_IOOPS_VERSION,
+       .init           = init,
+       .invalidate     = delete_invalidate,
+       .cleanup        = cleanup,
+       .queue          = queue_io,
+       .get_file_size  = generic_get_file_size,
+       .open_file      = delete_file,
+       .flags          =  FIO_SYNCIO | FIO_FAKEIO |
+                               FIO_NOSTATS | FIO_NOFILEHASH,
+};
+
+static void fio_init fio_filedelete_register(void)
+{
+       register_ioengine(&ioengine);
+}
+
+static void fio_exit fio_filedelete_unregister(void)
+{
+       unregister_ioengine(&ioengine);
+}
diff --git a/examples/filedelete-ioengine.fio b/examples/filedelete-ioengine.fio
new file mode 100644 (file)
index 0000000..3c0028f
--- /dev/null
@@ -0,0 +1,18 @@
+# Example filedelete job
+
+# 'filedelete' engine only do 'unlink(filename)', file will not be open().
+# 'filesize' must be set, then files will be created at setup stage.
+# 'unlink' is better set to 0, since the file is deleted in measurement.
+# the options disabled completion latency output such as 'disable_clat' and 'gtod_reduce' must not set.
+[global]
+ioengine=filedelete
+filesize=4k
+nrfiles=200
+unlink=0
+
+[t0]
+[t1]
+[t2]
+[t3]
+[t4]
+[t5]
diff --git a/fio.1 b/fio.1
index f959e00d01b93db7f3ed9c58d2a9a47f7f690052..c59a80020bf25f0ff035f09bd3c4a5c31168fc1f 100644 (file)
--- a/fio.1
+++ b/fio.1
@@ -1847,6 +1847,11 @@ Simply do stat() and do no I/O to the file. You need to set 'filesize'
 and 'nrfiles', so that files will be created.
 This engine is to measure file lookup and meta data access.
 .TP
+.B filedelete
+Simply delete files by unlink() and do no I/O to the file. You need to set 'filesize'
+and 'nrfiles', so that files will be created.
+This engine is to measure file delete.
+.TP
 .B libpmem
 Read and write using mmap I/O to a file on a filesystem
 mounted with DAX on a persistent memory device through the PMDK