08 June, 2011

Using fsync and fsync_range with directories

There is a non-obvious difference between possible fd argument for fsync() and fsync_range(). In Linux and NetBSD you can use fsync() to sync directory. In NetBSD there is also fsync_range() which can't be used for directories, because it expects writable fd. Originally I thought that if fsync_range() can't, then fsync() can't too, but it can.

Example below shows how to obtain file descriptor for directory to use it with fsync:
#include <stdio.h>
#include <stdlib.h>

#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>


int main() {
    int fd;
    DIR *dirp;
    int error;
    char path[] = "test_dir";

    if ((dirp = opendir(path)) == 0) {
        printf("Failed to open dir: %d\n", errno);
        return -1;
    }
    fd = dirfd(dirp);
    if (fd == -1) {
        printf("Failed to open: %d\n", errno);
        return -1;
    }

    if (fsync(fd) == -1) {
        printf("fsync failed: %d\n", errno);
        return -1;
    }
    return 0;
}

No comments: