X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fjournal%2Fjournal-file.c;h=0e33a0fd873e7562a640d50246bb0c9e9e169603;hp=c9030c56addb5e7dac5f6d19c23b9b70d9fae234;hb=b6e676ce41508e2aeea22202fc8f234126177f52;hpb=b9a1617d75c16a48cccf4ff135013dca9af94e7d diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index c9030c56a..0e33a0fd8 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "btrfs-util.h" #include "journal-def.h" @@ -33,7 +34,6 @@ #include "journal-authenticate.h" #include "lookup3.h" #include "compress.h" -#include "fsprg.h" #define DEFAULT_DATA_HASH_TABLE_SIZE (2047ULL*sizeof(HashItem)) #define DEFAULT_FIELD_HASH_TABLE_SIZE (333ULL*sizeof(HashItem)) @@ -141,8 +141,17 @@ void journal_file_close(JournalFile *f) { if (f->mmap && f->fd >= 0) mmap_cache_close_fd(f->mmap, f->fd); - if (f->fd >= 0 && f->defrag_on_close) - btrfs_defrag_fd(f->fd); + if (f->fd >= 0 && f->defrag_on_close) { + + /* Be friendly to btrfs: turn COW back on again now, + * and defragment the file. We won't write to the file + * ever again, hence remove all fragmentation, and + * reenable all the good bits COW usually provides + * (such as data checksumming). */ + + (void) chattr_fd(f->fd, false, FS_NOCOW_FL); + (void) btrfs_defrag_fd(f->fd); + } safe_close(f->fd); free(f->path); @@ -313,7 +322,7 @@ static int journal_file_verify_header(JournalFile *f) { } else if (state == STATE_ARCHIVED) return -ESHUTDOWN; else if (state != STATE_OFFLINE) { - log_debug("Journal file %s has unknown state %u.", f->path, state); + log_debug("Journal file %s has unknown state %i.", f->path, state); return -EBUSY; } } @@ -1953,11 +1962,12 @@ static int test_object_monotonic(JournalFile *f, uint64_t p, uint64_t needle) { return TEST_RIGHT; } -static inline int find_data_object_by_boot_id( +static int find_data_object_by_boot_id( JournalFile *f, sd_id128_t boot_id, Object **o, uint64_t *b) { + char t[sizeof("_BOOT_ID=")-1 + 32 + 1] = "_BOOT_ID="; sd_id128_to_string(boot_id, t + 9); @@ -2003,8 +2013,7 @@ void journal_file_reset_location(JournalFile *f) { f->current_xor_hash = 0; } -void journal_file_save_location(JournalFile *f, direction_t direction, Object *o, uint64_t offset) { - f->last_direction = direction; +void journal_file_save_location(JournalFile *f, Object *o, uint64_t offset) { f->location_type = LOCATION_SEEK; f->current_offset = offset; f->current_seqnum = le64toh(o->entry.seqnum); @@ -2407,7 +2416,7 @@ void journal_file_dump(JournalFile *f) { break; default: - printf("Type: unknown (%u)\n", o->object.type); + printf("Type: unknown (%i)\n", o->object.type); break; } @@ -2591,6 +2600,18 @@ int journal_file_open( goto fail; if (f->last_stat.st_size == 0 && f->writable) { + + /* Before we write anything, turn off COW logic. Given + * our write pattern that is quite unfriendly to COW + * file systems this should greatly improve + * performance on COW file systems, such as btrfs, at + * the expense of data integrity features (which + * shouldn't be too bad, given that we do our own + * checksumming). */ + r = chattr_fd(f->fd, true, FS_NOCOW_FL); + if (r < 0 && r != -ENOTTY) + log_warning_errno(r, "Failed to set file attributes: %m"); + /* 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 @@ -2601,7 +2622,7 @@ int journal_file_open( * attributes are not supported we'll just skip this, * and rely solely on mtime/atime/ctime of the file. */ - fd_setcrtime(f->fd, now(CLOCK_REALTIME)); + fd_setcrtime(f->fd, 0); #ifdef HAVE_GCRYPT /* Try to load the FSPRG state, and if we can't, then @@ -2808,6 +2829,8 @@ int journal_file_open_reliably( /* btrfs doesn't cope well with our write pattern and * fragments heavily. Let's defrag all files we rotate */ + + (void) chattr_path(p, false, FS_NOCOW_FL); (void) btrfs_defrag(p); log_warning("File %s corrupted or uncleanly shut down, renaming and replacing.", fname);