Commit | Line | Data |
---|---|---|
73ccd14e SF |
1 | /* |
2 | * filestat engine | |
3 | * | |
4 | * IO engine that doesn't do any IO, just stat files and tracks the latency | |
5 | * of the file stat. | |
6 | */ | |
7 | #include <stdio.h> | |
8 | #include <fcntl.h> | |
9 | #include <errno.h> | |
10 | #include <sys/types.h> | |
11 | #include <sys/stat.h> | |
12 | #include <unistd.h> | |
13 | #include "../fio.h" | |
c446eff0 | 14 | #include "../optgroup.h" |
73ccd14e SF |
15 | |
16 | struct fc_data { | |
17 | enum fio_ddir stat_ddir; | |
18 | }; | |
19 | ||
c446eff0 TK |
20 | struct filestat_options { |
21 | void *pad; | |
22 | unsigned int lstat; | |
23 | }; | |
24 | ||
25 | static struct fio_option options[] = { | |
26 | { | |
27 | .name = "lstat", | |
28 | .lname = "lstat", | |
29 | .type = FIO_OPT_BOOL, | |
30 | .off1 = offsetof(struct filestat_options, lstat), | |
31 | .help = "Use lstat(2) to measure lookup/getattr performance", | |
32 | .def = "0", | |
33 | .category = FIO_OPT_C_ENGINE, | |
34 | .group = FIO_OPT_G_FILESTAT, | |
35 | }, | |
36 | { | |
37 | .name = NULL, | |
38 | }, | |
39 | }; | |
40 | ||
73ccd14e SF |
41 | static int stat_file(struct thread_data *td, struct fio_file *f) |
42 | { | |
c446eff0 | 43 | struct filestat_options *o = td->eo; |
73ccd14e SF |
44 | struct timespec start; |
45 | int do_lat = !td->o.disable_lat; | |
46 | struct stat statbuf; | |
47 | int ret; | |
48 | ||
49 | dprint(FD_FILE, "fd stat %s\n", f->file_name); | |
50 | ||
51 | if (f->filetype != FIO_TYPE_FILE) { | |
52 | log_err("fio: only files are supported\n"); | |
53 | return 1; | |
54 | } | |
55 | if (!strcmp(f->file_name, "-")) { | |
56 | log_err("fio: can't read/write to stdin/out\n"); | |
57 | return 1; | |
58 | } | |
59 | ||
60 | if (do_lat) | |
61 | fio_gettime(&start, NULL); | |
62 | ||
c446eff0 TK |
63 | if (o->lstat) |
64 | ret = lstat(f->file_name, &statbuf); | |
65 | else | |
66 | ret = stat(f->file_name, &statbuf); | |
73ccd14e SF |
67 | |
68 | if (ret == -1) { | |
69 | char buf[FIO_VERROR_SIZE]; | |
70 | int e = errno; | |
71 | ||
c446eff0 TK |
72 | snprintf(buf, sizeof(buf), "%sstat(%s)", |
73 | o->lstat ? "l" : "", f->file_name); | |
73ccd14e SF |
74 | td_verror(td, e, buf); |
75 | return 1; | |
76 | } | |
77 | ||
78 | if (do_lat) { | |
79 | struct fc_data *data = td->io_ops_data; | |
80 | uint64_t nsec; | |
81 | ||
82 | nsec = ntime_since_now(&start); | |
b2a432bf | 83 | add_clat_sample(td, data->stat_ddir, nsec, 0, 0, 0); |
73ccd14e SF |
84 | } |
85 | ||
86 | return 0; | |
87 | } | |
88 | ||
89 | static enum fio_q_status queue_io(struct thread_data *td, struct io_u fio_unused *io_u) | |
90 | { | |
91 | return FIO_Q_COMPLETED; | |
92 | } | |
93 | ||
94 | static int init(struct thread_data *td) | |
95 | { | |
96 | struct fc_data *data; | |
97 | ||
98 | data = calloc(1, sizeof(*data)); | |
99 | ||
100 | if (td_read(td)) | |
101 | data->stat_ddir = DDIR_READ; | |
102 | else if (td_write(td)) | |
103 | data->stat_ddir = DDIR_WRITE; | |
104 | ||
105 | td->io_ops_data = data; | |
106 | return 0; | |
107 | } | |
108 | ||
109 | static void cleanup(struct thread_data *td) | |
110 | { | |
111 | struct fc_data *data = td->io_ops_data; | |
112 | ||
113 | free(data); | |
114 | } | |
115 | ||
116 | static int stat_invalidate(struct thread_data *td, struct fio_file *f) | |
117 | { | |
118 | /* do nothing because file not opened */ | |
119 | return 0; | |
120 | } | |
121 | ||
122 | static struct ioengine_ops ioengine = { | |
123 | .name = "filestat", | |
124 | .version = FIO_IOOPS_VERSION, | |
125 | .init = init, | |
126 | .cleanup = cleanup, | |
127 | .queue = queue_io, | |
128 | .invalidate = stat_invalidate, | |
129 | .get_file_size = generic_get_file_size, | |
130 | .open_file = stat_file, | |
131 | .flags = FIO_SYNCIO | FIO_FAKEIO | | |
132 | FIO_NOSTATS | FIO_NOFILEHASH, | |
c446eff0 TK |
133 | .options = options, |
134 | .option_struct_size = sizeof(struct filestat_options), | |
73ccd14e SF |
135 | }; |
136 | ||
137 | static void fio_init fio_filestat_register(void) | |
138 | { | |
139 | register_ioengine(&ioengine); | |
140 | } | |
141 | ||
142 | static void fio_exit fio_filestat_unregister(void) | |
143 | { | |
144 | unregister_ioengine(&ioengine); | |
145 | } |