dovecot-1.1: Maildir: Handle uidlist errors better.

dovecot at dovecot.org dovecot at dovecot.org
Mon May 4 23:48:50 EEST 2009


details:   http://hg.dovecot.org/dovecot-1.1/rev/003bebac2c76
changeset: 8262:003bebac2c76
user:      Timo Sirainen <tss at iki.fi>
date:      Mon May 04 14:33:54 2009 -0400
description:
Maildir: Handle uidlist errors better.

diffstat:

6 files changed, 86 insertions(+), 67 deletions(-)
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 310 to 300 lines):

diff -r 6bbe27c32cb8 -r 003bebac2c76 src/lib-storage/index/maildir/maildir-copy.c
--- a/src/lib-storage/index/maildir/maildir-copy.c	Mon May 04 14:28:31 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-copy.c	Mon May 04 14:33:54 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 6bbe27c32cb8 -r 003bebac2c76 src/lib-storage/index/maildir/maildir-mail.c
--- a/src/lib-storage/index/maildir/maildir-mail.c	Mon May 04 14:28:31 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-mail.c	Mon May 04 14:33:54 2009 -0400
@@ -139,7 +139,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)
 {
@@ -147,10 +147,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);
@@ -169,7 +170,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)
@@ -243,7 +244,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,
@@ -417,7 +418,7 @@ maildir_mail_get_special(struct mail *_m
 
 	if (field == MAIL_FETCH_UIDL_FILE_NAME) {
 		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,
@@ -477,12 +478,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 6bbe27c32cb8 -r 003bebac2c76 src/lib-storage/index/maildir/maildir-sync.c
--- a/src/lib-storage/index/maildir/maildir-sync.c	Mon May 04 14:28:31 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-sync.c	Mon May 04 14:33:54 2009 -0400
@@ -676,6 +676,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;
+	const char *fname;
 	int ret;
 
 	*lost_files_r = FALSE;
@@ -810,8 +811,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 6bbe27c32cb8 -r 003bebac2c76 src/lib-storage/index/maildir/maildir-uidlist.c
--- a/src/lib-storage/index/maildir/maildir-uidlist.c	Mon May 04 14:28:31 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c	Mon May 04 14:33:54 2009 -0400
@@ -853,9 +853,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;
@@ -863,7 +864,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;
@@ -877,66 +878,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;
@@ -985,14 +992,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 6bbe27c32cb8 -r 003bebac2c76 src/lib-storage/index/maildir/maildir-uidlist.h
--- a/src/lib-storage/index/maildir/maildir-uidlist.h	Mon May 04 14:28:31 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-uidlist.h	Mon May 04 14:33:54 2009 -0400
@@ -63,13 +63,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,
+			   enum maildir_uidlist_rec_flag *flags_r,
+			   const char **fname_r);
+int maildir_uidlist_lookup_nosync(struct maildir_uidlist *uidlist, uint32_t uid,
+				  enum maildir_uidlist_rec_flag *flags_r,
+				  const char **fname_r);
 /* Returns extension's value or NULL if it doesn't exist. */
 const char *
 maildir_uidlist_lookup_ext(struct maildir_uidlist *uidlist, uint32_t uid,
diff -r 6bbe27c32cb8 -r 003bebac2c76 src/lib-storage/index/maildir/maildir-util.c
--- a/src/lib-storage/index/maildir/maildir-util.c	Mon May 04 14:28:31 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-util.c	Mon May 04 14:33:54 2009 -0400
@@ -23,9 +23,9 @@ static int maildir_file_do_try(struct ma
         enum maildir_uidlist_rec_flag flags;
 	int ret;


More information about the dovecot-cvs mailing list