diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index 47edcbb04f..85c8070a1b 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -967,3 +967,33 @@ int unlinkat_deallocate(int fd, const char *name, int flags) { return 0; } + +int fsync_directory_of_file(int fd) { + _cleanup_free_ char *path = NULL, *dn = NULL; + _cleanup_close_ int dfd = -1; + int r; + + r = fd_verify_regular(fd); + if (r < 0) + return r; + + 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; +} diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h index acb83dfd83..82d7e765b3 100644 --- a/src/basic/fs-util.h +++ b/src/basic/fs-util.h @@ -107,3 +107,5 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free); int access_fd(int fd, int mode); int unlinkat_deallocate(int fd, const char *name, int flags); + +int fsync_directory_of_file(int fd); diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 96e45e92f5..9820123660 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -33,6 +33,7 @@ #include "chattr-util.h" #include "compress.h" #include "fd-util.h" +#include "fs-util.h" #include "journal-authenticate.h" #include "journal-def.h" #include "journal-file.h" @@ -454,39 +455,6 @@ 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; diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c index 184a2a52c2..ebcec4fcc5 100644 --- a/src/test/test-fs-util.c +++ b/src/test/test-fs-util.c @@ -552,6 +552,15 @@ static void test_unlinkat_deallocate(void) { assert_se(st.st_nlink == 0); } +static void test_fsync_directory_of_file(void) { + _cleanup_close_ int fd = -1; + + fd = open_tmpfile_unlinkable(NULL, O_RDWR); + assert_se(fd >= 0); + + assert_se(fsync_directory_of_file(fd) >= 0); +} + int main(int argc, char *argv[]) { test_unlink_noerrno(); test_get_files_in_directory(); @@ -562,6 +571,7 @@ int main(int argc, char *argv[]) { test_access_fd(); test_touch_file(); test_unlinkat_deallocate(); + test_fsync_directory_of_file(); return 0; }