No changes in code, just some splitting out.
#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). */
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;
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;
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);
strv.h
strxcpyx.c
strxcpyx.h
+ sync-util.c
+ sync-util.h
sysctl-util.c
sysctl-util.h
syslog-util.c
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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);
#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"
#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"
(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);
#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"
(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)
#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"
#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
#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"
#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) {
#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;
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;
}
#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))
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;
}
#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"
#include "parse-util.h"
#include "random-util.h"
#include "string-util.h"
+#include "sync-util.h"
#include "util.h"
#include "xattr-util.h"
#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"
#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;
#include "alloc-util.h"
#include "fd-util.h"
-#include "fs-util.h"
#include "id128-util.h"
#include "io-util.h"
#include "log.h"
#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"
#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"
#include "signal-util.h"
#include "string-util.h"
#include "strv.h"
+#include "sync-util.h"
#include "umount.h"
#include "util.h"
#include "virt.h"
#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"
#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"