]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
maildir: When saving messages, in some race conditions we might have written a duplic...
authorTimo Sirainen <tss@iki.fi>
Mon, 13 Apr 2009 22:23:37 +0000 (18:23 -0400)
committerTimo Sirainen <tss@iki.fi>
Mon, 13 Apr 2009 22:23:37 +0000 (18:23 -0400)
--HG--
branch : HEAD

src/lib-index/mail-index.c
src/lib-index/mail-index.h
src/lib-storage/index/maildir/maildir-uidlist.c

index 9fdd5c46df347881ebda3aa625c3360f9d19309d..d00d08574b7e72ff994ac173672bc9ca45bdf81b 100644 (file)
@@ -555,6 +555,11 @@ int mail_index_set_error(struct mail_index *index, const char *fmt, ...)
        return -1;
 }
 
+bool mail_index_is_in_memory(struct mail_index *index)
+{
+       return MAIL_INDEX_IS_IN_MEMORY(index);
+}
+
 int mail_index_move_to_memory(struct mail_index *index)
 {
        struct mail_index_map *map;
index fa25f9e3d9f5601ee95a4a612e4e5fc64edc51af..1ab8090797c8ae0079205dba08f1b95ef9486afc 100644 (file)
@@ -206,6 +206,8 @@ int mail_index_open_or_create(struct mail_index *index,
                              enum file_lock_method lock_method);
 void mail_index_close(struct mail_index *index);
 
+/* Returns TRUE if index is currently in memory. */
+bool mail_index_is_in_memory(struct mail_index *index);
 /* Move the index into memory. Returns 0 if ok, -1 if error occurred. */
 int mail_index_move_to_memory(struct mail_index *index);
 /* Returns TRUE if index is currently in memory. */
index b8bddef275d5937dddd98f555912f61d3cd5eea3..5f8d128a2b654e47a3264909d9fb9414f4a5ec42 100644 (file)
@@ -820,10 +820,14 @@ int maildir_uidlist_refresh(struct maildir_uidlist *uidlist)
 int maildir_uidlist_refresh_fast_init(struct maildir_uidlist *uidlist)
 {
        const struct maildir_index_header *mhdr = &uidlist->mbox->maildir_hdr;
+       struct mail_index *index = uidlist->mbox->ibox.index;
+       struct mail_index_view *view;
        const struct mail_index_header *hdr;
        struct stat st;
        int ret;
 
+       i_assert(UIDLIST_IS_LOCKED(uidlist));
+
        if (uidlist->fd != -1)
                return maildir_uidlist_refresh(uidlist);
 
@@ -832,12 +836,17 @@ int maildir_uidlist_refresh_fast_init(struct maildir_uidlist *uidlist)
 
        if (st.st_size == mhdr->uidlist_size &&
            st.st_mtime == (time_t)mhdr->uidlist_mtime &&
-           ST_NTIMES_EQUAL(ST_MTIME_NSEC(st), mhdr->uidlist_mtime_nsecs)) {
-               /* index is up-to-date */
-               hdr = mail_index_get_header(uidlist->mbox->ibox.view);
+           ST_NTIMES_EQUAL(ST_MTIME_NSEC(st), mhdr->uidlist_mtime_nsecs) &&
+           (!mail_index_is_in_memory(index) || st.st_mtime < ioloop_time-1)) {
+               /* index is up-to-date. look up the uidvalidity and next-uid
+                  from it. we'll need to create a new view temporarily to
+                  make sure we get the latest values. */
+               view = mail_index_view_open(index);
+               hdr = mail_index_get_header(view);
                uidlist->uid_validity = hdr->uid_validity;
                uidlist->next_uid = hdr->next_uid;
                uidlist->initial_hdr_read = TRUE;
+               mail_index_view_close(&view);
                return 1;
        } else {
                return maildir_uidlist_refresh(uidlist);