dovecot-1.3: maildir: When saving messages, in some race conditi...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Apr 14 02:21:02 EEST 2009
details: http://hg.dovecot.org/dovecot-1.3/rev/67369ba9f447
changeset: 9099:67369ba9f447
user: Timo Sirainen <tss at iki.fi>
date: Mon Apr 13 18:23:37 2009 -0400
description:
maildir: When saving messages, in some race conditions we might have written a duplicate UID.
diffstat:
3 files changed, 19 insertions(+), 3 deletions(-)
src/lib-index/mail-index.c | 5 +++++
src/lib-index/mail-index.h | 2 ++
src/lib-storage/index/maildir/maildir-uidlist.c | 15 ++++++++++++---
diffs (66 lines):
diff -r e2e481482c27 -r 67369ba9f447 src/lib-index/mail-index.c
--- a/src/lib-index/mail-index.c Mon Apr 13 18:21:24 2009 -0400
+++ b/src/lib-index/mail-index.c Mon Apr 13 18:23:37 2009 -0400
@@ -555,6 +555,11 @@ int mail_index_set_error(struct mail_ind
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;
diff -r e2e481482c27 -r 67369ba9f447 src/lib-index/mail-index.h
--- a/src/lib-index/mail-index.h Mon Apr 13 18:21:24 2009 -0400
+++ b/src/lib-index/mail-index.h Mon Apr 13 18:23:37 2009 -0400
@@ -206,6 +206,8 @@ int mail_index_open_or_create(struct mai
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. */
diff -r e2e481482c27 -r 67369ba9f447 src/lib-storage/index/maildir/maildir-uidlist.c
--- a/src/lib-storage/index/maildir/maildir-uidlist.c Mon Apr 13 18:21:24 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c Mon Apr 13 18:23:37 2009 -0400
@@ -820,10 +820,14 @@ int maildir_uidlist_refresh_fast_init(st
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(st
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);
More information about the dovecot-cvs
mailing list