1 #define _XOPEN_SOURCE 500 /* pwrite */ 2 #include <unistd.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <sys/types.h> 6 #include <sys/stat.h> 7 #include <fcntl.h> 8 #include <libaio.h> 9 #include <errno.h> 10 #include <time.h> 11 #include <sys/types.h> 12 #include <sys/wait.h> 13 14 /* 15 * DIO invalidates the read cache after it writes. At one point it tried to 16 * return EIO if this failed. When called from AIO, though, this EIO return 17 * would clobber EIOCBQUEUED and cause fs/aio.c and fs/direct-io.c to complete 18 * an iocb twice. This typically references freed memory from an interrupt 19 * handler and oopses. 20 * 21 * This test hits the race after at most two minutes on a single spindle. It 22 * spins performing large dio writes. It also spins racing buffered writes. 23 * It assumes it's on ext3 using ordered writes. The ordered write bhs can be 24 * pinned by jbd as a transaction commits. If invalidate_inode_pages2_range() 25 * hits pages backed by those buffers ->releasepage will fail and it'll try to 26 * return -EIO. 27 */ 28 #ifndef O_DIRECT 29 #define O_DIRECT 040000 /* direct disk access hint */ 30 #endif 31 32 #define GINORMOUS (32 * 1024 * 1024) 33 34 35 /* This test never survived to 180 seconds on a single spindle */ 36 #define SECONDS 200 37 38 static unsigned char buf[GINORMOUS] __attribute((aligned (512))); 39 40 #define fail(fmt , args...) do {\ 41 printf(fmt , ##args); \ 42 exit(1); \ 43 } while (0) 44 45 void spin_dio(int fd) 46 { 47 io_context_t ctx; 48 struct iocb iocb; 49 struct iocb *iocbs[1] = { &iocb }; 50 struct io_event event; 51 int ret; 52 53 io_prep_pwrite(&iocb, fd, buf, GINORMOUS, 0); 54 55 ret = io_queue_init(1, &ctx); 56 if (ret) 57 fail("io_queue_init returned %d", ret); 58 59 while (1) { 60 ret = io_submit(ctx, 1, iocbs); 61 if (ret != 1) 62 fail("io_submit returned %d instead of 1", ret); 63 64 ret = io_getevents(ctx, 1, 1, &event, NULL); 65 if (ret != 1) 66 fail("io_getevents returned %d instead of 1", ret); 67 68 if (event.res == -EIO) { 69 printf("invalidation returned -EIO, OK\n"); 70 exit(0); 71 } 72 73 if (event.res != GINORMOUS) 74 fail("event res %ld\n", event.res); 75 } 76 } 77 78 void spin_buffered(int fd) 79 { 80 int ret; 81 82 while (1) { 83 ret = pwrite(fd, buf, GINORMOUS, 0); 84 if (ret != GINORMOUS) 85 fail("buffered write returned %d", ret); 86 } 87 } 88 89 static void alarm_handler(int signum) 90 { 91 } 92 93 int main(int argc, char **argv) 94 { 95 pid_t buffered_pid; 96 pid_t dio_pid; 97 pid_t pid; 98 int fd; 99 int fd2; 100 int status; 101 102 if (argc != 2) 103 fail("only arg should be file name"); 104 105 fd = open(argv[1], O_DIRECT|O_CREAT|O_RDWR, 0644); 106 if (fd < 0) 107 fail("open dio failed: %d\n", errno); 108 109 fd2 = open(argv[1], O_RDWR, 0644); 110 if (fd < 0) 111 fail("open failed: %d\n", errno); 112 113 buffered_pid = fork(); 114 if (buffered_pid < 0) 115 fail("fork failed: %d\n", errno); 116 117 if (buffered_pid == 0) { 118 spin_buffered(fd2); 119 exit(0); 120 } 121 122 dio_pid = fork(); 123 if (dio_pid < 0) { 124 kill(buffered_pid, SIGKILL); 125 fail("fork failed: %d\n", errno); 126 } 127 128 if (dio_pid == 0) { 129 spin_dio(fd); 130 exit(0); 131 } 132 133 signal(SIGALRM, alarm_handler); 134 alarm(SECONDS); 135 136 pid = wait(&status); 137 if (pid < 0 && errno == EINTR) { 138 /* if we timed out then we're done */ 139 kill(buffered_pid, SIGKILL); 140 kill(dio_pid, SIGKILL); 141 printf("ran for %d seconds without error, passing\n", SECONDS); 142 exit(0); 143 } 144 145 if (pid == dio_pid) 146 kill(buffered_pid, SIGKILL); 147 else 148 kill(dio_pid, SIGKILL); 149 150 /* 151 * pass on the child's pass/fail return code or fail if the child 152 * didn't exit cleanly. 153 */ 154 exit(WIFEXITED(status) ? WEXITSTATUS(status) : 1); 155 } 156