mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-03-10 00:58:20 +03:00
Merge pull request #18864 from poettering/fsync-tweaks
make sure fsync_directory_of_file() + fsync_full() work on more inode types reasonably
This commit is contained in:
commit
6ce8eda8a1
@ -1413,11 +1413,16 @@ int unlinkat_deallocate(int fd, const char *name, UnlinkDeallocateFlags flags) {
|
||||
int fsync_directory_of_file(int fd) {
|
||||
_cleanup_free_ char *path = NULL;
|
||||
_cleanup_close_ int dfd = -1;
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
r = fd_verify_regular(fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
assert(fd >= 0);
|
||||
|
||||
/* We only reasonably can do this for regular files and directories, hence check for that */
|
||||
if (fstat(fd, &st) < 0)
|
||||
return -errno;
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
|
||||
r = fd_get_path(fd, &path);
|
||||
if (r < 0) {
|
||||
@ -1437,10 +1442,17 @@ int fsync_directory_of_file(int fd) {
|
||||
if (!path_is_absolute(path))
|
||||
return -EINVAL;
|
||||
|
||||
dfd = open_parent(path, O_CLOEXEC, 0);
|
||||
dfd = open_parent(path, O_CLOEXEC|O_NOFOLLOW, 0);
|
||||
if (dfd < 0)
|
||||
return dfd;
|
||||
|
||||
} else if (S_ISDIR(st.st_mode)) {
|
||||
dfd = openat(fd, "..", O_RDONLY|O_DIRECTORY|O_CLOEXEC, 0);
|
||||
if (dfd < 0)
|
||||
return -errno;
|
||||
} else
|
||||
return -ENOTTY;
|
||||
|
||||
if (fsync(dfd) < 0)
|
||||
return -errno;
|
||||
|
||||
@ -1453,9 +1465,14 @@ int fsync_full(int fd) {
|
||||
/* Sync both the file and the directory */
|
||||
|
||||
r = fsync(fd) < 0 ? -errno : 0;
|
||||
q = fsync_directory_of_file(fd);
|
||||
|
||||
return r < 0 ? r : q;
|
||||
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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user