From: Timo Sirainen Date: Mon, 11 Aug 2003 01:56:37 +0000 (+0300) Subject: Save sync stamp in index header rather than in file's mtime. X-Git-Tag: 1.1.alpha1~4428 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e6d35af29202a78abd9c6a8412f340693b36a948;p=thirdparty%2Fdovecot%2Fcore.git Save sync stamp in index header rather than in file's mtime. --HG-- branch : HEAD --- diff --git a/src/lib-index/mail-cache.c b/src/lib-index/mail-cache.c index 51baac7f18..ee8fd56b1e 100644 --- a/src/lib-index/mail-cache.c +++ b/src/lib-index/mail-cache.c @@ -360,7 +360,7 @@ static void mail_index_clear_cache_offsets(struct mail_index *index) { struct mail_index_record *rec; - index->file_sync_stamp = ioloop_time-61; + index->sync_stamp = 0; rec = index->lookup(index, 1); while (rec != NULL) { diff --git a/src/lib-index/mail-index-open.c b/src/lib-index/mail-index-open.c index 13776e3c45..87a53f3625 100644 --- a/src/lib-index/mail-index-open.c +++ b/src/lib-index/mail-index-open.c @@ -30,7 +30,7 @@ static int mail_index_open_init(struct mail_index *index, (hdr->flags & MAIL_INDEX_FLAG_MAILDIR_NEW) != 0; if ((hdr->flags & MAIL_INDEX_HDR_FLAG_DIRTY_MESSAGES) != 0) - index->next_dirty_flush = ioloop_time; + index->next_dirty_flags_flush = ioloop_time; /* update \Recent message counters */ if ((flags & MAIL_INDEX_OPEN_FLAG_UPDATE_RECENT) != 0 && diff --git a/src/lib-index/mail-index.c b/src/lib-index/mail-index.c index b6b80f7e4d..60beb6deca 100644 --- a/src/lib-index/mail-index.c +++ b/src/lib-index/mail-index.c @@ -13,7 +13,6 @@ #include #include -#include static int mmap_verify(struct mail_index *index) { @@ -76,6 +75,7 @@ static int mmap_verify(struct mail_index *index) } index->sync_id = hdr->sync_id; + index->sync_stamp = hdr->sync_stamp; index->mmap_used_length = hdr->used_file_size; return TRUE; } @@ -225,17 +225,6 @@ static int mail_index_sync_file(struct mail_index *index) return !failed; } -static void mail_index_update_timestamp(struct mail_index *index) -{ - struct utimbuf ut; - - /* keep index's modify stamp same as the sync file's stamp */ - ut.actime = ioloop_time; - ut.modtime = index->file_sync_stamp; - if (utime(index->filepath, &ut) < 0) - index_set_syscall_error(index, "utime()"); -} - int mail_index_fmdatasync(struct mail_index *index, size_t size) { i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE); @@ -451,6 +440,9 @@ static int mail_index_lock_full(struct mail_index *index, keep_fsck = (index->set_flags & MAIL_INDEX_HDR_FLAG_FSCK) != 0; mail_index_update_header_changes(index); + if (index->sync_dirty_stamp == 0) + index->header->sync_stamp = index->sync_stamp; + /* remove the FSCK flag only after successful fsync() */ if (mail_index_sync_file(index) && !keep_fsck) { index->header->flags &= ~MAIL_INDEX_HDR_FLAG_FSCK; @@ -462,8 +454,6 @@ static int mail_index_lock_full(struct mail_index *index, index_set_syscall_error(index, "msync()"); } } - - mail_index_update_timestamp(index); } if (lock_type == MAIL_LOCK_UNLOCK) diff --git a/src/lib-index/mail-index.h b/src/lib-index/mail-index.h index 22e8c44e48..5d171a09db 100644 --- a/src/lib-index/mail-index.h +++ b/src/lib-index/mail-index.h @@ -124,6 +124,8 @@ struct mail_index_header { /* these UIDs may not exist and may not even be unseen */ uint32_t first_unseen_uid_lowwater; uint32_t first_deleted_uid_lowwater; + + uint32_t sync_stamp; }; struct mail_index_record { @@ -293,7 +295,6 @@ struct mail_index { /* last maildir sync: */ time_t last_new_mtime, last_uidlist_mtime; - time_t maildir_cur_dirty, next_dirty_flush; int maildir_lock_fd; pool_t new_filename_pool; struct hash_table *new_filenames; @@ -309,7 +310,8 @@ struct mail_index { size_t header_size; enum mail_lock_type lock_type; - time_t file_sync_stamp; + time_t sync_stamp, sync_dirty_stamp; + time_t next_dirty_flags_flush; unsigned int first_recent_uid; mail_lock_notify_callback_t *lock_notify_cb; diff --git a/src/lib-index/maildir/maildir-expunge.c b/src/lib-index/maildir/maildir-expunge.c index f23de9b299..73711273c2 100644 --- a/src/lib-index/maildir/maildir-expunge.c +++ b/src/lib-index/maildir/maildir-expunge.c @@ -39,12 +39,12 @@ int maildir_expunge_mail(struct mail_index *index, /* if we're in out-of-space condition, reset it since we'll probably have enough space now. */ index->maildir_keep_new = FALSE; - if (index->next_dirty_flush != 0) - index->next_dirty_flush = ioloop_time; + if (index->next_dirty_flags_flush != 0) + index->next_dirty_flags_flush = ioloop_time; /* cur/ was updated, set it dirty-synced */ - index->maildir_cur_dirty = ioloop_time; - index->file_sync_stamp = ioloop_time; + index->sync_dirty_stamp = ioloop_time; + index->sync_stamp = ioloop_time; } return TRUE; } diff --git a/src/lib-index/maildir/maildir-sync.c b/src/lib-index/maildir/maildir-sync.c index 29d869cc2c..0bcc30b5bb 100644 --- a/src/lib-index/maildir/maildir-sync.c +++ b/src/lib-index/maildir/maildir-sync.c @@ -1084,14 +1084,6 @@ static int maildir_index_sync_context(struct maildir_sync_context *ctx, if (!maildir_try_flush_dirty_flags(ctx->index, FALSE)) return FALSE; - if (index->fd != -1) { - /* FIXME: file_sync_stamp should be in index file's headers. - it should also contain maildir_cur_dirty. */ - if (fstat(index->fd, &st) < 0) - return index_set_syscall_error(index, "fstat()"); - index->file_sync_stamp = st.st_mtime; - } - if (stat(ctx->new_dir, &st) < 0) { index_file_set_syscall_error(index, ctx->new_dir, "stat()"); return FALSE; @@ -1110,9 +1102,17 @@ static int maildir_index_sync_context(struct maildir_sync_context *ctx, return FALSE; } - if (cur_mtime != index->file_sync_stamp || - (index->maildir_cur_dirty != 0 && - index->maildir_cur_dirty < ioloop_time - MAILDIR_SYNC_SECS)) { + if (cur_mtime != index->sync_stamp && + index->sync_dirty_stamp == 0) { + /* update index->sync_stamp from header. + set_lock() does it automatically. */ + if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE)) + return FALSE; + } + + if (cur_mtime != index->sync_stamp || + (index->sync_dirty_stamp != 0 && + index->sync_dirty_stamp < ioloop_time - MAILDIR_SYNC_SECS)) { /* cur/ changed, or delayed cur/ check */ if (changes != NULL) *changes = TRUE; @@ -1150,20 +1150,20 @@ static int maildir_index_sync_context(struct maildir_sync_context *ctx, index->header->flags &= ~MAIL_INDEX_FLAG_MAILDIR_NEW; } - if (index->maildir_cur_dirty == 0 || - index->maildir_cur_dirty < ioloop_time - MAILDIR_SYNC_SECS) { + if (index->sync_dirty_stamp == 0 || + index->sync_dirty_stamp < ioloop_time - MAILDIR_SYNC_SECS) { if (cur_mtime >= ioloop_time - MAILDIR_SYNC_SECS) - index->maildir_cur_dirty = cur_mtime; + index->sync_dirty_stamp = cur_mtime; else if (ctx->new_count == 0 || !ctx->new_mails_cur) - index->maildir_cur_dirty = 0; + index->sync_dirty_stamp = 0; else { /* uidlist is locked, wait for a while before trying again */ - index->maildir_cur_dirty = ioloop_time; + index->sync_dirty_stamp = ioloop_time; } } - index->file_sync_stamp = cur_mtime; + index->sync_stamp = cur_mtime; if (ctx->new_dent == NULL && (ctx->new_count == 0 || !ctx->new_mails_new)) index->last_new_mtime = new_mtime; @@ -1268,8 +1268,8 @@ static int maildir_index_sync_context_readonly(struct maildir_sync_context *ctx) return FALSE; } - cur_changed = st.st_mtime != index->file_sync_stamp || - index->maildir_cur_dirty != 0; + cur_changed = st.st_mtime != index->sync_stamp || + index->sync_dirty_stamp != 0; } if (!cur_changed) { diff --git a/src/lib-index/maildir/maildir-update-flags.c b/src/lib-index/maildir/maildir-update-flags.c index d48296c45d..dff013af2e 100644 --- a/src/lib-index/maildir/maildir-update-flags.c +++ b/src/lib-index/maildir/maildir-update-flags.c @@ -60,8 +60,8 @@ int maildir_try_flush_dirty_flags(struct mail_index *index, int force) struct mail_index_record *rec; int ret, dirty = FALSE; - if (index->next_dirty_flush == 0 || - (ioloop_time < index->next_dirty_flush && !force)) + if (index->next_dirty_flags_flush == 0 || + (ioloop_time < index->next_dirty_flags_flush && !force)) return TRUE; if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE)) @@ -91,9 +91,9 @@ int maildir_try_flush_dirty_flags(struct mail_index *index, int force) if (!dirty) { index->header->flags &= ~MAIL_INDEX_HDR_FLAG_DIRTY_MESSAGES; - index->next_dirty_flush = 0; + index->next_dirty_flags_flush = 0; } else { - index->next_dirty_flush = + index->next_dirty_flags_flush = ioloop_time + MAILDIR_DIRTY_FLUSH_TIMEOUT; } @@ -177,8 +177,8 @@ static int do_rename(struct mail_index *index, const char *path, void *context) } /* cur/ was updated, set it dirty-synced */ - index->file_sync_stamp = ioloop_time; - index->maildir_cur_dirty = ioloop_time; + index->sync_stamp = ioloop_time; + index->sync_dirty_stamp = ioloop_time; ctx->found = TRUE; return 1; } @@ -218,7 +218,7 @@ int maildir_index_update_flags(struct mail_index *index, MAIL_INDEX_HDR_FLAG_DIRTY_MESSAGES; } - index->next_dirty_flush = + index->next_dirty_flags_flush = ioloop_time + MAILDIR_DIRTY_FLUSH_TIMEOUT; } else if (ctx.new_fname != NULL) { maildir_index_update_filename(index, rec->uid, diff --git a/src/lib-index/mbox/mbox-rewrite.c b/src/lib-index/mbox/mbox-rewrite.c index 6e2c8a2685..1e48e13633 100644 --- a/src/lib-index/mbox/mbox-rewrite.c +++ b/src/lib-index/mbox/mbox-rewrite.c @@ -551,7 +551,7 @@ static int dirty_flush(struct mail_index *index, uoff_t dirty_offset, /* All ok. Just make sure the timestamps of index and mbox differ, so index will be updated at next sync */ - index->file_sync_stamp = ioloop_time-61; + index->sync_stamp = 0; if (o_stream_seek(output, 0) < 0) { mbox_set_syscall_error(index, "o_stream_seek()"); diff --git a/src/lib-index/mbox/mbox-sync.c b/src/lib-index/mbox/mbox-sync.c index f83634c644..12a2ca5a74 100644 --- a/src/lib-index/mbox/mbox-sync.c +++ b/src/lib-index/mbox/mbox-sync.c @@ -69,7 +69,6 @@ int mbox_index_sync(struct mail_index *index, int minimal_sync __attr_unused__, enum mail_lock_type data_lock_type, int *changes) { struct stat st; - time_t index_mtime; uoff_t filesize; int count, fd; @@ -90,15 +89,6 @@ int mbox_index_sync(struct mail_index *index, int minimal_sync __attr_unused__, i_assert(index->lock_type != MAIL_LOCK_SHARED); - if (index->fd == -1) { - /* anon-mmaped */ - index_mtime = index->file_sync_stamp; - } else { - if (fstat(index->fd, &st) < 0) - return index_set_syscall_error(index, "fstat()"); - index_mtime = st.st_mtime; - } - count = 0; while (stat(index->mailbox_path, &st) < 0) { if (errno != ENOENT || ++count == 3) @@ -125,33 +115,28 @@ int mbox_index_sync(struct mail_index *index, int minimal_sync __attr_unused__, mbox_file_close_fd(index); } - if (index_mtime != st.st_mtime || index->mbox_size != filesize) { + if (index->mbox_sync_counter == 0) { + /* first sync, get expected mbox size */ + index->mbox_size = get_indexed_mbox_size(index); + } + + if (index->sync_stamp != st.st_mtime || index->mbox_size != filesize) { mbox_file_close_stream(index); - index->mbox_size = get_indexed_mbox_size(index); - if (index->file_sync_stamp == 0 && - index->mbox_size == filesize) { - /* just opened the mailbox, and the file size is same - as we expected. don't bother checking it any - further. */ - } else { - if (changes != NULL) - *changes = TRUE; - - if (!mbox_lock_and_sync_full(index, data_lock_type)) - return FALSE; + if (changes != NULL) + *changes = TRUE; - if ((index->set_flags & - MAIL_INDEX_HDR_FLAG_REBUILD) != 0) { - /* uidvalidity probably changed, rebuild */ - if (!index->rebuild(index)) - return FALSE; - } + if (!mbox_lock_and_sync_full(index, data_lock_type)) + return FALSE; - index->mbox_size = filesize; + if ((index->set_flags & MAIL_INDEX_HDR_FLAG_REBUILD) != 0) { + /* uidvalidity probably changed, rebuild */ + if (!index->rebuild(index)) + return FALSE; } - index->file_sync_stamp = st.st_mtime; + index->mbox_size = filesize; + index->sync_stamp = st.st_mtime; } /* we need some index lock to be able to lock mbox */