summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/basic/fileio.c6
-rw-r--r--src/basic/fs-util.c166
-rw-r--r--src/basic/fs-util.h8
-rw-r--r--src/basic/meson.build2
-rw-r--r--src/basic/sync-util.c175
-rw-r--r--src/basic/sync-util.h11
-rw-r--r--src/boot/bless-boot.c1
-rw-r--r--src/boot/bootctl.c8
-rw-r--r--src/coredump/coredump.c8
-rw-r--r--src/home/homed-manager.c1
-rw-r--r--src/home/homework-luks.c1
-rw-r--r--src/import/pull-job.c2
-rw-r--r--src/libsystemd/sd-id128/id128-util.c7
-rw-r--r--src/libsystemd/sd-journal/journal-file.c9
-rw-r--r--src/partition/repart.c1
-rw-r--r--src/random-seed/random-seed.c1
-rw-r--r--src/shared/copy.c1
-rw-r--r--src/shared/install-file.c1
-rw-r--r--src/shared/machine-id-setup.c2
-rw-r--r--src/shutdown/umount.c2
-rw-r--r--src/sysusers/sysusers.c1
-rw-r--r--src/test/test-fs-util.c1
22 files changed, 216 insertions, 199 deletions
diff --git a/src/basic/fileio.c b/src/basic/fileio.c
index 601e1a61e9..a268a41add 100644
--- a/src/basic/fileio.c
+++ b/src/basic/fileio.c
@@ -25,6 +25,7 @@
#include "socket-util.h"
#include "stdio-util.h"
#include "string-util.h"
+#include "sync-util.h"
#include "tmpfile-util.h"
/* The maximum size of the file we'll read in one go in read_full_file() (64M). */
@@ -1195,10 +1196,7 @@ int fflush_sync_and_check(FILE *f) {
if (fd < 0)
return 0;
- if (fsync(fd) < 0)
- return -errno;
-
- r = fsync_directory_of_file(fd);
+ r = fsync_full(fd);
if (r < 0)
return r;
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
index 6c3ef972fe..2412df197a 100644
--- a/src/basic/fs-util.c
+++ b/src/basic/fs-util.c
@@ -1349,172 +1349,6 @@ int unlinkat_deallocate(int fd, const char *name, UnlinkDeallocateFlags flags) {
return 0;
}
-int fsync_directory_of_file(int fd) {
- _cleanup_close_ int dfd = -1;
- struct stat st;
- int r;
-
- assert(fd >= 0);
-
- /* We only reasonably can do this for regular files and directories, or for O_PATH fds, hence check
- * for the inode type first */
- if (fstat(fd, &st) < 0)
- return -errno;
-
- if (S_ISDIR(st.st_mode)) {
- dfd = openat(fd, "..", O_RDONLY|O_DIRECTORY|O_CLOEXEC, 0);
- if (dfd < 0)
- return -errno;
-
- } else if (!S_ISREG(st.st_mode)) { /* Regular files are OK regardless if O_PATH or not, for all other
- * types check O_PATH flag */
- int flags;
-
- flags = fcntl(fd, F_GETFL);
- if (flags < 0)
- return -errno;
-
- if (!FLAGS_SET(flags, O_PATH)) /* If O_PATH this refers to the inode in the fs, in which case
- * we can sensibly do what is requested. Otherwise this refers
- * to a socket, fifo or device node, where the concept of a
- * containing directory doesn't make too much sense. */
- return -ENOTTY;
- }
-
- if (dfd < 0) {
- _cleanup_free_ char *path = NULL;
-
- r = fd_get_path(fd, &path);
- if (r < 0) {
- log_debug_errno(r, "Failed to query /proc/self/fd/%d%s: %m",
- fd,
- r == -ENOSYS ? ", ignoring" : "");
-
- if (r == -ENOSYS)
- /* If /proc is not available, we're most likely running in some
- * chroot environment, and syncing the directory is not very
- * important in that case. Let's just silently do nothing. */
- return 0;
-
- return r;
- }
-
- if (!path_is_absolute(path))
- return -EINVAL;
-
- dfd = open_parent(path, O_CLOEXEC|O_NOFOLLOW, 0);
- if (dfd < 0)
- return dfd;
- }
-
- if (fsync(dfd) < 0)
- return -errno;
-
- return 0;
-}
-
-int fsync_full(int fd) {
- int r, q;
-
- /* Sync both the file and the directory */
-
- r = fsync(fd) < 0 ? -errno : 0;
-
- q = fsync_directory_of_file(fd);
- if (r < 0) /* Return earlier error */
- return r;
- if (q == -ENOTTY) /* Ignore if the 'fd' refers to a block device or so which doesn't really have a
- * parent dir */
- return 0;
- return q;
-}
-
-int fsync_path_at(int at_fd, const char *path) {
- _cleanup_close_ int opened_fd = -1;
- int fd;
-
- if (isempty(path)) {
- if (at_fd == AT_FDCWD) {
- opened_fd = open(".", O_RDONLY|O_DIRECTORY|O_CLOEXEC);
- if (opened_fd < 0)
- return -errno;
-
- fd = opened_fd;
- } else
- fd = at_fd;
- } else {
- opened_fd = openat(at_fd, path, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
- if (opened_fd < 0)
- return -errno;
-
- fd = opened_fd;
- }
-
- if (fsync(fd) < 0)
- return -errno;
-
- return 0;
-}
-
-int fsync_parent_at(int at_fd, const char *path) {
- _cleanup_close_ int opened_fd = -1;
-
- if (isempty(path)) {
- if (at_fd != AT_FDCWD)
- return fsync_directory_of_file(at_fd);
-
- opened_fd = open("..", O_RDONLY|O_DIRECTORY|O_CLOEXEC);
- if (opened_fd < 0)
- return -errno;
-
- if (fsync(opened_fd) < 0)
- return -errno;
-
- return 0;
- }
-
- opened_fd = openat(at_fd, path, O_PATH|O_CLOEXEC|O_NOFOLLOW);
- if (opened_fd < 0)
- return -errno;
-
- return fsync_directory_of_file(opened_fd);
-}
-
-int fsync_path_and_parent_at(int at_fd, const char *path) {
- _cleanup_close_ int opened_fd = -1;
-
- if (isempty(path)) {
- if (at_fd != AT_FDCWD)
- return fsync_full(at_fd);
-
- opened_fd = open(".", O_RDONLY|O_DIRECTORY|O_CLOEXEC);
- } else
- opened_fd = openat(at_fd, path, O_RDONLY|O_NOFOLLOW|O_NONBLOCK|O_CLOEXEC);
- if (opened_fd < 0)
- return -errno;
-
- return fsync_full(opened_fd);
-}
-
-int syncfs_path(int atfd, const char *path) {
- _cleanup_close_ int fd = -1;
-
- if (isempty(path)) {
- if (atfd != AT_FDCWD)
- return syncfs(atfd) < 0 ? -errno : 0;
-
- fd = open(".", O_RDONLY|O_DIRECTORY|O_CLOEXEC);
- } else
- fd = openat(atfd, path, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
- if (fd < 0)
- return -errno;
-
- if (syncfs(fd) < 0)
- return -errno;
-
- return 0;
-}
-
int open_parent(const char *path, int flags, mode_t mode) {
_cleanup_free_ char *parent = NULL;
int fd, r;
diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h
index d612cbe404..7120ecd99d 100644
--- a/src/basic/fs-util.h
+++ b/src/basic/fs-util.h
@@ -137,14 +137,6 @@ typedef enum UnlinkDeallocateFlags {
int unlinkat_deallocate(int fd, const char *name, UnlinkDeallocateFlags flags);
-int fsync_directory_of_file(int fd);
-int fsync_full(int fd);
-int fsync_path_at(int at_fd, const char *path);
-int fsync_parent_at(int at_fd, const char *path);
-int fsync_path_and_parent_at(int at_fd, const char *path);
-
-int syncfs_path(int atfd, const char *path);
-
int open_parent(const char *path, int flags, mode_t mode);
int conservative_renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
diff --git a/src/basic/meson.build b/src/basic/meson.build
index 82f42df929..7b42ac428c 100644
--- a/src/basic/meson.build
+++ b/src/basic/meson.build
@@ -215,6 +215,8 @@ basic_sources = files('''
strv.h
strxcpyx.c
strxcpyx.h
+ sync-util.c
+ sync-util.h
sysctl-util.c
sysctl-util.h
syslog-util.c
diff --git a/src/basic/sync-util.c b/src/basic/sync-util.c
new file mode 100644
index 0000000000..479ff73c63
--- /dev/null
+++ b/src/basic/sync-util.c
@@ -0,0 +1,175 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include "fd-util.h"
+#include "fs-util.h"
+#include "path-util.h"
+#include "sync-util.h"
+
+int fsync_directory_of_file(int fd) {
+ _cleanup_close_ int dfd = -1;
+ struct stat st;
+ int r;
+
+ assert(fd >= 0);
+
+ /* We only reasonably can do this for regular files and directories, or for O_PATH fds, hence check
+ * for the inode type first */
+ if (fstat(fd, &st) < 0)
+ return -errno;
+
+ if (S_ISDIR(st.st_mode)) {
+ dfd = openat(fd, "..", O_RDONLY|O_DIRECTORY|O_CLOEXEC, 0);
+ if (dfd < 0)
+ return -errno;
+
+ } else if (!S_ISREG(st.st_mode)) { /* Regular files are OK regardless if O_PATH or not, for all other
+ * types check O_PATH flag */
+ int flags;
+
+ flags = fcntl(fd, F_GETFL);
+ if (flags < 0)
+ return -errno;
+
+ if (!FLAGS_SET(flags, O_PATH)) /* If O_PATH this refers to the inode in the fs, in which case
+ * we can sensibly do what is requested. Otherwise this refers
+ * to a socket, fifo or device node, where the concept of a
+ * containing directory doesn't make too much sense. */
+ return -ENOTTY;
+ }
+
+ if (dfd < 0) {
+ _cleanup_free_ char *path = NULL;
+
+ r = fd_get_path(fd, &path);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to query /proc/self/fd/%d%s: %m",
+ fd,
+ r == -ENOSYS ? ", ignoring" : "");
+
+ if (r == -ENOSYS)
+ /* If /proc is not available, we're most likely running in some
+ * chroot environment, and syncing the directory is not very
+ * important in that case. Let's just silently do nothing. */
+ return 0;
+
+ return r;
+ }
+
+ if (!path_is_absolute(path))
+ return -EINVAL;
+
+ dfd = open_parent(path, O_CLOEXEC|O_NOFOLLOW, 0);
+ if (dfd < 0)
+ return dfd;
+ }
+
+ if (fsync(dfd) < 0)
+ return -errno;
+
+ return 0;
+}
+
+int fsync_full(int fd) {
+ int r, q;
+
+ /* Sync both the file and the directory */
+
+ r = fsync(fd) < 0 ? -errno : 0;
+
+ q = fsync_directory_of_file(fd);
+ if (r < 0) /* Return earlier error */
+ return r;
+ if (q == -ENOTTY) /* Ignore if the 'fd' refers to a block device or so which doesn't really have a
+ * parent dir */
+ return 0;
+ return q;
+}
+
+int fsync_path_at(int at_fd, const char *path) {
+ _cleanup_close_ int opened_fd = -1;
+ int fd;
+
+ if (isempty(path)) {
+ if (at_fd == AT_FDCWD) {
+ opened_fd = open(".", O_RDONLY|O_DIRECTORY|O_CLOEXEC);
+ if (opened_fd < 0)
+ return -errno;
+
+ fd = opened_fd;
+ } else
+ fd = at_fd;
+ } else {
+ opened_fd = openat(at_fd, path, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
+ if (opened_fd < 0)
+ return -errno;
+
+ fd = opened_fd;
+ }
+
+ if (fsync(fd) < 0)
+ return -errno;
+
+ return 0;
+}
+
+int fsync_parent_at(int at_fd, const char *path) {
+ _cleanup_close_ int opened_fd = -1;
+
+ if (isempty(path)) {
+ if (at_fd != AT_FDCWD)
+ return fsync_directory_of_file(at_fd);
+
+ opened_fd = open("..", O_RDONLY|O_DIRECTORY|O_CLOEXEC);
+ if (opened_fd < 0)
+ return -errno;
+
+ if (fsync(opened_fd) < 0)
+ return -errno;
+
+ return 0;
+ }
+
+ opened_fd = openat(at_fd, path, O_PATH|O_CLOEXEC|O_NOFOLLOW);
+ if (opened_fd < 0)
+ return -errno;
+
+ return fsync_directory_of_file(opened_fd);
+}
+
+int fsync_path_and_parent_at(int at_fd, const char *path) {
+ _cleanup_close_ int opened_fd = -1;
+
+ if (isempty(path)) {
+ if (at_fd != AT_FDCWD)
+ return fsync_full(at_fd);
+
+ opened_fd = open(".", O_RDONLY|O_DIRECTORY|O_CLOEXEC);
+ } else
+ opened_fd = openat(at_fd, path, O_RDONLY|O_NOFOLLOW|O_NONBLOCK|O_CLOEXEC);
+ if (opened_fd < 0)
+ return -errno;
+
+ return fsync_full(opened_fd);
+}
+
+int syncfs_path(int at_fd, const char *path) {
+ _cleanup_close_ int fd = -1;
+
+ if (isempty(path)) {
+ if (at_fd != AT_FDCWD)
+ return syncfs(at_fd) < 0 ? -errno : 0;
+
+ fd = open(".", O_RDONLY|O_DIRECTORY|O_CLOEXEC);
+ } else
+ fd = openat(at_fd, path, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
+ if (fd < 0)
+ return -errno;
+
+ if (syncfs(fd) < 0)
+ return -errno;
+
+ return 0;
+}
diff --git a/src/basic/sync-util.h b/src/basic/sync-util.h
new file mode 100644
index 0000000000..e449440a53
--- /dev/null
+++ b/src/basic/sync-util.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+int fsync_directory_of_file(int fd);
+int fsync_full(int fd);
+
+int fsync_path_at(int at_fd, const char *path);
+int fsync_parent_at(int at_fd, const char *path);
+int fsync_path_and_parent_at(int at_fd, const char *path);
+
+int syncfs_path(int at_fd, const char *path);
diff --git a/src/boot/bless-boot.c b/src/boot/bless-boot.c
index 7d5a52841e..cb06886727 100644
--- a/src/boot/bless-boot.c
+++ b/src/boot/bless-boot.c
@@ -14,6 +14,7 @@
#include "parse-util.h"
#include "path-util.h"
#include "pretty-print.h"
+#include "sync-util.h"
#include "terminal-util.h"
#include "util.h"
#include "verbs.h"
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index 27b0086406..91b36e91ba 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -38,6 +38,7 @@
#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
+#include "sync-util.h"
#include "terminal-util.h"
#include "tmpfile-util.h"
#include "umask-util.h"
@@ -569,13 +570,12 @@ static int copy_file_with_version_check(const char *from, const char *to, bool f
(void) copy_times(fd_from, fd_to, 0);
- if (fsync(fd_to) < 0) {
+ r = fsync_full(fd_to);
+ if (r < 0) {
(void) unlink_noerrno(t);
- return log_error_errno(errno, "Failed to copy data from \"%s\" to \"%s\": %m", from, t);
+ return log_error_errno(r, "Failed to copy data from \"%s\" to \"%s\": %m", from, t);
}
- (void) fsync_directory_of_file(fd_to);
-
if (renameat(AT_FDCWD, t, AT_FDCWD, to) < 0) {
(void) unlink_noerrno(t);
return log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", t, to);
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index 444b9ec374..d7eab3d36c 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -48,6 +48,7 @@
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
+#include "sync-util.h"
#include "tmpfile-util.h"
#include "user-record.h"
#include "user-util.h"
@@ -261,10 +262,9 @@ static int fix_permissions(
(void) fix_acl(fd, uid);
(void) fix_xattr(fd, context);
- if (fsync(fd) < 0)
- return log_error_errno(errno, "Failed to sync coredump %s: %m", coredump_tmpfile_name(filename));
-
- (void) fsync_directory_of_file(fd);
+ r = fsync_full(fd);
+ if (r < 0)
+ return log_error_errno(r, "Failed to sync coredump %s: %m", coredump_tmpfile_name(filename));
r = link_tmpfile(fd, filename, target);
if (r < 0)
diff --git a/src/home/homed-manager.c b/src/home/homed-manager.c
index 6549e6bd4e..070fd97d69 100644
--- a/src/home/homed-manager.c
+++ b/src/home/homed-manager.c
@@ -38,6 +38,7 @@
#include "socket-util.h"
#include "stat-util.h"
#include "strv.h"
+#include "sync-util.h"
#include "tmpfile-util.h"
#include "udev-util.h"
#include "user-record-sign.h"
diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c
index 2321a31021..8af9223d57 100644
--- a/src/home/homework-luks.c
+++ b/src/home/homework-luks.c
@@ -36,6 +36,7 @@
#include "resize-fs.h"
#include "stat-util.h"
#include "strv.h"
+#include "sync-util.h"
#include "tmpfile-util.h"
/* Round down to the nearest 4K size. Given that newer hardware generally prefers 4K sectors, let's align our
diff --git a/src/import/pull-job.c b/src/import/pull-job.c
index 4e37dce33f..34b116a8f8 100644
--- a/src/import/pull-job.c
+++ b/src/import/pull-job.c
@@ -7,7 +7,6 @@
#include "alloc-util.h"
#include "fd-util.h"
#include "format-util.h"
-#include "fs-util.h"
#include "gcrypt-util.h"
#include "hexdecoct.h"
#include "import-util.h"
@@ -18,6 +17,7 @@
#include "pull-job.h"
#include "string-util.h"
#include "strv.h"
+#include "sync-util.h"
#include "xattr-util.h"
void pull_job_close_disk_fd(PullJob *j) {
diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c
index 2074771a41..19937110b0 100644
--- a/src/libsystemd/sd-id128/id128-util.c
+++ b/src/libsystemd/sd-id128/id128-util.c
@@ -5,12 +5,12 @@
#include <unistd.h>
#include "fd-util.h"
-#include "fs-util.h"
#include "hexdecoct.h"
#include "id128-util.h"
#include "io-util.h"
#include "stdio-util.h"
#include "string-util.h"
+#include "sync-util.h"
char *id128_to_uuid_string(sd_id128_t id, char s[static ID128_UUID_STRING_MAX]) {
unsigned n, k = 0;
@@ -167,10 +167,7 @@ int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync) {
return r;
if (do_sync) {
- if (fsync(fd) < 0)
- return -errno;
-
- r = fsync_directory_of_file(fd);
+ r = fsync_full(fd);
if (r < 0)
return r;
}
diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c
index 9fecc84495..d5ceba2f8f 100644
--- a/src/libsystemd/sd-journal/journal-file.c
+++ b/src/libsystemd/sd-journal/journal-file.c
@@ -32,6 +32,7 @@
#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
+#include "sync-util.h"
#include "xattr-util.h"
#define DEFAULT_DATA_HASH_TABLE_SIZE (2047ULL*sizeof(HashItem))
@@ -474,11 +475,9 @@ static int journal_file_refresh_header(JournalFile *f) {
r = journal_file_set_online(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);
+ /* Sync the online state to disk; likely just created a new file, also sync the directory this file
+ * is located in. */
+ (void) fsync_full(f->fd);
return r;
}
diff --git a/src/partition/repart.c b/src/partition/repart.c
index 564ee4835b..3203b48d8c 100644
--- a/src/partition/repart.c
+++ b/src/partition/repart.c
@@ -61,6 +61,7 @@
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
+#include "sync-util.h"
#include "terminal-util.h"
#include "tpm2-util.h"
#include "user-util.h"
diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c
index e003ca60e3..7724e0365e 100644
--- a/src/random-seed/random-seed.c
+++ b/src/random-seed/random-seed.c
@@ -25,6 +25,7 @@
#include "parse-util.h"
#include "random-util.h"
#include "string-util.h"
+#include "sync-util.h"
#include "util.h"
#include "xattr-util.h"
diff --git a/src/shared/copy.c b/src/shared/copy.c
index f27ce252ee..9053fce333 100644
--- a/src/shared/copy.c
+++ b/src/shared/copy.c
@@ -29,6 +29,7 @@
#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
+#include "sync-util.h"
#include "time-util.h"
#include "tmpfile-util.h"
#include "umask-util.h"
diff --git a/src/shared/install-file.c b/src/shared/install-file.c
index 664f028ad1..5187d71bec 100644
--- a/src/shared/install-file.c
+++ b/src/shared/install-file.c
@@ -10,6 +10,7 @@
#include "install-file.h"
#include "missing_syscall.h"
#include "rm-rf.h"
+#include "sync-util.h"
int fs_make_very_read_only(int fd) {
struct stat st;
diff --git a/src/shared/machine-id-setup.c b/src/shared/machine-id-setup.c
index d2f989272d..e483675a75 100644
--- a/src/shared/machine-id-setup.c
+++ b/src/shared/machine-id-setup.c
@@ -9,7 +9,6 @@
#include "alloc-util.h"
#include "fd-util.h"
-#include "fs-util.h"
#include "id128-util.h"
#include "io-util.h"
#include "log.h"
@@ -23,6 +22,7 @@
#include "process-util.h"
#include "stat-util.h"
#include "string-util.h"
+#include "sync-util.h"
#include "umask-util.h"
#include "util.h"
#include "virt.h"
diff --git a/src/shutdown/umount.c b/src/shutdown/umount.c
index c2a26242c0..09fc339ab1 100644
--- a/src/shutdown/umount.c
+++ b/src/shutdown/umount.c
@@ -23,7 +23,6 @@
#include "device-util.h"
#include "escape.h"
#include "fd-util.h"
-#include "fs-util.h"
#include "fstab-util.h"
#include "libmount-util.h"
#include "mount-setup.h"
@@ -34,6 +33,7 @@
#include "signal-util.h"
#include "string-util.h"
#include "strv.h"
+#include "sync-util.h"
#include "umount.h"
#include "util.h"
#include "virt.h"
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index 7daebdbe55..c55f7f8b7e 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -29,6 +29,7 @@
#include "specifier.h"
#include "string-util.h"
#include "strv.h"
+#include "sync-util.h"
#include "tmpfile-util-label.h"
#include "uid-range.h"
#include "user-record.h"
diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c
index ac7ee5d3bf..f0cac447c3 100644
--- a/src/test/test-fs-util.c
+++ b/src/test/test-fs-util.c
@@ -16,6 +16,7 @@
#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
+#include "sync-util.h"
#include "tests.h"
#include "tmpfile-util.h"
#include "umask-util.h"