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.
This commit is contained in:
Lennart Poettering 2018-02-19 18:23:38 +01:00
parent 3cc4411403
commit 11b29a96e9
4 changed files with 43 additions and 33 deletions

View File

@ -967,3 +967,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;
}

View File

@ -107,3 +107,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);

View File

@ -33,6 +33,7 @@
#include "chattr-util.h"
#include "compress.h"
#include "fd-util.h"
#include "fs-util.h"
#include "journal-authenticate.h"
#include "journal-def.h"
#include "journal-file.h"
@ -454,39 +455,6 @@ static int journal_file_init_header(JournalFile *f, JournalFile *template) {
return 0;
}
static int fsync_directory_of_file(int fd) {
_cleanup_free_ char *path = NULL, *dn = NULL;
_cleanup_close_ int dfd = -1;
struct stat st;
int r;
if (fstat(fd, &st) < 0)
return -errno;
if (!S_ISREG(st.st_mode))
return -EBADFD;
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;
}
static int journal_file_refresh_header(JournalFile *f) {
sd_id128_t boot_id;
int r;

View File

@ -552,6 +552,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();
@ -562,6 +571,7 @@ int main(int argc, char *argv[]) {
test_access_fd();
test_touch_file();
test_unlinkat_deallocate();
test_fsync_directory_of_file();
return 0;
}