From: Lennart Poettering Date: Wed, 24 Dec 2014 15:39:55 +0000 (+0100) Subject: util: make creation time xattr logic more generic X-Git-Tag: v219~853 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=4a4d89b682d2a8d32e899c4b47950f64df74fb7c util: make creation time xattr logic more generic --- diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index fec54f31b..48c27ee62 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "journal-def.h" #include "journal-file.h" @@ -2526,8 +2525,6 @@ int journal_file_open( } if (f->last_stat.st_size == 0 && f->writable) { - uint64_t crtime; - /* Let's attach the creation time to the journal file, * so that the vacuuming code knows the age of this * file even if the file might end up corrupted one @@ -2538,8 +2535,7 @@ int journal_file_open( * attributes are not supported we'll just skip this, * and rely solely on mtime/atime/ctime of the file. */ - crtime = htole64((uint64_t) now(CLOCK_REALTIME)); - fsetxattr(f->fd, "user.crtime_usec", &crtime, sizeof(crtime), XATTR_CREATE); + fd_setcrtime(f->fd, now(CLOCK_REALTIME)); #ifdef HAVE_GCRYPT /* Try to load the FSPRG state, and if we can't, then diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c index 497340984..832c327b3 100644 --- a/src/journal/journal-vacuum.c +++ b/src/journal/journal-vacuum.c @@ -75,9 +75,8 @@ static void patch_realtime( const struct stat *st, unsigned long long *realtime) { - usec_t x; - uint64_t crtime; _cleanup_free_ const char *path = NULL; + usec_t x, crtime; /* The timestamp was determined by the file name, but let's * see if the file might actually be older than the file name @@ -112,10 +111,8 @@ static void patch_realtime( if (!path) return; - if (getxattr(path, "user.crtime_usec", &crtime, sizeof(crtime)) == sizeof(crtime)) { - crtime = le64toh(crtime); - - if (crtime > 0 && crtime != (uint64_t) -1 && crtime < *realtime) + if (path_getcrtime(path, &crtime) >= 0) { + if (crtime < *realtime) *realtime = crtime; } } diff --git a/src/shared/util.c b/src/shared/util.c index e95f6ed24..98b3465d4 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #undef basename @@ -84,6 +85,7 @@ #include "gunicode.h" #include "virt.h" #include "def.h" +#include "sparse-endian.h" int saved_argc = 0; char **saved_argv = NULL; @@ -7558,3 +7560,62 @@ int openpt_in_namespace(pid_t pid, int flags) { return -EIO; } + +int fd_getcrtime(int fd, usec_t *usec) { + uint64_t u; + le64_t le; + ssize_t n; + + assert(fd >= 0); + assert(usec); + + /* Until Linux gets a real concept of birthtime/creation time, + * let's fake one with xattrs */ + + n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le)); + if (n < 0) + return -errno; + if (n != sizeof(le)) + return -EIO; + + u = le64toh(le); + if (u == 0 || u == (uint64_t) -1) + return -EIO; + + *usec = (usec_t) u; + return 0; +} + +int path_getcrtime(const char *p, usec_t *usec) { + uint64_t u; + le64_t le; + ssize_t n; + + assert(p); + assert(usec); + + n = getxattr(p, "user.crtime_usec", &le, sizeof(le)); + if (n < 0) + return -errno; + if (n != sizeof(le)) + return -EIO; + + u = le64toh(le); + if (u == 0 || u == (uint64_t) -1) + return -EIO; + + *usec = (usec_t) u; + return 0; +} + +int fd_setcrtime(int fd, usec_t usec) { + le64_t le; + + assert(fd >= 0); + + le = htole64((uint64_t) usec); + if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), XATTR_CREATE) < 0) + return -errno; + + return 0; +} diff --git a/src/shared/util.h b/src/shared/util.h index 7f02f42c6..4d5b9824d 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -1062,3 +1062,7 @@ union inotify_event_buffer { int ptsname_malloc(int fd, char **ret); int openpt_in_namespace(pid_t pid, int flags); + +int fd_setcrtime(int fd, usec_t usec); +int fd_getcrtime(int fd, usec_t *usec); +int path_getcrtime(const char *p, usec_t *usec);