Home | History | Annotate | Download | only in ffsb-6.0-rc2
      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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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