chiark / gitweb /
fs-util: move fsync_directory_of_file() into generic code
authorLennart Poettering <lennart@poettering.net>
Mon, 19 Feb 2018 17:23:38 +0000 (18:23 +0100)
committerSven Eden <yamakuzure@gmx.net>
Wed, 30 May 2018 05:59:00 +0000 (07:59 +0200)
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.

src/basic/fs-util.c
src/basic/fs-util.h
src/test/test-fs-util.c

index 87116d61866fb0b42ab6a60ea46f146b2e5155ab..687a406d7d083209088e43ea9a4113ddd7e66aa7 100644 (file)
@@ -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;
+}
index 0e9fea9919defbfc557c46a4ac1fdf31ce413ab9..0737e403ed62749f8a47abd6f179e1a3422b155c 100644 (file)
@@ -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);
index 49883eeaa3ea151b3ea1e8d55bc28e0a5ac4dfab..507e24bdc2186c16cc5bedc50845c6343d5143a4 100644 (file)
@@ -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;
 }