I have a test program. It takes about 37 seconds on Linux kernel 3.1.*, but only takes about 1 seconds on kernel 3.0.18 (I just replace the kernel on the same machine as before). Please give me a clue on how to improve it on kernel 3.1. Thanks!
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int my_fsync(int fd)
{
// return fdatasync(fd);
return fsync(fd);
}
int main(int argc, char **argv)
{
int rc = 0;
int count;
int i;
char oldpath[1024];
char newpath[1024];
char *writebuffer = calloc(1024, 1);
snprintf(oldpath, sizeof(oldpath), "./%s", "foo");
snprintf(newpath, sizeof(newpath), "./%s", "foo.new");
for (count = 0; count < 1000; ++count) {
int fd = open(newpath, O_CREAT | O_TRUNC | O_WRONLY, S_IRWXU);
if (fd == -1) {
fprintf(stderr, "open error! path: %s\n", newpath);
exit(1);
}
for (i = 0; i < 10; i++) {
rc = write(fd, writebuffer, 1024);
if (rc != 1024) {
fprintf(stderr, "underwrite!\n");
exit(1);
}
}
if (my_fsync(fd)) {
perror("fsync failed!\n");
exit(1);
}
if (close(fd)) {
perror("close failed!\n");
exit(1);
}
if (rename(newpath, oldpath)) {
perror("rename failed!\n");
exit(1);
}
}
return 0;
}
# strace -c ./testfsync
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
98.58 0.068004 68 1000 fsync
0.84 0.000577 0 10001 write
0.40 0.000275 0 1000 rename
0.19 0.000129 0 1003 open
0.00 0.000000 0 1 read
0.00 0.000000 0 1003 close
0.00 0.000000 0 1 execve
0.00 0.000000 0 1 1 access
0.00 0.000000 0 3 brk
0.00 0.000000 0 1 munmap
0.00 0.000000 0 2 setitimer
0.00 0.000000 0 68 sigreturn
0.00 0.000000 0 1 uname
0.00 0.000000 0 1 mprotect
0.00 0.000000 0 2 writev
0.00 0.000000 0 2 rt_sigaction
0.00 0.000000 0 6 mmap2
0.00 0.000000 0 2 fstat64
0.00 0.000000 0 1 set_thread_area
------ ----------- ----------- --------- --------- ----------------
100.00 0.068985 14099 1 total
Found the reason. File system barriers enabled by default in ext3 for Linux kernel 3.1 (http://kernelnewbies.org/Linux_3.1). After disable barriers, it becomes much faster.