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" | |
14 | ||
15 | struct fc_data { | |
16 | enum fio_ddir stat_ddir; | |
17 | }; | |
18 | ||
19 | static int stat_file(struct thread_data *td, struct fio_file *f) | |
20 | { | |
21 | struct timespec start; | |
22 | int do_lat = !td->o.disable_lat; | |
23 | struct stat statbuf; | |
24 | int ret; | |
25 | ||
26 | dprint(FD_FILE, "fd stat %s\n", f->file_name); | |
27 | ||
28 | if (f->filetype != FIO_TYPE_FILE) { | |
29 | log_err("fio: only files are supported\n"); | |
30 | return 1; | |
31 | } | |
32 | if (!strcmp(f->file_name, "-")) { | |
33 | log_err("fio: can't read/write to stdin/out\n"); | |
34 | return 1; | |
35 | } | |
36 | ||
37 | if (do_lat) | |
38 | fio_gettime(&start, NULL); | |
39 | ||
40 | ret = stat(f->file_name, &statbuf); | |
41 | ||
42 | if (ret == -1) { | |
43 | char buf[FIO_VERROR_SIZE]; | |
44 | int e = errno; | |
45 | ||
46 | snprintf(buf, sizeof(buf), "stat(%s)", f->file_name); | |
47 | td_verror(td, e, buf); | |
48 | return 1; | |
49 | } | |
50 | ||
51 | if (do_lat) { | |
52 | struct fc_data *data = td->io_ops_data; | |
53 | uint64_t nsec; | |
54 | ||
55 | nsec = ntime_since_now(&start); | |
b2a432bf | 56 | add_clat_sample(td, data->stat_ddir, nsec, 0, 0, 0); |
73ccd14e SF |
57 | } |
58 | ||
59 | return 0; | |
60 | } | |
61 | ||
62 | static enum fio_q_status queue_io(struct thread_data *td, struct io_u fio_unused *io_u) | |
63 | { | |
64 | return FIO_Q_COMPLETED; | |
65 | } | |
66 | ||
67 | static int init(struct thread_data *td) | |
68 | { | |
69 | struct fc_data *data; | |
70 | ||
71 | data = calloc(1, sizeof(*data)); | |
72 | ||
73 | if (td_read(td)) | |
74 | data->stat_ddir = DDIR_READ; | |
75 | else if (td_write(td)) | |
76 | data->stat_ddir = DDIR_WRITE; | |
77 | ||
78 | td->io_ops_data = data; | |
79 | return 0; | |
80 | } | |
81 | ||
82 | static void cleanup(struct thread_data *td) | |
83 | { | |
84 | struct fc_data *data = td->io_ops_data; | |
85 | ||
86 | free(data); | |
87 | } | |
88 | ||
89 | static int stat_invalidate(struct thread_data *td, struct fio_file *f) | |
90 | { | |
91 | /* do nothing because file not opened */ | |
92 | return 0; | |
93 | } | |
94 | ||
95 | static struct ioengine_ops ioengine = { | |
96 | .name = "filestat", | |
97 | .version = FIO_IOOPS_VERSION, | |
98 | .init = init, | |
99 | .cleanup = cleanup, | |
100 | .queue = queue_io, | |
101 | .invalidate = stat_invalidate, | |
102 | .get_file_size = generic_get_file_size, | |
103 | .open_file = stat_file, | |
104 | .flags = FIO_SYNCIO | FIO_FAKEIO | | |
105 | FIO_NOSTATS | FIO_NOFILEHASH, | |
106 | }; | |
107 | ||
108 | static void fio_init fio_filestat_register(void) | |
109 | { | |
110 | register_ioengine(&ioengine); | |
111 | } | |
112 | ||
113 | static void fio_exit fio_filestat_unregister(void) | |
114 | { | |
115 | unregister_ioengine(&ioengine); | |
116 | } |