mirror of
https://github.com/systemd/systemd.git
synced 2025-02-03 17:47:28 +03:00
sd-journal: cache last entry offset and journal file state
When the offset of the last entry object (or last object for journal files generated by an old journald) is not changed, the timestamps should be updated by journal_file_read_tail_timestamp() are unchanged. So, we can drop to call fstat() in the function. As, the journal header is always mapped, so we can read the offset and journal file state without calling fstat. Still, when the last entry offset is changed, we may need to call fstat() to read the entry object. But, hopefully the number of fstat() call can be reduced.
This commit is contained in:
parent
4ebf678f1f
commit
99e6f682d3
@ -2244,7 +2244,6 @@ static int journal_file_link_entry(
|
||||
f->header->tail_entry_monotonic = o->entry.monotonic;
|
||||
if (JOURNAL_HEADER_CONTAINS(f->header, tail_entry_offset))
|
||||
f->header->tail_entry_offset = htole64(offset);
|
||||
f->newest_mtime = 0; /* we have a new tail entry now, explicitly invalidate newest boot id/timestamp info */
|
||||
|
||||
/* Link up the items */
|
||||
for (uint64_t i = 0; i < n_items; i++) {
|
||||
|
@ -129,7 +129,8 @@ typedef struct JournalFile {
|
||||
uint64_t newest_monotonic_usec;
|
||||
uint64_t newest_realtime_usec;
|
||||
unsigned newest_boot_id_prioq_idx;
|
||||
usec_t newest_mtime;
|
||||
uint64_t newest_entry_offset;
|
||||
uint8_t newest_state;
|
||||
} JournalFile;
|
||||
|
||||
typedef enum JournalFileFlags {
|
||||
|
@ -2428,11 +2428,10 @@ static int journal_file_read_tail_timestamp(sd_journal *j, JournalFile *f) {
|
||||
|
||||
/* Tries to read the timestamp of the most recently written entry. */
|
||||
|
||||
r = journal_file_fstat(f);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (f->newest_mtime == timespec_load(&f->last_stat.st_mtim))
|
||||
return 0; /* mtime didn't change since last time, don't bother */
|
||||
if (f->header->state == f->newest_state &&
|
||||
f->header->state == STATE_ARCHIVED &&
|
||||
f->newest_entry_offset != 0)
|
||||
return 0; /* We have already read archived file. */
|
||||
|
||||
if (JOURNAL_HEADER_CONTAINS(f->header, tail_entry_offset)) {
|
||||
offset = le64toh(READ_NOW(f->header->tail_entry_offset));
|
||||
@ -2443,6 +2442,8 @@ static int journal_file_read_tail_timestamp(sd_journal *j, JournalFile *f) {
|
||||
}
|
||||
if (offset == 0)
|
||||
return -ENODATA; /* not a single object/entry, hence no tail timestamp */
|
||||
if (offset == f->newest_entry_offset)
|
||||
return 0; /* No new entry is added after we read last time. */
|
||||
|
||||
/* Move to the last object in the journal file, in the hope it is an entry (which it usually will
|
||||
* be). If we lack the "tail_entry_offset" field in the header, we specify the type as OBJECT_UNUSED
|
||||
@ -2452,6 +2453,7 @@ static int journal_file_read_tail_timestamp(sd_journal *j, JournalFile *f) {
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to move to last object in journal file, ignoring: %m");
|
||||
o = NULL;
|
||||
offset = 0;
|
||||
}
|
||||
if (o && o->object.type == OBJECT_ENTRY) {
|
||||
/* Yay, last object is an entry, let's use the data. */
|
||||
@ -2469,10 +2471,11 @@ static int journal_file_read_tail_timestamp(sd_journal *j, JournalFile *f) {
|
||||
mo = le64toh(f->header->tail_entry_monotonic);
|
||||
rt = le64toh(f->header->tail_entry_realtime);
|
||||
id = f->header->tail_entry_boot_id;
|
||||
offset = UINT64_MAX;
|
||||
} else {
|
||||
/* Otherwise let's find the last entry manually (this possibly means traversing the
|
||||
* chain of entry arrays, till the end */
|
||||
r = journal_file_next_entry(f, 0, DIRECTION_UP, &o, NULL);
|
||||
r = journal_file_next_entry(f, 0, DIRECTION_UP, &o, offset == 0 ? &offset : NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
@ -2494,7 +2497,8 @@ static int journal_file_read_tail_timestamp(sd_journal *j, JournalFile *f) {
|
||||
f->newest_monotonic_usec = mo;
|
||||
f->newest_realtime_usec = rt;
|
||||
f->newest_machine_id = f->header->machine_id;
|
||||
f->newest_mtime = timespec_load(&f->last_stat.st_mtim);
|
||||
f->newest_entry_offset = offset;
|
||||
f->newest_state = f->header->state;
|
||||
|
||||
r = journal_file_reshuffle_newest_by_boot_id(j, f);
|
||||
if (r < 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user