#define _GNU_SOURCE #define _LARGEFILE64_SOURCE #define _XOPEN_SOURCE 600 #include #include #include #include #include #include #include #include int main(void) { int ret; int fd = open("test.txt", O_CREAT | O_DIRECT | O_RDWR | O_TRUNC, 0777); if (fd < 0) { perror("open()"); exit(1); } const size_t pagesize = getpagesize(); printf("PAGE_SIZE: %d\n", pagesize); size_t buffsize = pagesize * 2; char *buf; ret = posix_memalign((void**)&buf, pagesize, buffsize); if (ret) { fprintf(stderr, "posix_memalign: %s\n", strerror(ret)); exit(1); } /* check file offset boundary */ off_t fboundary = pagesize; while (pwrite(fd, buf, buffsize, fboundary/2) == buffsize) { fboundary /= 2; } printf("O_DIRECT file offset boundary: %llu\n", (unsigned long long)fboundary); ret = ftruncate(fd, 0); if (ret < 0) { perror("ftruncate()"); exit(1); } /* check block size boundary */ size_t sboundary = pagesize; while (sboundary && pwrite(fd, buf, sboundary/2, 0) == sboundary/2) { sboundary /= 2; } printf("O_DIRECT block size boundary: %d\n", sboundary); ret = ftruncate(fd, 0); if (ret < 0) { perror("ftruncate()"); exit(1); } /* check buffer address boundary */ off_t aboundary = pagesize; if (sboundary == 0) sboundary = 512; while (pwrite(fd, buf + aboundary/2, sboundary, 0) == sboundary) { aboundary /= 2; } printf("O_DIRECT buffer address boundary: %llu\n", (unsigned long long)aboundary); ret = ftruncate(fd, 0); if (ret < 0) { perror("ftruncate()"); exit(1); } free(buf); /* test */ ret = posix_memalign((void**)&buf, aboundary, sboundary); if (ret) { fprintf(stderr, "posix_memalign: %s\n", strerror(ret)); exit(1); } if ((unsigned long)buf % aboundary) { fputs("not aligned mem\n", stderr); exit(1); } ssize_t written; written = pwrite(fd, buf, sboundary, fboundary * 3); if (written < 0) { perror("pwrite()"); exit(1); } free(buf); close(fd); struct stat st; ret = stat("test.txt", &st); if (ret < 0) { perror("stat()"); exit(1); } if (st.st_size != sboundary + fboundary * 3) { fputs("wrong size\n", stderr); exit(1); } puts("offset,size test OK"); unlink("test.txt"); return 0; }