1 module during.tests.fsync; 2 3 import during; 4 import during.tests.base; 5 6 import core.stdc.stdlib; 7 import core.sys.linux.errno; 8 import core.sys.linux.fcntl; 9 import core.sys.posix.sys.uio : iovec; 10 import core.sys.posix.unistd; 11 12 @("single") 13 unittest 14 { 15 Uring io; 16 auto res = io.setup(); 17 assert(res >= 0, "Error initializing IO"); 18 19 auto fname = getTestFileName!"fsync_single"; 20 auto fd = openFile(fname, O_CREAT | O_WRONLY); 21 scope (exit) unlink(&fname[0]); 22 23 auto ret = io 24 .putWith!((ref SubmissionEntry e, int fd) => e.prepFsync(fd))(fd) 25 .submit(1); 26 assert(ret == 1); 27 assert(io.length == 1); 28 assert(io.front.res == 0); 29 io.popFront(); 30 31 close(fd); 32 } 33 34 @("barier") 35 unittest 36 { 37 enum NUM_WRITES = 4; 38 Uring io; 39 auto res = io.setup(); 40 assert(res >= 0, "Error initializing IO"); 41 42 auto fname = getTestFileName!"fsync_barier"; 43 auto fd = openFile(fname, O_CREAT | O_WRONLY); 44 scope (exit) unlink(&fname[0]); 45 46 iovec[4] iovecs; 47 foreach (i; 0..NUM_WRITES) 48 { 49 iovecs[i].iov_base = malloc(4096); 50 iovecs[i].iov_len = 4096; 51 } 52 53 int off; 54 foreach (i; 0..NUM_WRITES) 55 { 56 io.putWith!((ref SubmissionEntry e, int fd, ref iovec v, int off) 57 { 58 e.prepWritev(fd, v, off); 59 e.user_data = 1; 60 })(fd, iovecs[i], off); 61 off += 4096; 62 } 63 64 io.putWith!((ref SubmissionEntry e, int fd) 65 { 66 e.prepFsync(fd);//, FsyncFlags.DATASYNC); 67 e.user_data = 2; 68 // TODO: Works with IO_LINK but not without it: See: https://github.com/axboe/liburing/issues/33 69 e.flags = cast(SubmissionEntryFlags)(SubmissionEntryFlags.IO_DRAIN | SubmissionEntryFlags.IO_LINK); 70 // e.flags = SubmissionEntryFlags.IO_DRAIN; 71 })(fd); 72 73 auto ret = io.submit(NUM_WRITES + 1); 74 if (ret < 0) 75 { 76 if (ret == -EINVAL) 77 { 78 version (D_BetterC) 79 { 80 errmsg = "kernel may not support barrier fsync yet"; 81 return; 82 } 83 else throw new Exception("kernel may not support barrier fsync yet"); 84 } 85 assert(0, "submit failed"); 86 } 87 else assert(ret == NUM_WRITES + 1); 88 89 assert(io.length == NUM_WRITES + 1); 90 foreach (i; 0..NUM_WRITES + 1) 91 { 92 if (io.front.res == -EINVAL) 93 { 94 version (D_BetterC) 95 { 96 errmsg = "kernel doesn't support IOSQE_IO_DRAIN"; 97 break; 98 } 99 else throw new Exception("kernel doesn't support IOSQE_IO_DRAIN"); 100 } 101 assert(io.front.res >= 0); 102 if (i < NUM_WRITES) assert(io.front.user_data == 1, "unexpected op completion"); 103 else assert(io.front.user_data == 2, "unexpected op completion"); 104 105 io.popFront(); 106 } 107 108 close(fd); 109 } 110 111 @("range") 112 unittest 113 { 114 version (D_BetterC) errmsg = "Not implemented"; 115 else throw new Exception("Not implemented"); 116 }