dovecot-2.0: Maildir: Handle uidlist errors better.
dovecot at dovecot.org
dovecot at dovecot.org
Mon May 4 23:48:46 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/d04b97ed7ac4
changeset: 9207:d04b97ed7ac4
user: Timo Sirainen <tss at iki.fi>
date: Mon May 04 16:40:41 2009 -0400
description:
Maildir: Handle uidlist errors better.
diffstat:
7 files changed, 90 insertions(+), 69 deletions(-)
src/lib-storage/index/dbox/dbox-file-maildir.c | 6 -
src/lib-storage/index/maildir/maildir-copy.c | 6 -
src/lib-storage/index/maildir/maildir-mail.c | 24 +++--
src/lib-storage/index/maildir/maildir-sync.c | 8 +
src/lib-storage/index/maildir/maildir-uidlist.c | 94 ++++++++++++-----------
src/lib-storage/index/maildir/maildir-uidlist.h | 15 +--
src/lib-storage/index/maildir/maildir-util.c | 6 -
diffs (truncated from 324 to 300 lines):
diff -r 9b6ca1680cd2 -r d04b97ed7ac4 src/lib-storage/index/dbox/dbox-file-maildir.c
--- a/src/lib-storage/index/dbox/dbox-file-maildir.c Mon May 04 16:38:38 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-file-maildir.c Mon May 04 16:40:41 2009 -0400
@@ -84,6 +84,8 @@ bool dbox_maildir_uid_get_fname(struct d
{
enum maildir_uidlist_rec_flag flags;
- *fname_r = maildir_uidlist_lookup(mbox->maildir_uidlist, uid, &flags);
- return *fname_r != NULL;
+ if (maildir_uidlist_lookup(mbox->maildir_uidlist, uid, &flags,
+ fname_r) <= 0)
+ return FALSE;
+ return TRUE;
}
diff -r 9b6ca1680cd2 -r d04b97ed7ac4 src/lib-storage/index/maildir/maildir-copy.c
--- a/src/lib-storage/index/maildir/maildir-copy.c Mon May 04 16:38:38 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-copy.c Mon May 04 16:40:41 2009 -0400
@@ -167,9 +167,9 @@ maildir_copy_hardlink(struct maildir_tra
uidlist. if it doesn't, we can use it. otherwise generate
a new filename. FIXME: There's a race condition here if
another process is just doing the same copy. */
- src_fname = maildir_uidlist_lookup(src_mbox->uidlist,
- mail->uid, &src_flags);
- if (src_fname != NULL &&
+ if (maildir_uidlist_lookup(src_mbox->uidlist,
+ mail->uid, &src_flags,
+ &src_fname) > 0 &&
maildir_uidlist_refresh(dest_mbox->uidlist) >= 0 &&
maildir_uidlist_get_full_filename(dest_mbox->uidlist,
src_fname) == NULL)
diff -r 9b6ca1680cd2 -r d04b97ed7ac4 src/lib-storage/index/maildir/maildir-mail.c
--- a/src/lib-storage/index/maildir/maildir-mail.c Mon May 04 16:38:38 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-mail.c Mon May 04 16:40:41 2009 -0400
@@ -147,7 +147,7 @@ static int maildir_mail_get_save_date(st
return data->save_date;
}
-static bool
+static int
maildir_mail_get_fname(struct maildir_mailbox *mbox, struct mail *mail,
const char **fname_r)
{
@@ -155,10 +155,11 @@ maildir_mail_get_fname(struct maildir_ma
struct mail_index_view *view;
uint32_t seq;
bool exists;
-
- *fname_r = maildir_uidlist_lookup(mbox->uidlist, mail->uid, &flags);
- if (*fname_r != NULL)
- return TRUE;
+ int ret;
+
+ ret = maildir_uidlist_lookup(mbox->uidlist, mail->uid, &flags, fname_r);
+ if (ret != 0)
+ return ret;
/* file exists in index file, but not in dovecot-uidlist anymore. */
mail_set_expunged(mail);
@@ -177,7 +178,7 @@ maildir_mail_get_fname(struct maildir_ma
the same as in index. fix this by forcing a resync. */
(void)maildir_storage_sync_force(mbox, mail->uid);
}
- return FALSE;
+ return 0;
}
static int maildir_get_pop3_state(struct index_mail *mail)
@@ -252,7 +253,7 @@ static int maildir_quick_size_lookup(str
char *p;
if (_mail->uid != 0) {
- if (!maildir_mail_get_fname(mbox, _mail, &fname))
+ if (maildir_mail_get_fname(mbox, _mail, &fname) <= 0)
return -1;
} else {
path = maildir_save_file_get_path(_mail->transaction,
@@ -428,7 +429,7 @@ maildir_mail_get_special(struct mail *_m
case MAIL_FETCH_UIDL_FILE_NAME:
case MAIL_FETCH_GUID:
if (_mail->uid != 0) {
- if (!maildir_mail_get_fname(mbox, _mail, &fname))
+ if (maildir_mail_get_fname(mbox, _mail, &fname) <= 0)
return -1;
} else {
path = maildir_save_file_get_path(_mail->transaction,
@@ -488,12 +489,15 @@ static void maildir_mail_set_cache_corru
enum maildir_uidlist_rec_flag flags;
const char *fname;
uoff_t size;
+ int ret;
if (field == MAIL_FETCH_VIRTUAL_SIZE) {
/* make sure it gets removed from uidlist.
if it's in file name, we can't really do more than log it. */
- fname = maildir_uidlist_lookup(mbox->uidlist,
- _mail->uid, &flags);
+ ret = maildir_uidlist_lookup(mbox->uidlist, _mail->uid,
+ &flags, &fname);
+ if (ret <= 0)
+ return;
if (maildir_filename_get_size(fname, MAILDIR_EXTRA_VIRTUAL_SIZE,
&size)) {
const char *subdir =
diff -r 9b6ca1680cd2 -r d04b97ed7ac4 src/lib-storage/index/maildir/maildir-sync.c
--- a/src/lib-storage/index/maildir/maildir-sync.c Mon May 04 16:38:38 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-sync.c Mon May 04 16:40:41 2009 -0400
@@ -692,6 +692,7 @@ static int maildir_sync_context(struct m
enum maildir_uidlist_sync_flags sync_flags;
enum maildir_uidlist_rec_flag flags;
bool new_changed, cur_changed, lock_failure;
+ const char *fname;
int ret;
*lost_files_r = FALSE;
@@ -854,8 +855,11 @@ static int maildir_sync_context(struct m
}
if (find_uid != NULL && *find_uid != 0) {
- if (maildir_uidlist_lookup_nosync(ctx->mbox->uidlist, *find_uid,
- &flags) == NULL) {
+ ret = maildir_uidlist_lookup_nosync(ctx->mbox->uidlist,
+ *find_uid, &flags, &fname);
+ if (ret < 0)
+ return -1;
+ if (ret == 0) {
/* UID is expunged */
*find_uid = 0;
} else if ((flags & MAILDIR_UIDLIST_REC_FLAG_NONSYNCED) == 0) {
diff -r 9b6ca1680cd2 -r d04b97ed7ac4 src/lib-storage/index/maildir/maildir-uidlist.c
--- a/src/lib-storage/index/maildir/maildir-uidlist.c Mon May 04 16:38:38 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c Mon May 04 16:40:41 2009 -0400
@@ -860,9 +860,10 @@ int maildir_uidlist_refresh_fast_init(st
}
}
-static struct maildir_uidlist_rec *
+static int
maildir_uidlist_lookup_rec(struct maildir_uidlist *uidlist, uint32_t uid,
- unsigned int *idx_r)
+ unsigned int *idx_r,
+ struct maildir_uidlist_rec **rec_r)
{
struct maildir_uidlist_rec *const *recs;
unsigned int idx, left_idx, right_idx;
@@ -870,7 +871,7 @@ maildir_uidlist_lookup_rec(struct maildi
if (!uidlist->initial_read) {
/* first time we need to read uidlist */
if (maildir_uidlist_refresh(uidlist) < 0)
- return NULL;
+ return -1;
}
idx = left_idx = 0;
@@ -884,66 +885,72 @@ maildir_uidlist_lookup_rec(struct maildi
right_idx = idx;
else {
*idx_r = idx;
- return recs[idx];
+ *rec_r = recs[idx];
+ return 1;
}
}
if (idx > 0) idx--;
*idx_r = idx;
- return NULL;
-}
-
-const char *
-maildir_uidlist_lookup(struct maildir_uidlist *uidlist, uint32_t uid,
- enum maildir_uidlist_rec_flag *flags_r)
-{
- const char *fname;
-
- fname = maildir_uidlist_lookup_nosync(uidlist, uid, flags_r);
- if (fname == NULL) {
+ return 0;
+}
+
+int maildir_uidlist_lookup(struct maildir_uidlist *uidlist, uint32_t uid,
+ enum maildir_uidlist_rec_flag *flags_r,
+ const char **fname_r)
+{
+ int ret;
+
+ ret = maildir_uidlist_lookup_nosync(uidlist, uid, flags_r, fname_r);
+ if (ret <= 0) {
+ if (ret < 0)
+ return -1;
if (uidlist->fd != -1 || uidlist->mbox == NULL) {
/* refresh uidlist and check again in case it was added
after the last mailbox sync */
if (maildir_uidlist_refresh(uidlist) < 0)
- return NULL;
+ return -1;
} else {
/* the uidlist doesn't exist. */
if (maildir_storage_sync_force(uidlist->mbox, uid) < 0)
- return NULL;
+ return -1;
}
/* try again */
- fname = maildir_uidlist_lookup_nosync(uidlist, uid, flags_r);
- }
-
- return fname;
-}
-
-const char *
-maildir_uidlist_lookup_nosync(struct maildir_uidlist *uidlist, uint32_t uid,
- enum maildir_uidlist_rec_flag *flags_r)
-{
- const struct maildir_uidlist_rec *rec;
+ ret = maildir_uidlist_lookup_nosync(uidlist, uid,
+ flags_r, fname_r);
+ }
+
+ return ret;
+}
+
+int maildir_uidlist_lookup_nosync(struct maildir_uidlist *uidlist, uint32_t uid,
+ enum maildir_uidlist_rec_flag *flags_r,
+ const char **fname_r)
+{
+ struct maildir_uidlist_rec *rec;
unsigned int idx;
-
- rec = maildir_uidlist_lookup_rec(uidlist, uid, &idx);
- if (rec == NULL)
- return NULL;
+ int ret;
+
+ if ((ret = maildir_uidlist_lookup_rec(uidlist, uid, &idx, &rec)) <= 0)
+ return ret;
*flags_r = rec->flags;
- return rec->filename;
+ *fname_r = rec->filename;
+ return 1;
}
const char *
maildir_uidlist_lookup_ext(struct maildir_uidlist *uidlist, uint32_t uid,
enum maildir_uidlist_rec_ext_key key)
{
- const struct maildir_uidlist_rec *rec;
+ struct maildir_uidlist_rec *rec;
unsigned int idx;
const unsigned char *p;
-
- rec = maildir_uidlist_lookup_rec(uidlist, uid, &idx);
- if (rec == NULL || rec->extensions == NULL)
+ int ret;
+
+ ret = maildir_uidlist_lookup_rec(uidlist, uid, &idx, &rec);
+ if (ret <= 0 || rec->extensions == NULL)
return NULL;
p = rec->extensions;
@@ -992,14 +999,17 @@ maildir_uidlist_set_ext_real(struct mail
const unsigned char *p;
buffer_t *buf;
unsigned int len;
-
- rec = maildir_uidlist_lookup_rec(uidlist, uid, &idx);
- if (rec == NULL) {
+ int ret;
+
+ ret = maildir_uidlist_lookup_rec(uidlist, uid, &idx, &rec);
+ if (ret <= 0) {
+ if (ret < 0)
+ return;
+
/* maybe it's a new message */
if (maildir_uidlist_refresh(uidlist) < 0)
return;
- rec = maildir_uidlist_lookup_rec(uidlist, uid, &idx);
- if (rec == NULL) {
+ if (maildir_uidlist_lookup_rec(uidlist, uid, &idx, &rec) <= 0) {
/* message is already expunged, ignore */
return;
}
diff -r 9b6ca1680cd2 -r d04b97ed7ac4 src/lib-storage/index/maildir/maildir-uidlist.h
--- a/src/lib-storage/index/maildir/maildir-uidlist.h Mon May 04 16:38:38 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-uidlist.h Mon May 04 16:40:41 2009 -0400
@@ -64,13 +64,14 @@ int maildir_uidlist_refresh(struct maild
fill in the uidvalidity/nextuid from index file instead. */
int maildir_uidlist_refresh_fast_init(struct maildir_uidlist *uidlist);
-/* Returns uidlist record for given filename, or NULL if not found. */
-const char *
-maildir_uidlist_lookup(struct maildir_uidlist *uidlist, uint32_t uid,
- enum maildir_uidlist_rec_flag *flags_r);
-const char *
-maildir_uidlist_lookup_nosync(struct maildir_uidlist *uidlist, uint32_t uid,
- enum maildir_uidlist_rec_flag *flags_r);
+/* Look up uidlist record for given filename. Returns 1 if found,
+ 0 if not found, -1 if error */
+int maildir_uidlist_lookup(struct maildir_uidlist *uidlist, uint32_t uid,
More information about the dovecot-cvs
mailing list