engines: add engine for file stat
authorSu, Friendy <Friendy.Su@sony.com>
Wed, 22 Jan 2020 15:31:25 +0000 (08:31 -0700)
committerJens Axboe <axboe@kernel.dk>
Wed, 22 Jan 2020 15:31:25 +0000 (08:31 -0700)
This engine is to measure performance of accessing file's meta data.
This is for the actual access pattern which does not do real IO, but
just look up the file and get file's attribute.

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

diff --git a/HOWTO b/HOWTO
index 41d32c04dc638b12de1dc20e9444ed4462c81051..74318954b1fb73bc8d32a10c9c851da07def8466 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -1996,6 +1996,11 @@ I/O engine
                        set  `filesize` so that all the accounting still occurs, but no
                        actual I/O will be done other than creating the file.
 
+               **filestat**
+                       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.
+
                **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 3c5e0f5b7b4cfb348b6fc5fa82ff28186d2ca4ea..027b62bcbb6f0bf573a15ddf6488e20cb7818567 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -45,7 +45,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/ftruncate.c engines/filecreate.c engines/filestat.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/filestat.c b/engines/filestat.c
new file mode 100644 (file)
index 0000000..9a394fe
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * filestat engine
+ *
+ * IO engine that doesn't do any IO, just stat files and tracks the latency
+ * of the file stat.
+ */
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include "../fio.h"
+
+struct fc_data {
+       enum fio_ddir stat_ddir;
+};
+
+static int stat_file(struct thread_data *td, struct fio_file *f)
+{
+       struct timespec start;
+       int do_lat = !td->o.disable_lat;
+       struct stat statbuf;
+       int ret;
+
+       dprint(FD_FILE, "fd stat %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 = stat(f->file_name, &statbuf);
+
+       if (ret == -1) {
+               char buf[FIO_VERROR_SIZE];
+               int e = errno;
+
+               snprintf(buf, sizeof(buf), "stat(%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);
+       }
+
+       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 void cleanup(struct thread_data *td)
+{
+       struct fc_data *data = td->io_ops_data;
+
+       free(data);
+}
+
+static int stat_invalidate(struct thread_data *td, struct fio_file *f)
+{
+       /* do nothing because file not opened */
+       return 0;
+}
+
+static struct ioengine_ops ioengine = {
+       .name           = "filestat",
+       .version        = FIO_IOOPS_VERSION,
+       .init           = init,
+       .cleanup        = cleanup,
+       .queue          = queue_io,
+       .invalidate     = stat_invalidate,
+       .get_file_size  = generic_get_file_size,
+       .open_file      = stat_file,
+       .flags          =  FIO_SYNCIO | FIO_FAKEIO |
+                               FIO_NOSTATS | FIO_NOFILEHASH,
+};
+
+static void fio_init fio_filestat_register(void)
+{
+       register_ioengine(&ioengine);
+}
+
+static void fio_exit fio_filestat_unregister(void)
+{
+       unregister_ioengine(&ioengine);
+}
diff --git a/examples/filestat-ioengine.fio b/examples/filestat-ioengine.fio
new file mode 100644 (file)
index 0000000..932fced
--- /dev/null
@@ -0,0 +1,19 @@
+# Example filestat job
+
+# 'filestat' engine only do 'stat(filename)', file will not be open().
+# 'filesize' must be set, then files will be created at setup stage.
+
+[global]
+ioengine=filestat
+numjobs=1
+filesize=4k
+nrfiles=200
+thread
+
+[t0]
+[t1]
+[t2]
+[t3]
+[t4]
+[t5]
+
diff --git a/fio.1 b/fio.1
index cf5dd853dda1b2f0cac3d7ab8776bf5b2ed7cf00..6283fc1d92931fd860915c92735d0f9136c3ac7e 100644 (file)
--- a/fio.1
+++ b/fio.1
@@ -1760,6 +1760,11 @@ Simply create the files and do no I/O to them.  You still need to set
 \fBfilesize\fR so that all the accounting still occurs, but no actual I/O will be
 done other than creating the file.
 .TP
+.B filestat
+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 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