From a0fe2a2d2028ea8b5e6873b1f55e91a36081656c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 26 Apr 2016 15:47:55 +0200 Subject: [PATCH] journal: when creating a new journal file, fsync() the directory it is created in too Fixes: #2831 --- src/basic/fd-util.c | 8 +++++++- src/journal/journal-file.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index 9130d02..8b466cf 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -361,8 +361,14 @@ bool fdname_is_valid(const char *s) { int fd_get_path(int fd, char **ret) { char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + int r; xsprintf(procfs_path, "/proc/self/fd/%i", fd); - return readlink_malloc(procfs_path, ret); + r = readlink_malloc(procfs_path, ret); + + if (r == -ENOENT) /* If the file doesn't exist the fd is invalid */ + return -EBADF; + + return r; } diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 35f4aba..a58079b 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -439,6 +439,39 @@ static int journal_file_init_header(JournalFile *f, JournalFile *template) { return 0; } +static int fsync_directory_of_file(int fd) { + _cleanup_free_ char *path = NULL, *dn = NULL; + _cleanup_close_ int dfd = -1; + struct stat st; + int r; + + if (fstat(fd, &st) < 0) + return -errno; + + if (!S_ISREG(st.st_mode)) + return -EBADFD; + + r = fd_get_path(fd, &path); + if (r < 0) + return r; + + if (!path_is_absolute(path)) + return -EINVAL; + + dn = dirname_malloc(path); + if (!dn) + return -ENOMEM; + + dfd = open(dn, O_RDONLY|O_CLOEXEC|O_DIRECTORY); + if (dfd < 0) + return -errno; + + if (fsync(dfd) < 0) + return -errno; + + return 0; +} + static int journal_file_refresh_header(JournalFile *f) { sd_id128_t boot_id; int r; @@ -464,6 +497,9 @@ static int journal_file_refresh_header(JournalFile *f) { /* Sync the online state to disk */ (void) fsync(f->fd); + /* We likely just created a new file, also sync the directory this file is located in. */ + (void) fsync_directory_of_file(f->fd); + return r; } -- 2.7.4