engines/filestat: add "lstat" option to use lstat(2)
authorTomohiro Kusumi <kusumi.tomohiro@gmail.com>
Thu, 23 Jan 2020 16:36:32 +0000 (01:36 +0900)
committerTomohiro Kusumi <kusumi.tomohiro@gmail.com>
Thu, 23 Jan 2020 17:05:51 +0000 (02:05 +0900)
Use stat(2) by default, but lstat(2) if "lstat" bool option specified.

Signed-off-by: Tomohiro Kusumi <kusumi.tomohiro@gmail.com>
HOWTO
engines/filestat.c
fio.1
optgroup.h

diff --git a/HOWTO b/HOWTO
index 0a36616..f19f922 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -2261,6 +2261,10 @@ with the caveat that when used on the command line, they must come after the
        multiple paths exist between the client and the server or in certain loopback
        configurations.
 
+.. option:: lstat=bool : [filestat]
+
+       Use lstat(2) to measure lookup/getattr performance. Default is 0.
+
 .. option:: readfua=bool : [sg]
 
        With readfua option set to 1, read operations include
index 7952593..6c87c4c 100644 (file)
 #include <sys/stat.h>
 #include <unistd.h>
 #include "../fio.h"
+#include "../optgroup.h"
 
 struct fc_data {
        enum fio_ddir stat_ddir;
 };
 
+struct filestat_options {
+       void *pad;
+       unsigned int lstat;
+};
+
+static struct fio_option options[] = {
+       {
+               .name   = "lstat",
+               .lname  = "lstat",
+               .type   = FIO_OPT_BOOL,
+               .off1   = offsetof(struct filestat_options, lstat),
+               .help   = "Use lstat(2) to measure lookup/getattr performance",
+               .def    = "0",
+               .category = FIO_OPT_C_ENGINE,
+               .group  = FIO_OPT_G_FILESTAT,
+       },
+       {
+               .name   = NULL,
+       },
+};
+
 static int stat_file(struct thread_data *td, struct fio_file *f)
 {
+       struct filestat_options *o = td->eo;
        struct timespec start;
        int do_lat = !td->o.disable_lat;
        struct stat statbuf;
@@ -37,13 +60,17 @@ static int stat_file(struct thread_data *td, struct fio_file *f)
        if (do_lat)
                fio_gettime(&start, NULL);
 
-       ret = stat(f->file_name, &statbuf);
+       if (o->lstat)
+               ret = lstat(f->file_name, &statbuf);
+       else
+               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);
+               snprintf(buf, sizeof(buf), "%sstat(%s)",
+                       o->lstat ? "l" : "", f->file_name);
                td_verror(td, e, buf);
                return 1;
        }
@@ -103,6 +130,8 @@ static struct ioengine_ops ioengine = {
        .open_file      = stat_file,
        .flags          =  FIO_SYNCIO | FIO_FAKEIO |
                                FIO_NOSTATS | FIO_NOFILEHASH,
+       .options        = options,
+       .option_struct_size = sizeof(struct filestat_options),
 };
 
 static void fio_init fio_filestat_register(void)
diff --git a/fio.1 b/fio.1
index 05896e6..a58632b 100644 (file)
--- a/fio.1
+++ b/fio.1
@@ -2032,6 +2032,9 @@ on the client site it will be used in the rdma_resolve_add()
 function. This can be useful when multiple paths exist between the
 client and the server or in certain loopback configurations.
 .TP
+.BI (filestat)lstat \fR=\fPbool
+Use \fBlstat\fR\|(2) to measure lookup/getattr performance. Default: 0.
+.TP
 .BI (sg)readfua \fR=\fPbool
 With readfua option set to 1, read operations include the force
 unit access (fua) flag. Default: 0.
index 55ef593..5789afd 100644 (file)
@@ -65,6 +65,7 @@ enum opt_category_group {
        __FIO_OPT_G_ISCSI,
        __FIO_OPT_G_NBD,
        __FIO_OPT_G_IOURING,
+       __FIO_OPT_G_FILESTAT,
        __FIO_OPT_G_NR,
 
        FIO_OPT_G_RATE          = (1ULL << __FIO_OPT_G_RATE),
@@ -106,6 +107,7 @@ enum opt_category_group {
        FIO_OPT_G_ISCSI         = (1ULL << __FIO_OPT_G_ISCSI),
        FIO_OPT_G_NBD           = (1ULL << __FIO_OPT_G_NBD),
        FIO_OPT_G_IOURING       = (1ULL << __FIO_OPT_G_IOURING),
+       FIO_OPT_G_FILESTAT      = (1ULL << __FIO_OPT_G_FILESTAT),
 };
 
 extern const struct opt_group *opt_group_from_mask(uint64_t *mask);