Mercurial > dovecot > core-2.2
changeset 12646:87f84a76fb1e
lib-storage: Return STATUS replies from mailbox list index only when it's fully up-to-date.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 09 Feb 2011 01:31:40 +0200 |
parents | d3d5f104ca40 |
children | f02d429ff6bd |
files | src/lib-storage/index/cydir/cydir-storage.c src/lib-storage/index/dbox-multi/mdbox-storage.c src/lib-storage/index/dbox-single/sdbox-storage.c src/lib-storage/index/index-storage.h src/lib-storage/index/index-sync.c src/lib-storage/index/maildir/maildir-sync-index.c src/lib-storage/index/maildir/maildir-sync.h src/lib-storage/index/mbox/mbox-storage.c src/lib-storage/index/raw/raw-storage.c src/lib-storage/list/index-mailbox-list-status.c src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.c |
diffstat | 12 files changed, 154 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/cydir/cydir-storage.c Tue Feb 08 22:54:14 2011 +0200 +++ b/src/lib-storage/index/cydir/cydir-storage.c Wed Feb 09 01:31:40 2011 +0200 @@ -146,8 +146,8 @@ index_storage_mailbox_rename, index_storage_get_status, NULL, - NULL, - NULL, + index_storage_list_index_has_changed, + index_storage_list_index_update_sync, cydir_storage_sync_init, index_mailbox_sync_next, index_mailbox_sync_deinit,
--- a/src/lib-storage/index/dbox-multi/mdbox-storage.c Tue Feb 08 22:54:14 2011 +0200 +++ b/src/lib-storage/index/dbox-multi/mdbox-storage.c Wed Feb 09 01:31:40 2011 +0200 @@ -420,8 +420,8 @@ index_storage_mailbox_rename, index_storage_get_status, mdbox_mailbox_get_metadata, - NULL, - NULL, + index_storage_list_index_has_changed, + index_storage_list_index_update_sync, mdbox_storage_sync_init, index_mailbox_sync_next, index_mailbox_sync_deinit,
--- a/src/lib-storage/index/dbox-single/sdbox-storage.c Tue Feb 08 22:54:14 2011 +0200 +++ b/src/lib-storage/index/dbox-single/sdbox-storage.c Wed Feb 09 01:31:40 2011 +0200 @@ -378,8 +378,8 @@ index_storage_mailbox_rename, index_storage_get_status, sdbox_mailbox_get_metadata, - NULL, - NULL, + index_storage_list_index_has_changed, + index_storage_list_index_update_sync, sdbox_storage_sync_init, index_mailbox_sync_next, index_mailbox_sync_deinit,
--- a/src/lib-storage/index/index-storage.h Tue Feb 08 22:54:14 2011 +0200 +++ b/src/lib-storage/index/index-storage.h Wed Feb 09 01:31:40 2011 +0200 @@ -138,4 +138,11 @@ bool index_keyword_array_cmp(const ARRAY_TYPE(keyword_indexes) *k1, const ARRAY_TYPE(keyword_indexes) *k2); +int index_storage_list_index_has_changed(struct mailbox *box, + struct mail_index_view *list_view, + uint32_t seq); +void index_storage_list_index_update_sync(struct mailbox *box, + struct mail_index_transaction *trans, + uint32_t seq); + #endif
--- a/src/lib-storage/index/index-sync.c Tue Feb 08 22:54:14 2011 +0200 +++ b/src/lib-storage/index/index-sync.c Wed Feb 09 01:31:40 2011 +0200 @@ -6,6 +6,11 @@ #include "array.h" #include "index-sync-private.h" +struct index_storage_list_index_record { + uint32_t size; + uint32_t mtime; +}; + enum mail_index_sync_flags index_storage_get_sync_flags(struct mailbox *box) { enum mail_index_sync_flags sync_flags = 0; @@ -430,3 +435,99 @@ ret |= MAILBOX_SYNC_TYPE_FLAGS; return ret; } + +static unsigned int +index_storage_list_get_ext_id(struct mail_storage *storage, + struct mail_index_view *view) +{ + if (storage->list_sync_ext_id == (uint32_t)-1) { + storage->list_sync_ext_id = + mail_index_ext_register(mail_index_view_get_index(view), + "index sync", 0, + sizeof(struct index_storage_list_index_record), + sizeof(uint32_t)); + } + return storage->list_sync_ext_id; +} + +int index_storage_list_index_has_changed(struct mailbox *box, + struct mail_index_view *list_view, + uint32_t seq) +{ + const struct index_storage_list_index_record *rec; + const void *data; + const char *dir, *path; + struct stat st; + uint32_t ext_id; + bool expunged; + + if (mail_index_is_in_memory(mail_index_view_get_index(list_view))) + return 1; + + ext_id = index_storage_list_get_ext_id(box->storage, list_view); + mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged); + rec = data; + + if (rec == NULL || expunged || rec->size == 0 || rec->mtime == 0) { + /* doesn't exist / not synced */ + return 1; + } + + dir = mailbox_list_get_path(box->list, box->name, + MAILBOX_LIST_PATH_TYPE_INDEX); + path = t_strconcat(dir, "/", box->index_prefix, ".log", NULL); + if (stat(path, &st) < 0) { + mail_storage_set_critical(box->storage, + "stat(%s) failed: %m", path); + return -1; + } + if (rec->size != (st.st_size & 0xffffffffU) || + rec->mtime != (st.st_mtime & 0xffffffffU)) + return 1; + return 0; +} + +void index_storage_list_index_update_sync(struct mailbox *box, + struct mail_index_transaction *trans, + uint32_t seq) +{ + struct mail_index_view *list_view; + const struct index_storage_list_index_record *old_rec; + struct index_storage_list_index_record new_rec; + const void *data; + const char *dir, *path; + struct stat st; + uint32_t ext_id; + bool expunged; + + list_view = mail_index_transaction_get_view(trans); + if (mail_index_is_in_memory(mail_index_view_get_index(list_view))) + return; + + /* get the current record */ + ext_id = index_storage_list_get_ext_id(box->storage, list_view); + mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged); + if (expunged) + return; + old_rec = data; + + dir = mailbox_list_get_path(box->list, box->name, + MAILBOX_LIST_PATH_TYPE_INDEX); + path = t_strconcat(dir, "/", box->index_prefix, ".log", NULL); + if (stat(path, &st) < 0) { + mail_storage_set_critical(box->storage, + "stat(%s) failed: %m", path); + return; + } + + memset(&new_rec, 0, sizeof(new_rec)); + new_rec.size = st.st_size & 0xffffffffU; + new_rec.mtime = st.st_mtime & 0xffffffffU; + + if (old_rec == NULL || + memcmp(old_rec, &new_rec, sizeof(*old_rec)) != 0) { + mail_index_update_ext(trans, seq, + box->storage->list_sync_ext_id, + &new_rec, NULL); + } +}
--- a/src/lib-storage/index/maildir/maildir-sync-index.c Tue Feb 08 22:54:14 2011 +0200 +++ b/src/lib-storage/index/maildir/maildir-sync-index.c Wed Feb 09 01:31:40 2011 +0200 @@ -711,6 +711,9 @@ uint32_t ext_id; bool expunged; + if (mbox->storage->set->maildir_very_dirty_syncs) + return index_storage_list_index_has_changed(box, list_view, seq); + ext_id = maildir_list_get_ext_id(mbox->storage, list_view); mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged); rec = data; @@ -746,9 +749,9 @@ return 0; } -int maildir_list_index_update_sync(struct mailbox *box, - struct mail_index_transaction *trans, - uint32_t seq) +void maildir_list_index_update_sync(struct mailbox *box, + struct mail_index_transaction *trans, + uint32_t seq) { struct maildir_mailbox *mbox = (struct maildir_mailbox *)box; struct mail_index_view *list_view; @@ -759,12 +762,17 @@ uint32_t ext_id; bool expunged; + if (mbox->storage->set->maildir_very_dirty_syncs) { + index_storage_list_index_update_sync(box, trans, seq); + return; + } + /* get the current record */ list_view = mail_index_transaction_get_view(trans); ext_id = maildir_list_get_ext_id(mbox->storage, list_view); mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged); if (expunged) - return 0; + return; old_rec = data; memset(&new_rec, 0, sizeof(new_rec)); @@ -777,10 +785,9 @@ } if (old_rec == NULL || - memcmp(old_rec, &new_rec, sizeof(old_rec)) != 0) { + memcmp(old_rec, &new_rec, sizeof(*old_rec)) != 0) { mail_index_update_ext(trans, seq, mbox->storage->maildir_list_ext_id, &new_rec, NULL); } - return 0; }
--- a/src/lib-storage/index/maildir/maildir-sync.h Tue Feb 08 22:54:14 2011 +0200 +++ b/src/lib-storage/index/maildir/maildir-sync.h Wed Feb 09 01:31:40 2011 +0200 @@ -50,8 +50,8 @@ int maildir_list_index_has_changed(struct mailbox *box, struct mail_index_view *list_view, uint32_t seq); -int maildir_list_index_update_sync(struct mailbox *box, - struct mail_index_transaction *trans, - uint32_t seq); +void maildir_list_index_update_sync(struct mailbox *box, + struct mail_index_transaction *trans, + uint32_t seq); #endif
--- a/src/lib-storage/index/mbox/mbox-storage.c Tue Feb 08 22:54:14 2011 +0200 +++ b/src/lib-storage/index/mbox/mbox-storage.c Wed Feb 09 01:31:40 2011 +0200 @@ -764,8 +764,8 @@ index_storage_mailbox_rename, index_storage_get_status, mbox_mailbox_get_metadata, - NULL, - NULL, + index_storage_list_index_has_changed, + index_storage_list_index_update_sync, mbox_storage_sync_init, index_mailbox_sync_next, index_mailbox_sync_deinit,
--- a/src/lib-storage/index/raw/raw-storage.c Tue Feb 08 22:54:14 2011 +0200 +++ b/src/lib-storage/index/raw/raw-storage.c Wed Feb 09 01:31:40 2011 +0200 @@ -146,8 +146,8 @@ index_storage_mailbox_rename, index_storage_get_status, NULL, - NULL, - NULL, + index_storage_list_index_has_changed, + index_storage_list_index_update_sync, raw_storage_sync_init, index_mailbox_sync_next, index_mailbox_sync_deinit,
--- a/src/lib-storage/list/index-mailbox-list-status.c Tue Feb 08 22:54:14 2011 +0200 +++ b/src/lib-storage/list/index-mailbox-list-status.c Wed Feb 09 01:31:40 2011 +0200 @@ -27,6 +27,7 @@ struct index_mailbox_node *node; struct mail_index_view *view; uint32_t seq; + int ret; if (index_mailbox_list_refresh(box->list) < 0) return -1; @@ -40,9 +41,17 @@ view = mail_index_view_open(ilist->index); if (!mail_index_lookup_seq(view, node->uid, &seq)) { /* our in-memory tree is out of sync */ + ret = 1; + } else T_BEGIN { + ret = box->v.list_index_has_changed == NULL ? 0 : + box->v.list_index_has_changed(box, view, seq); + } T_END; + + if (ret != 0) { + /* error / mailbox has changed. we'll need to sync it. */ index_mailbox_list_refresh_later(box->list); mail_index_view_close(&view); - return 0; + return ret < 0 ? -1 : 0; } *view_r = view; @@ -221,6 +230,9 @@ &status->highest_modseq, NULL); } + if (box->v.list_index_update_sync != NULL) + box->v.list_index_update_sync(box, trans, seq); + return mail_index_transaction_commit_full(&trans, &result); } @@ -280,7 +292,7 @@ sizeof(uint32_t)); ilist->hmodseq_ext_id = - mail_index_ext_register(ilist->index, "msgs", 0, + mail_index_ext_register(ilist->index, "hmodseq", 0, sizeof(uint64_t), sizeof(uint64_t)); }
--- a/src/lib-storage/mail-storage-private.h Tue Feb 08 22:54:14 2011 +0200 +++ b/src/lib-storage/mail-storage-private.h Wed Feb 09 01:31:40 2011 +0200 @@ -85,6 +85,7 @@ struct mail_user *user; const char *temp_path_prefix; const struct mail_storage_settings *set; + uint32_t list_sync_ext_id; enum mail_storage_flags flags; @@ -128,10 +129,10 @@ int (*list_index_has_changed)(struct mailbox *box, struct mail_index_view *list_view, uint32_t seq); - /* Update the sync extension record. Returns 0 = ok, -1 = error. */ - int (*list_index_update_sync)(struct mailbox *box, - struct mail_index_transaction *trans, - uint32_t seq); + /* Update the sync extension record. */ + void (*list_index_update_sync)(struct mailbox *box, + struct mail_index_transaction *trans, + uint32_t seq); struct mailbox_sync_context * (*sync_init)(struct mailbox *box,
--- a/src/lib-storage/mail-storage.c Tue Feb 08 22:54:14 2011 +0200 +++ b/src/lib-storage/mail-storage.c Wed Feb 09 01:31:40 2011 +0200 @@ -349,6 +349,7 @@ storage->user = ns->user; storage->set = ns->mail_set; storage->flags = flags; + storage->list_sync_ext_id = (uint32_t)-1; p_array_init(&storage->module_contexts, storage->pool, 5); if (storage->v.create != NULL &&