From: Lennart Poettering Date: Mon, 19 Feb 2018 17:23:38 +0000 (+0100) Subject: fs-util: move fsync_directory_of_file() into generic code X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=71b2b9d7412a0f916f5be02c73f8b12e531babf8;p=elogind.git fs-util: move fsync_directory_of_file() into generic code This function used by the journal code is pretty useful generically, let's move it to fs-util.c to make it useful for other code too. --- diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index 87116d618..687a406d7 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -982,3 +982,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 0e9fea991..0737e403e 100644 --- a/src/basic/fs-util.h +++ b/src/basic/fs-util.h @@ -123,3 +123,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/test/test-fs-util.c b/src/test/test-fs-util.c index 49883eeaa..507e24bdc 100644 --- a/src/test/test-fs-util.c +++ b/src/test/test-fs-util.c @@ -556,6 +556,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(); @@ -570,6 +579,7 @@ int main(int argc, char *argv[]) { #endif // 0 test_touch_file(); test_unlinkat_deallocate(); + test_fsync_directory_of_file(); return 0; }