Mercurial > dovecot > original-hg > dovecot-1.2
changeset 6062:8341db7a1698 HEAD
Moved mailbox list index sync stamp checking and updating to
storage-specific code.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 18 Jul 2007 06:17:47 +0300 |
parents | f42deb78f0e7 |
children | dab02b1fc89d |
files | src/lib-storage/index/cydir/cydir-storage.c src/lib-storage/index/dbox/dbox-storage.c src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/maildir/maildir-storage.h 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/list/index-mailbox-list-sync.c src/lib-storage/list/index-mailbox-list.h src/lib-storage/mail-storage-private.h |
diffstat | 10 files changed, 132 insertions(+), 127 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/cydir/cydir-storage.c Wed Jul 18 04:17:13 2007 +0300 +++ b/src/lib-storage/index/cydir/cydir-storage.c Wed Jul 18 06:17:47 2007 +0300 @@ -425,6 +425,8 @@ index_storage_allow_new_keywords, index_storage_mailbox_close, index_storage_get_status, + NULL, + NULL, cydir_storage_sync_init, index_mailbox_sync_next, index_mailbox_sync_deinit,
--- a/src/lib-storage/index/dbox/dbox-storage.c Wed Jul 18 04:17:13 2007 +0300 +++ b/src/lib-storage/index/dbox/dbox-storage.c Wed Jul 18 06:17:47 2007 +0300 @@ -569,6 +569,8 @@ index_storage_allow_new_keywords, dbox_storage_close, index_storage_get_status, + NULL, + NULL, dbox_storage_sync_init, index_mailbox_sync_next, index_mailbox_sync_deinit,
--- a/src/lib-storage/index/maildir/maildir-storage.c Wed Jul 18 04:17:13 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.c Wed Jul 18 06:17:47 2007 +0300 @@ -270,6 +270,7 @@ } list->v.delete_mailbox = maildir_list_delete_mailbox; list->v.rename_mailbox = maildir_list_rename_mailbox; + storage->maildir_list_ext_id = (uint32_t)-1; MODULE_CONTEXT_SET_FULL(list, maildir_mailbox_list_module, storage, &storage->list_module_ctx); @@ -1053,6 +1054,8 @@ index_storage_allow_new_keywords, maildir_storage_mailbox_close, maildir_storage_get_status, + maildir_list_index_has_changed, + maildir_list_index_update_sync, maildir_storage_sync_init, index_mailbox_sync_next, index_mailbox_sync_deinit,
--- a/src/lib-storage/index/maildir/maildir-storage.h Wed Jul 18 04:17:13 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.h Wed Jul 18 06:17:47 2007 +0300 @@ -54,12 +54,18 @@ uint32_t cur_check_time, cur_mtime, cur_mtime_nsecs; }; +struct maildir_list_index_record { + uint32_t new_mtime, cur_mtime; +}; + struct maildir_storage { struct mail_storage storage; union mailbox_list_module_context list_module_ctx; const char *temp_prefix; + uint32_t maildir_list_ext_id; + unsigned int copy_with_hardlinks:1; unsigned int copy_preserve_filename:1; unsigned int save_size_in_filename:1;
--- a/src/lib-storage/index/maildir/maildir-sync-index.c Wed Jul 18 04:17:13 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-sync-index.c Wed Jul 18 06:17:47 2007 +0300 @@ -472,3 +472,100 @@ } return ret < 0 ? -1 : (full_rescan ? 0 : 1); } + +static unsigned int maildir_list_get_ext_id(struct maildir_storage *storage, + struct mail_index_view *view) +{ + if (storage->maildir_list_ext_id == (uint32_t)-1) { + storage->maildir_list_ext_id = + mail_index_ext_register(mail_index_view_get_index(view), + "maildir", 0, + sizeof(struct maildir_list_index_record), + sizeof(uint32_t)); + } + return storage->maildir_list_ext_id; +} + +int maildir_list_index_has_changed(struct mailbox *box, + struct mail_index_view *list_view, + uint32_t seq) +{ + struct maildir_mailbox *mbox = (struct maildir_mailbox *)box; + const struct maildir_list_index_record *rec; + const void *data; + const char *root_dir, *new_dir, *cur_dir; + struct stat st; + uint32_t ext_id; + + ext_id = maildir_list_get_ext_id(mbox->storage, list_view); + if (mail_index_lookup_ext(list_view, seq, ext_id, &data) <= 0) + return -1; + rec = data; + + if (rec == NULL || rec->new_mtime == 0 || rec->cur_mtime == 0) { + /* doesn't exist, not synced or dirty-synced */ + return 1; + } + + root_dir = mailbox_list_get_path(mail_storage_get_list(box->storage), + box->name, + MAILBOX_LIST_PATH_TYPE_MAILBOX); + + /* check if new/ changed */ + new_dir = t_strconcat(root_dir, "/new", NULL); + if (stat(new_dir, &st) < 0) { + mail_storage_set_critical(box->storage, + "stat(%s) failed: %m", new_dir); + return -1; + } + if (rec->new_mtime != st.st_mtime) + return 1; + + /* check if cur/ changed */ + cur_dir = t_strconcat(root_dir, "/cur", NULL); + if (stat(cur_dir, &st) < 0) { + mail_storage_set_critical(box->storage, + "stat(%s) failed: %m", cur_dir); + return -1; + } + if (rec->cur_mtime != st.st_mtime) + return 1; + return 0; +} + +int 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; + const struct maildir_index_header *mhdr = &mbox->maildir_hdr; + const struct maildir_list_index_record *old_rec; + struct maildir_list_index_record new_rec; + const void *data; + uint32_t ext_id; + + /* get the current record */ + list_view = mail_index_transaction_get_view(trans); + ext_id = maildir_list_get_ext_id(mbox->storage, list_view); + if (mail_index_lookup_ext(list_view, seq, ext_id, &data) <= 0) + return -1; + old_rec = data; + + memset(&new_rec, 0, sizeof(new_rec)); + if (mhdr->new_check_time <= mhdr->new_mtime + MAILDIR_SYNC_SECS || + mhdr->cur_check_time <= mhdr->cur_mtime + MAILDIR_SYNC_SECS) { + /* dirty, we need a refresh next time */ + } else { + new_rec.new_mtime = mhdr->new_mtime; + new_rec.cur_mtime = mhdr->cur_mtime; + } + + if (old_rec == NULL || + 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 Wed Jul 18 04:17:13 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-sync.h Wed Jul 18 06:17:47 2007 +0300 @@ -38,4 +38,11 @@ maildir_sync_get_keywords_sync_ctx(struct maildir_index_sync_context *ctx); void maildir_sync_notify(struct maildir_sync_context *ctx); +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); + #endif
--- a/src/lib-storage/index/mbox/mbox-storage.c Wed Jul 18 04:17:13 2007 +0300 +++ b/src/lib-storage/index/mbox/mbox-storage.c Wed Jul 18 06:17:47 2007 +0300 @@ -954,6 +954,8 @@ index_storage_allow_new_keywords, mbox_storage_mailbox_close, index_storage_get_status, + NULL, + NULL, mbox_storage_sync_init, index_mailbox_sync_next, index_mailbox_sync_deinit,
--- a/src/lib-storage/list/index-mailbox-list-sync.c Wed Jul 18 04:17:13 2007 +0300 +++ b/src/lib-storage/list/index-mailbox-list-sync.c Wed Jul 18 06:17:47 2007 +0300 @@ -82,82 +82,6 @@ } static int -index_list_lookup_stamps(struct index_mailbox_list *ilist, - struct mail_index_view *view, uint32_t seq, - time_t *new_stamp_r, time_t *cur_stamp_r, - uint8_t *dirty_flags_r) -{ - const void *data; - - if (mail_index_lookup_ext(view, seq, ilist->eid_new_sync_stamp, - &data) <= 0) - return -1; - *new_stamp_r = data == NULL ? 0 : *(const uint32_t *)data; - - if (mail_index_lookup_ext(view, seq, ilist->eid_cur_sync_stamp, - &data) <= 0) - return -1; - *cur_stamp_r = data == NULL ? 0 : *(const uint32_t *)data; - - if (mail_index_lookup_ext(view, seq, ilist->eid_dirty_flags, - &data) <= 0) - return -1; - *dirty_flags_r = data == NULL ? 0 : *(const uint8_t *)data; - return 0; -} - -static int -index_list_has_mailbox_changed(struct mailbox *box, - struct mail_index_view *view, uint32_t seq) -{ - /* FIXME: this function shouldn't be maildir-specific */ - struct index_mailbox_list *ilist; - struct mailbox_list *list; - const char *root_dir, *new_dir, *cur_dir; - struct stat st; - time_t idx_new_stamp, idx_cur_stamp, max_stamp; - uint8_t idx_dirty_flags; - - list = mail_storage_get_list(box->storage); - ilist = INDEX_LIST_CONTEXT(list); - - if (index_list_lookup_stamps(ilist, view, seq, &idx_new_stamp, - &idx_cur_stamp, &idx_dirty_flags) < 0) - return -1; - - /* if there are dirty flags and the timestamp is old enough, - do a resync in any case */ - max_stamp = I_MAX(idx_new_stamp, idx_cur_stamp); - if (idx_dirty_flags != 0 && - ioloop_time - max_stamp >= MAILDIR_SYNC_SECS) - return 1; - - /* check if new/ changed */ - root_dir = mailbox_list_get_path(list, box->name, - MAILBOX_LIST_PATH_TYPE_MAILBOX); - new_dir = t_strconcat(root_dir, "/new", NULL); - if (stat(new_dir, &st) < 0) { - mail_storage_set_critical(box->storage, - "stat(%s) failed: %m", new_dir); - return -1; - } - if (idx_new_stamp != st.st_mtime) - return 1; - - /* check if cur/ changed */ - cur_dir = t_strconcat(root_dir, "/cur", NULL); - if (stat(cur_dir, &st) < 0) { - mail_storage_set_critical(box->storage, - "stat(%s) failed: %m", cur_dir); - return -1; - } - if (idx_cur_stamp != st.st_mtime) - return 1; - - return 0; -} - -static int index_list_mailbox_open_unchanged_view(struct mailbox *box, struct mail_index_view **view_r, uint32_t *seq_r) @@ -193,7 +117,7 @@ } t_push(); - ret = index_list_has_mailbox_changed(box, view, seq); + ret = box->v.list_index_has_changed(box, view, seq); t_pop(); if (ret != 0) { /* error / mailbox has changed. we'll need to sync it. */ @@ -291,42 +215,6 @@ } static int -index_list_update_sync_stamps(struct index_mailbox_list *ilist, - struct mailbox *box, - struct mail_index_transaction *trans, - struct mail_index_view *view, uint32_t seq) -{ - struct index_mailbox *ibox = (struct index_mailbox *)box; - const struct mail_index_header *hdr; - time_t hdr_new_stamp, hdr_cur_stamp; - time_t idx_new_stamp, idx_cur_stamp; - uint8_t hdr_dirty_flags, idx_dirty_flags; - - hdr = mail_index_get_header(ibox->view); - hdr_cur_stamp = hdr->sync_stamp; - hdr_new_stamp = hdr->sync_size & 0xffffffff; - hdr_dirty_flags = hdr->sync_size >> 32; - - if (index_list_lookup_stamps(ilist, view, seq, &idx_new_stamp, - &idx_cur_stamp, &idx_dirty_flags) < 0) - return -1; - - if (idx_new_stamp != hdr_new_stamp) { - mail_index_update_ext(trans, seq, ilist->eid_new_sync_stamp, - &hdr_new_stamp, NULL); - } - if (idx_cur_stamp != hdr_cur_stamp) { - mail_index_update_ext(trans, seq, ilist->eid_cur_sync_stamp, - &hdr_cur_stamp, NULL); - } - if (idx_dirty_flags != hdr_dirty_flags) { - mail_index_update_ext(trans, seq, ilist->eid_dirty_flags, - &hdr_dirty_flags, NULL); - } - return 0; -} - -static int index_list_update(struct index_mailbox_list *ilist, struct mailbox *box, struct mail_index_view *view, uint32_t seq, const struct mailbox_status *status) @@ -356,7 +244,8 @@ counter_p, NULL); } } - if (index_list_update_sync_stamps(ilist, box, trans, view, seq) < 0) + + if (box->v.list_index_update_sync(box, trans, seq) < 0) ret = -1; if (ret <= 0) { mail_index_transaction_rollback(&trans); @@ -498,17 +387,6 @@ index_list_map[i].name, 0, sizeof(uint32_t), sizeof(uint32_t)); } - - /* FIXME: maildir-only: */ - ilist->eid_cur_sync_stamp = - mail_index_ext_register(ilist->mail_index, "sync-cur", 0, - sizeof(uint32_t), sizeof(uint32_t)); - ilist->eid_new_sync_stamp = - mail_index_ext_register(ilist->mail_index, "sync-new", 0, - sizeof(uint32_t), sizeof(uint32_t)); - ilist->eid_dirty_flags = - mail_index_ext_register(ilist->mail_index, "sync-dirty", 0, - sizeof(uint8_t), sizeof(uint8_t)); } void index_mailbox_list_sync_init(void)
--- a/src/lib-storage/list/index-mailbox-list.h Wed Jul 18 04:17:13 2007 +0300 +++ b/src/lib-storage/list/index-mailbox-list.h Wed Jul 18 06:17:47 2007 +0300 @@ -19,8 +19,6 @@ uint32_t eid_messages, eid_unseen, eid_recent; uint32_t eid_uid_validity, eid_uidnext; - - uint32_t eid_cur_sync_stamp, eid_new_sync_stamp, eid_dirty_flags; }; struct index_mailbox_list_iterate_context {
--- a/src/lib-storage/mail-storage-private.h Wed Jul 18 04:17:13 2007 +0300 +++ b/src/lib-storage/mail-storage-private.h Wed Jul 18 06:17:47 2007 +0300 @@ -79,6 +79,16 @@ int (*get_status)(struct mailbox *box, enum mailbox_status_items items, struct mailbox_status *status); + /* Lookup sync extension record and figure out if it mailbox has + changed since. Returns 1 = yes, 0 = no, -1 = error. */ + 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); + struct mailbox_sync_context * (*sync_init)(struct mailbox *box, enum mailbox_sync_flags flags);