#include #include #include #include #include #include #include #include #define BLOCKSIZE 4096 #define RECSIZE 8 #define COUNT 1000000 static void do_test(int append_fd, int inplace_fd, int use_fdatasync) { char buf[RECSIZE+1]; char buf2[BLOCKSIZE]; int seq; int res; memset(buf2, 0, sizeof(buf2)); for (seq = 0; seq < COUNT; ++seq) { printf("Adding log entry %d...\n", seq); snprintf(buf, sizeof(buf), "%7d\n", seq); res = write(append_fd, buf, RECSIZE); if (res != RECSIZE) { fprintf(stderr, "Unexpected return %d from write() (errno=%d: %s)\n", res, errno, strerror(errno)); exit(1); } res = use_fdatasync ? fdatasync(append_fd) : fsync(append_fd); if (res) { fprintf(stderr, "Error in fdatasync() of append file (errno=%d: %s)\n", errno, strerror(errno)); exit(1); } memcpy(buf2 + (seq * RECSIZE) % BLOCKSIZE, buf, RECSIZE); res = pwrite(inplace_fd, buf2, BLOCKSIZE, 0); if (res != BLOCKSIZE) { fprintf(stderr, "Unexpected return %d from pwrite() (errno=%d: %s)\n", res, errno, strerror(errno)); exit(1); } res = fdatasync(inplace_fd); if (res) { fprintf(stderr, "Error in fdatasync() of inplace file (errno=%d: %s)\n", errno, strerror(errno)); exit(1); } } } int main(int argc, char *argv[]) { int append_fd, inplace_fd; int res; int use_fdatasync = 1; unsigned char buf[BLOCKSIZE]; if (argc > 1 && !strcmp("--fsync", argv[1])) use_fdatasync = 0; append_fd = open("append.log", O_WRONLY|O_CREAT|O_TRUNC, 0666); if (append_fd < 0) { fprintf(stderr, "Failed to open append file: %d: %s\n", errno, strerror(errno)); exit(1); } res = fsync(append_fd); if (res) { fprintf(stderr, "Failed initial fsync() of append file: %d: %s\n", errno, strerror(errno)); exit(1); } inplace_fd = open("inplace.log", O_WRONLY|O_CREAT, 0666); if (inplace_fd < 0) { fprintf(stderr, "Failed to open inplace file: %d: %s\n", errno, strerror(errno)); exit(1); } memset(buf, 0, BLOCKSIZE); res = write(inplace_fd, buf, BLOCKSIZE); if (res != BLOCKSIZE) { fprintf(stderr, "Failed to initialise inplace file, write() returns %d " "errno=%d: %s\n", res, errno, strerror(errno)); exit(1); } res = fsync(inplace_fd); if (res) { fprintf(stderr, "Failed initial fsync() of inplace file: %d: %s\n", errno, strerror(errno)); exit(1); } do_test(append_fd, inplace_fd, use_fdatasync); return 0; }