• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *   Copyright (c) International Business Machines Corp., 2001-2004
3  *
4  *   This program is free software;  you can redistribute it and/or modify
5  *   it under the terms of the GNU General Public License as published by
6  *   the Free Software Foundation; either version 2 of the License, or
7  *   (at your option) any later version.
8  *
9  *   This program is distributed in the hope that it will be useful,
10  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12  *   the GNU General Public License for more details.
13  *
14  *   You should have received a copy of the GNU General Public License
15  *   along with this program;  if not, write to the Free Software
16  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #define FILE_OFFSET_BITS 64
20 
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <fcntl.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <assert.h>
27 #include <inttypes.h>
28 #include <assert.h>
29 
30 #include "ffsb.h"
31 #include "fh.h"
32 
33 #include "config.h"
34 
35 /* !!! ugly */
36 #ifndef HAVE_OPEN64
37 #define open64 open
38 #endif
39 
40 #ifndef HAVE_FSEEKO64
41 #define lseek64 lseek
42 #endif
43 
44 /* All these functions read the global mainconfig->bufferedio variable
45  * to determine if they are to do buffered i/o or normal.
46  *
47  * ha, well, they're supposed to anyway...!!! TODO -SR 2006/05/14
48  */
49 
do_stats(struct timeval * start,struct timeval * end,ffsb_thread_t * ft,ffsb_fs_t * fs,syscall_t sys)50 static void do_stats(struct timeval *start, struct timeval *end,
51 		     ffsb_thread_t * ft, ffsb_fs_t * fs, syscall_t sys)
52 {
53 	struct timeval diff;
54 	uint32_t value = 0;
55 
56 	if (!ft && !fs)
57 		return;
58 
59 	timersub(end, start, &diff);
60 
61 	value = 1000000 * diff.tv_sec + diff.tv_usec;
62 
63 	if (ft && ft_needs_stats(ft, sys))
64 		ft_add_stat(ft, sys, value);
65 	if (fs && fs_needs_stats(fs, sys))
66 		fs_add_stat(fs, sys, value);
67 }
68 
fhopenhelper(char * filename,char * bufflags,int flags,ffsb_thread_t * ft,ffsb_fs_t * fs)69 static int fhopenhelper(char *filename, char *bufflags, int flags,
70 			ffsb_thread_t * ft, ffsb_fs_t * fs)
71 {
72 	int fd = 0;
73 	struct timeval start, end;
74 	int need_stats = ft_needs_stats(ft, SYS_OPEN) ||
75 	    fs_needs_stats(fs, SYS_OPEN);
76 
77 	flags |= O_LARGEFILE;
78 
79 	if (need_stats)
80 		gettimeofday(&start, NULL);
81 
82 	fd = open64(filename, flags, S_IRWXU);
83 	if (fd < 0) {
84 		perror(filename);
85 		exit(0);
86 	}
87 
88 	if (need_stats) {
89 		gettimeofday(&end, NULL);
90 		do_stats(&start, &end, ft, fs, SYS_OPEN);
91 	}
92 
93 	return fd;
94 }
95 
fhopenread(char * filename,ffsb_thread_t * ft,ffsb_fs_t * fs)96 int fhopenread(char *filename, ffsb_thread_t * ft, ffsb_fs_t * fs)
97 {
98 	int flags = O_RDONLY;
99 	int directio = fs_get_directio(fs);
100 
101 	if (directio)
102 		flags |= O_DIRECT;
103 	return fhopenhelper(filename, "r", flags, ft, fs);
104 }
105 
fhopenappend(char * filename,ffsb_thread_t * ft,ffsb_fs_t * fs)106 int fhopenappend(char *filename, ffsb_thread_t * ft, ffsb_fs_t * fs)
107 {
108 	int flags = O_APPEND | O_WRONLY;
109 	int directio = fs_get_directio(fs);
110 
111 	if (directio)
112 		flags |= O_DIRECT;
113 	return fhopenhelper(filename, "a", flags, ft, fs);
114 }
115 
fhopenwrite(char * filename,ffsb_thread_t * ft,ffsb_fs_t * fs)116 int fhopenwrite(char *filename, ffsb_thread_t * ft, ffsb_fs_t * fs)
117 {
118 	int flags = O_WRONLY;
119 	int directio = fs_get_directio(fs);
120 
121 	if (directio)
122 		flags |= O_DIRECT;
123 	return fhopenhelper(filename, "w", flags, ft, fs);
124 }
125 
fhopencreate(char * filename,ffsb_thread_t * ft,ffsb_fs_t * fs)126 int fhopencreate(char *filename, ffsb_thread_t * ft, ffsb_fs_t * fs)
127 {
128 	int flags = O_CREAT | O_RDWR | O_TRUNC;
129 	int directio = fs_get_directio(fs);
130 
131 	if (directio)
132 		flags |= O_DIRECT;
133 	return fhopenhelper(filename, "rw", flags, ft, fs);
134 }
135 
fhread(int fd,void * buf,uint64_t size,ffsb_thread_t * ft,ffsb_fs_t * fs)136 void fhread(int fd, void *buf, uint64_t size, ffsb_thread_t * ft,
137 	    ffsb_fs_t * fs)
138 {
139 	ssize_t realsize;
140 	struct timeval start, end;
141 	int need_stats = ft_needs_stats(ft, SYS_READ) ||
142 	    fs_needs_stats(fs, SYS_READ);
143 
144 	assert(size <= SIZE_MAX);
145 	if (need_stats)
146 		gettimeofday(&start, NULL);
147 	realsize = read(fd, buf, size);
148 
149 	if (need_stats) {
150 		gettimeofday(&end, NULL);
151 		do_stats(&start, &end, ft, fs, SYS_READ);
152 	}
153 
154 	if (realsize != size) {
155 		printf("Read %lld instead of %llu bytes.\n",
156 		       (unsigned long long)realsize, (unsigned long long)size);
157 		perror("read");
158 		exit(1);
159 	}
160 }
161 
fhwrite(int fd,void * buf,uint32_t size,ffsb_thread_t * ft,ffsb_fs_t * fs)162 void fhwrite(int fd, void *buf, uint32_t size, ffsb_thread_t * ft,
163 	     ffsb_fs_t * fs)
164 {
165 	ssize_t realsize;
166 	struct timeval start, end;
167 	int need_stats = ft_needs_stats(ft, SYS_WRITE) ||
168 	    fs_needs_stats(fs, SYS_WRITE);
169 
170 	assert(size <= SIZE_MAX);
171 	if (need_stats)
172 		gettimeofday(&start, NULL);
173 
174 	realsize = write(fd, buf, size);
175 
176 	if (need_stats) {
177 		gettimeofday(&end, NULL);
178 		do_stats(&start, &end, ft, fs, SYS_WRITE);
179 	}
180 
181 	if (realsize != size) {
182 		printf("Wrote %d instead of %d bytes.\n"
183 		       "Probably out of disk space\n", realsize, size);
184 		perror("write");
185 		exit(1);
186 	}
187 }
188 
fhseek(int fd,uint64_t offset,int whence,ffsb_thread_t * ft,ffsb_fs_t * fs)189 void fhseek(int fd, uint64_t offset, int whence, ffsb_thread_t * ft,
190 	    ffsb_fs_t * fs)
191 {
192 	uint64_t res;
193 	struct timeval start, end;
194 	int need_stats = ft_needs_stats(ft, SYS_LSEEK) ||
195 	    fs_needs_stats(fs, SYS_LSEEK);
196 
197 	if ((whence == SEEK_CUR) && (offset == 0))
198 		return;
199 
200 	if (need_stats)
201 		gettimeofday(&start, NULL);
202 
203 	res = lseek64(fd, offset, whence);
204 
205 	if (need_stats) {
206 		gettimeofday(&end, NULL);
207 		do_stats(&start, &end, ft, fs, SYS_LSEEK);
208 	}
209 	if ((whence == SEEK_SET) && (res != offset))
210 		perror("seek");
211 
212 	if (res == -1) {
213 		if (whence == SEEK_SET)
214 			fprintf(stderr, "tried to seek to %lld\n", offset);
215 		else
216 			fprintf(stderr, "tried to seek from current "
217 				"position to %lld\n", offset);
218 
219 		perror("seek");
220 		exit(1);
221 	}
222 }
223 
fhclose(int fd,ffsb_thread_t * ft,ffsb_fs_t * fs)224 void fhclose(int fd, ffsb_thread_t * ft, ffsb_fs_t * fs)
225 {
226 	struct timeval start, end;
227 	int need_stats = ft_needs_stats(ft, SYS_CLOSE) ||
228 	    fs_needs_stats(fs, SYS_CLOSE);
229 
230 	if (need_stats)
231 		gettimeofday(&start, NULL);
232 
233 	close(fd);
234 
235 	if (need_stats) {
236 		gettimeofday(&end, NULL);
237 		do_stats(&start, &end, ft, fs, SYS_CLOSE);
238 	}
239 }
240 
fhstat(char * name,ffsb_thread_t * ft,ffsb_fs_t * fs)241 void fhstat(char *name, ffsb_thread_t * ft, ffsb_fs_t * fs)
242 {
243 	struct timeval start, end;
244 	struct stat tmp_stat;
245 
246 	int need_stats = ft_needs_stats(ft, SYS_STAT) ||
247 	    fs_needs_stats(fs, SYS_CLOSE);
248 
249 	if (need_stats)
250 		gettimeofday(&start, NULL);
251 
252 	if (stat(name, &tmp_stat)) {
253 		fprintf(stderr, "stat call failed for file %s\n", name);
254 		exit(1);
255 	}
256 
257 	if (need_stats) {
258 		gettimeofday(&end, NULL);
259 		do_stats(&start, &end, ft, fs, SYS_STAT);
260 	}
261 }
262 
writefile_helper(int fd,uint64_t size,uint32_t blocksize,char * buf,struct ffsb_thread * ft,struct ffsb_fs * fs)263 int writefile_helper(int fd, uint64_t size, uint32_t blocksize, char *buf,
264 		     struct ffsb_thread *ft, struct ffsb_fs *fs)
265 {
266 	uint64_t iterations, a;
267 	uint64_t last;
268 
269 	iterations = size / blocksize;
270 	last = size % blocksize;
271 
272 	for (a = 0; a < iterations; a++)
273 		fhwrite(fd, buf, blocksize, ft, fs);
274 
275 	if (last) {
276 		a++;
277 		fhwrite(fd, buf, last, ft, fs);
278 	}
279 	return a;
280 }
281