1 2 /* 3 * Copyright (c) 2004 Daniel McNeil <daniel (at) osdl.org> 4 * 2004 Open Source Development Lab 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 * 19 * Module: .c 20 */ 21 22 /* 23 * Change History: 24 * 25 * 2/2004 Marty Ridgeway (mridge (at) us.ibm.com) Changes to adapt to LTP 26 * 27 */ 28 /* 29 * dio_append - append zeroed data to a file using O_DIRECT while 30 * a 2nd process is doing buffered reads and check if the buffer 31 * reads always see zero. 32 */ 33 #define _GNU_SOURCE 34 35 #include <stdlib.h> 36 #include <sys/types.h> 37 #include <signal.h> 38 #include <errno.h> 39 #include <fcntl.h> 40 #include <stdio.h> 41 #include <unistd.h> 42 #include <memory.h> 43 #include <limits.h> 44 45 #include "test.h" 46 #define NUM_CHILDREN 8 47 48 #include "common_checkzero.h" 49 50 int read_eof(char *filename) 51 { 52 int fd; 53 int i; 54 int r; 55 char buf[4096]; 56 57 while ((fd = open(filename, O_RDONLY)) < 0) { 58 sleep(1); /* wait for file to be created */ 59 } 60 61 for (i = 0; i < 1000000; i++) { 62 off_t offset; 63 char *bufoff; 64 65 offset = lseek(fd, SEEK_END, 0); 66 r = read(fd, buf, 4096); 67 if (r > 0) { 68 if ((bufoff = check_zero(buf, r))) { 69 fprintf(stderr, "non-zero read at offset %p\n", 70 offset + bufoff); 71 exit(1); 72 } 73 } 74 } 75 return 0; 76 } 77 78 void dio_append(char *filename) 79 { 80 int fd; 81 void *bufptr; 82 int i; 83 int w; 84 85 fd = open(filename, O_DIRECT | O_WRONLY | O_CREAT, 0666); 86 87 if (fd < 0) { 88 perror("cannot create file"); 89 return; 90 } 91 92 TEST(posix_memalign(&bufptr, 4096, 64 * 1024)); 93 if (TEST_RETURN) { 94 tst_resm(TBROK | TRERRNO, "cannot malloc aligned memory"); 95 close(fd); 96 return; 97 } 98 99 memset(bufptr, 0, 64 * 1024); 100 for (i = 0; i < 1000; i++) { 101 if ((w = write(fd, bufptr, 64 * 1024)) != 64 * 1024) { 102 fprintf(stderr, "write %d returned %d\n", i, w); 103 } 104 } 105 } 106 107 int main(int argc, char **argv) 108 { 109 char filename[PATH_MAX]; 110 int pid[NUM_CHILDREN]; 111 int num_children = 1; 112 int i; 113 114 snprintf(filename, sizeof(filename), "%s/aiodio/file", 115 getenv("TMP") ? getenv("TMP") : "/tmp"); 116 117 printf("Begin dio_append test...\n"); 118 119 for (i = 0; i < num_children; i++) { 120 if ((pid[i] = fork()) == 0) { 121 /* child */ 122 return read_eof(filename); 123 } else if (pid[i] < 0) { 124 /* error */ 125 perror("fork error"); 126 break; 127 } else { 128 /* Parent */ 129 continue; 130 } 131 } 132 133 /* 134 * Parent appends to end of file using direct i/o 135 */ 136 137 dio_append(filename); 138 139 for (i = 0; i < num_children; i++) { 140 kill(pid[i], SIGTERM); 141 } 142 return 0; 143 } 144