1 /* Test 70 - regression test for m_out vfs race condition. 2 * 3 * Regression test for vfs overwriting m_out fields by competing threads. 4 * lseek() uses one of these fields too so this test performs concurrent 5 * lseek()s to trigger this situation. 6 * 7 * The program consists of 2 processes, each seeking to different ranges in 8 * a test file. The bug would return the wrong value in one of the messaeg 9 * fields so the lseek() return value would be wrong sometimes. 10 * 11 * The first instance seeks from 0 to SEEKWINDOW, the other instance seeks 12 * from SEEKWINDOW to SEEKWINDOW+SEEKWINDOW. 13 */ 14 15 #include <time.h> 16 #include <sys/types.h> 17 #include <sys/wait.h> 18 #include <errno.h> 19 #include <fcntl.h> 20 #include <stdlib.h> 21 #include <unistd.h> 22 #include <stdio.h> 23 24 #include "common.h" 25 26 #define SEEKWINDOW 1000 27 28 static int 29 doseeks(int seekbase) 30 { 31 char template[30] = "tempfile.XXXXXXXX"; 32 int iteration, fd = mkstemp(template); 33 int limit = seekbase + SEEKWINDOW; 34 35 /* make a temporary file, unlink it so it's always gone 36 * afterwards, and make it the size we need. 37 */ 38 if(fd < 0) { perror("mkstemp"); e(2); return 1; } 39 if(unlink(template) < 0) { perror("unlink"); e(3); return 1; } 40 if(ftruncate(fd, limit) < 0) { perror("ftruncate"); e(4); return 1; } 41 42 /* try lseek() lots of times with different arguments and make 43 * sure we get the right return value back, while this happens 44 * in a concurrent process too. 45 */ 46 #define ITERATIONS 5000 47 for(iteration = 0; iteration < ITERATIONS; iteration++) { 48 int o; 49 for(o = seekbase; o < limit; o++) { 50 int r; 51 if((r=lseek(fd, o, SEEK_SET)) != o) { 52 if(r < 0) perror("lseek"); 53 fprintf(stderr, "%d/%d %d != %d\n", 54 iteration, ITERATIONS, r, o); 55 e(5); 56 return 1; 57 } 58 } 59 } 60 61 return 0; 62 } 63 64 int 65 main(void) 66 { 67 start(70); 68 pid_t f; 69 int result; 70 71 if((f=fork()) < 0) { e(1); quit(); } 72 73 if(f == 0) { exit(doseeks(0)); } 74 75 if(doseeks(SEEKWINDOW)) { e(10); } 76 77 if (waitpid(f, &result, 0) == -1) e(11); 78 if (WEXITSTATUS(result) != 0) e(12); 79 80 quit(); 81 82 return(-1); /* impossible */ 83 } 84 85