dovecot-1.1: Cleaned up read-only mailbox handling. Fixes a bug ...

dovecot at dovecot.org dovecot at dovecot.org
Wed Jan 14 20:55:11 EET 2009


details:   http://hg.dovecot.org/dovecot-1.1/rev/57df8194f18d
changeset: 8096:57df8194f18d
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Jan 14 13:55:04 2009 -0500
description:
Cleaned up read-only mailbox handling. Fixes a bug with Maildir syncing.
If Maildir was opened read-only (STATUS, EXAMINE) then all flag changes were
saved to index as dirty.

diffstat:

10 files changed, 36 insertions(+), 37 deletions(-)
src/lib-storage/index/index-storage.c              |    8 +++-----
src/lib-storage/index/index-storage.h              |    3 ++-
src/lib-storage/index/maildir/maildir-storage.c    |    2 +-
src/lib-storage/index/maildir/maildir-sync-index.c |    8 ++++----
src/lib-storage/index/mbox/mbox-file.c             |   20 ++++++++++----------
src/lib-storage/index/mbox/mbox-lock.c             |    2 +-
src/lib-storage/index/mbox/mbox-save.c             |    2 +-
src/lib-storage/index/mbox/mbox-storage.c          |   10 ++++------
src/lib-storage/index/mbox/mbox-storage.h          |    2 +-
src/lib-storage/index/mbox/mbox-sync.c             |   16 +++++++++-------

diffs (262 lines):

diff -r 6f6b0299b559 -r 57df8194f18d src/lib-storage/index/index-storage.c
--- a/src/lib-storage/index/index-storage.c	Wed Jan 14 11:48:20 2009 -0500
+++ b/src/lib-storage/index/index-storage.c	Wed Jan 14 13:55:04 2009 -0500
@@ -424,7 +424,6 @@ void index_storage_mailbox_init(struct i
 		     ibox->box.pool, sizeof(void *), 5);
 
 	ibox->open_flags = flags;
-	ibox->readonly = (flags & MAILBOX_OPEN_READONLY) != 0;
 	ibox->keep_recent = (flags & MAILBOX_OPEN_KEEP_RECENT) != 0;
 	ibox->keep_locked = (flags & MAILBOX_OPEN_KEEP_LOCKED) != 0;
 	ibox->move_to_memory = move_to_memory;
@@ -461,15 +460,14 @@ bool index_storage_is_readonly(struct ma
 {
 	struct index_mailbox *ibox = (struct index_mailbox *) box;
 
-	return ibox->readonly;
+	return (ibox->open_flags & MAILBOX_OPEN_READONLY) != 0 ||
+		ibox->backend_readonly;
 }
 
 bool index_storage_allow_new_keywords(struct mailbox *box)
 {
-	struct index_mailbox *ibox = (struct index_mailbox *) box;
-
 	/* FIXME: return FALSE if we're full */
-	return !ibox->readonly;
+	return index_storage_is_readonly(box);
 }
 
 bool index_storage_is_inconsistent(struct mailbox *box)
diff -r 6f6b0299b559 -r 57df8194f18d src/lib-storage/index/index-storage.h
--- a/src/lib-storage/index/index-storage.h	Wed Jan 14 11:48:20 2009 -0500
+++ b/src/lib-storage/index/index-storage.h	Wed Jan 14 13:55:04 2009 -0500
@@ -56,7 +56,8 @@ struct index_mailbox {
 
 	time_t sync_last_check;
 
-	unsigned int readonly:1;
+	/* we've discovered there aren't enough permissions to modify mailbox */
+	unsigned int backend_readonly:1;
 	unsigned int keep_recent:1;
 	unsigned int keep_locked:1;
 	unsigned int sent_diskspace_warning:1;
diff -r 6f6b0299b559 -r 57df8194f18d src/lib-storage/index/maildir/maildir-storage.c
--- a/src/lib-storage/index/maildir/maildir-storage.c	Wed Jan 14 11:48:20 2009 -0500
+++ b/src/lib-storage/index/maildir/maildir-storage.c	Wed Jan 14 13:55:04 2009 -0500
@@ -462,7 +462,7 @@ maildir_open(struct maildir_storage *sto
 
 	if (access(t_strconcat(path, "/cur", NULL), W_OK) < 0 &&
 	    errno == EACCES)
-		mbox->ibox.readonly = TRUE;
+		mbox->ibox.backend_readonly = TRUE;
 
 	mbox->keywords = maildir_keywords_init(mbox);
 	return &mbox->ibox.box;
diff -r 6f6b0299b559 -r 57df8194f18d src/lib-storage/index/maildir/maildir-sync-index.c
--- a/src/lib-storage/index/maildir/maildir-sync-index.c	Wed Jan 14 11:48:20 2009 -0500
+++ b/src/lib-storage/index/maildir/maildir-sync-index.c	Wed Jan 14 13:55:04 2009 -0500
@@ -191,10 +191,10 @@ int maildir_sync_index_begin(struct mail
 	ctx->trans = trans;
 	ctx->keywords_sync_ctx =
 		maildir_keywords_sync_init(mbox->keywords, mbox->ibox.index);
-
-	ctx->sync_changes = index_sync_changes_init(&mbox->ibox, ctx->sync_ctx,
-						    ctx->view, ctx->trans,
-						    mbox->ibox.readonly);
+	ctx->sync_changes =
+		index_sync_changes_init(&mbox->ibox, ctx->sync_ctx,
+					ctx->view, ctx->trans,
+					mbox->ibox.backend_readonly);
 
 	*ctx_r = ctx;
 	return 0;
diff -r 6f6b0299b559 -r 57df8194f18d src/lib-storage/index/mbox/mbox-file.c
--- a/src/lib-storage/index/mbox/mbox-file.c	Wed Jan 14 11:48:20 2009 -0500
+++ b/src/lib-storage/index/mbox/mbox-file.c	Wed Jan 14 13:55:04 2009 -0500
@@ -19,13 +19,13 @@ int mbox_file_open(struct mbox_mailbox *
 
 	if (mbox->mbox_file_stream != NULL) {
 		/* read-only mbox stream */
-		i_assert(mbox->mbox_readonly);
-		return 0;
-	}
-
-	fd = open(mbox->path, mbox->mbox_readonly ? O_RDONLY : O_RDWR);
-	if (fd == -1 && errno == EACCES && !mbox->mbox_readonly) {
-                mbox->mbox_readonly = TRUE;
+		i_assert(mbox->ibox.backend_readonly);
+		return 0;
+	}
+
+	fd = open(mbox->path, mbox->ibox.backend_readonly ? O_RDONLY : O_RDWR);
+	if (fd == -1 && errno == EACCES && !mbox->ibox.backend_readonly) {
+                mbox->ibox.backend_readonly = TRUE;
 		fd = open(mbox->path, O_RDONLY);
 	}
 
@@ -65,7 +65,7 @@ int mbox_file_open_stream(struct mbox_ma
 
 	if (mbox->mbox_file_stream != NULL) {
 		/* read-only mbox stream */
-		i_assert(mbox->mbox_fd == -1 && mbox->mbox_readonly);
+		i_assert(mbox->mbox_fd == -1 && mbox->ibox.backend_readonly);
 	} else {
 		if (mbox->mbox_fd == -1) {
 			if (mbox_file_open(mbox) < 0)
@@ -94,7 +94,7 @@ static void mbox_file_fix_atime(struct m
 	struct stat st;
 
 	if (mbox->ibox.recent_flags_count > 0 && mbox->ibox.keep_recent &&
-	    mbox->mbox_fd != -1 && !mbox->mbox_readonly) {
+	    mbox->mbox_fd != -1 && !mbox->ibox.backend_readonly) {
 		/* we've seen recent messages which we want to keep recent.
 		   keep file's atime lower than mtime so \Marked status
 		   gets shown while listing */
@@ -123,7 +123,7 @@ void mbox_file_close_stream(struct mbox_
 	if (mbox->mbox_file_stream != NULL) {
 		if (mbox->mbox_fd == -1) {
 			/* read-only mbox stream */
-			i_assert(mbox->mbox_readonly);
+			i_assert(mbox->ibox.backend_readonly);
 			i_stream_seek(mbox->mbox_file_stream, 0);
 		} else {
 			i_stream_destroy(&mbox->mbox_file_stream);
diff -r 6f6b0299b559 -r 57df8194f18d src/lib-storage/index/mbox/mbox-lock.c
--- a/src/lib-storage/index/mbox/mbox-lock.c	Wed Jan 14 11:48:20 2009 -0500
+++ b/src/lib-storage/index/mbox/mbox-lock.c	Wed Jan 14 13:55:04 2009 -0500
@@ -616,7 +616,7 @@ static int mbox_update_locking(struct mb
 
 	if (mbox->mbox_fd == -1 && mbox->mbox_file_stream != NULL) {
 		/* read-only mbox stream. no need to lock. */
-		i_assert(mbox->mbox_readonly);
+		i_assert(mbox->ibox.backend_readonly);
 		mbox->mbox_lock_type = lock_type;
 		return 1;
 	}
diff -r 6f6b0299b559 -r 57df8194f18d src/lib-storage/index/mbox/mbox-save.c
--- a/src/lib-storage/index/mbox/mbox-save.c	Wed Jan 14 11:48:20 2009 -0500
+++ b/src/lib-storage/index/mbox/mbox-save.c	Wed Jan 14 13:55:04 2009 -0500
@@ -271,7 +271,7 @@ mbox_save_init_file(struct mbox_save_con
 	bool empty = FALSE;
 	int ret;
 
-	if (ctx->mbox->mbox_readonly) {
+	if (ctx->mbox->ibox.backend_readonly) {
 		mail_storage_set_error(storage, MAIL_ERROR_PERM,
 				       "Read-only mbox");
 		return -1;
diff -r 6f6b0299b559 -r 57df8194f18d src/lib-storage/index/mbox/mbox-storage.c
--- a/src/lib-storage/index/mbox/mbox-storage.c	Wed Jan 14 11:48:20 2009 -0500
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Wed Jan 14 13:55:04 2009 -0500
@@ -608,10 +608,8 @@ mbox_open(struct mbox_storage *storage, 
 	if (access(path, R_OK|W_OK) < 0) {
 		if (errno < EACCES)
 			mbox_set_syscall_error(mbox, "access()");
-		else {
-			mbox->ibox.readonly = TRUE;
-			mbox->mbox_readonly = TRUE;
-		}
+		else
+			mbox->ibox.backend_readonly = TRUE;
 	}
 
 	if (strcmp(name, "INBOX") == 0) {
@@ -645,7 +643,7 @@ mbox_mailbox_open_stream(struct mbox_sto
 
 	i_stream_ref(input);
 	mbox->mbox_file_stream = input;
-	mbox->mbox_readonly = TRUE;
+	mbox->ibox.backend_readonly = TRUE;
 	mbox->no_mbox_file = TRUE;
 
 	mbox->path = "(read-only mbox stream)";
@@ -774,7 +772,7 @@ static int mbox_storage_mailbox_close(st
 	if (mbox->ibox.view != NULL) {
 		hdr = mail_index_get_header(mbox->ibox.view);
 		if ((hdr->flags & MAIL_INDEX_HDR_FLAG_HAVE_DIRTY) != 0 &&
-		    !mbox->mbox_readonly) {
+		    !mbox->ibox.backend_readonly) {
 			/* we've done changes to mbox which haven't been
 			   written yet. do it now. */
 			sync_flags |= MBOX_SYNC_REWRITE;
diff -r 6f6b0299b559 -r 57df8194f18d src/lib-storage/index/mbox/mbox-storage.h
--- a/src/lib-storage/index/mbox/mbox-storage.h	Wed Jan 14 11:48:20 2009 -0500
+++ b/src/lib-storage/index/mbox/mbox-storage.h	Wed Jan 14 13:55:04 2009 -0500
@@ -41,7 +41,7 @@ struct mbox_mailbox {
 	struct dotlock *mbox_dotlock;
 	unsigned int mbox_lock_id, mbox_global_lock_id;
 	struct timeout *keep_lock_to;
-	bool mbox_readonly, mbox_writeonly;
+	bool mbox_writeonly;
 
 	uint32_t mbox_ext_idx;
 	struct mbox_index_header mbox_hdr;
diff -r 6f6b0299b559 -r 57df8194f18d src/lib-storage/index/mbox/mbox-sync.c
--- a/src/lib-storage/index/mbox/mbox-sync.c	Wed Jan 14 11:48:20 2009 -0500
+++ b/src/lib-storage/index/mbox/mbox-sync.c	Wed Jan 14 13:55:04 2009 -0500
@@ -173,7 +173,7 @@ static void mbox_sync_read_index_syncs(s
 	}
 
 	index_sync_changes_read(sync_ctx->sync_changes, uid, sync_expunge_r);
-	if (sync_ctx->mbox->mbox_readonly) {
+	if (sync_ctx->mbox->ibox.backend_readonly) {
 		/* we can't expunge anything from read-only mboxes */
 		*sync_expunge_r = FALSE;
 	}
@@ -1534,7 +1534,8 @@ static int mbox_sync_do(struct mbox_sync
 		/* a) partial sync didn't work
 		   b) we ran out of UIDs
 		   c) syncing had errors */
-		if (sync_ctx->delay_writes && !sync_ctx->mbox->mbox_readonly &&
+		if (sync_ctx->delay_writes &&
+		    !sync_ctx->mbox->ibox.backend_readonly &&
 		    (sync_ctx->errors || sync_ctx->renumber_uids)) {
 			/* fixing a broken mbox state, be sure to write
 			   the changes. */
@@ -1671,7 +1672,7 @@ static int mbox_sync_int(struct mbox_mai
 	int ret, changed;
 	bool delay_writes;
 
-	delay_writes = mbox->mbox_readonly ||
+	delay_writes = mbox->ibox.backend_readonly ||
 		((flags & MBOX_SYNC_REWRITE) == 0 &&
 		 getenv("MBOX_LAZY_WRITES") != NULL);
 
@@ -1714,7 +1715,7 @@ again:
 		   lock it for writing immediately. the mbox must be locked
 		   before index syncing is started to avoid deadlocks, so we
 		   don't have much choice either (well, easy ones anyway). */
-		int lock_type = mbox->mbox_readonly ? F_RDLCK : F_WRLCK;
+		int lock_type = mbox->ibox.backend_readonly ? F_RDLCK : F_WRLCK;
 
 		if ((ret = mbox_lock(mbox, lock_type, lock_id)) <= 0) {
 			if (ret == 0 || lock_type == F_RDLCK)
@@ -1723,7 +1724,7 @@ again:
 			/* try as read-only */
 			if (mbox_lock(mbox, F_RDLCK, lock_id) <= 0)
 				return -1;
-			mbox->mbox_readonly = TRUE;
+			mbox->ibox.backend_readonly = TRUE;
 		}
 	}
 
@@ -1789,7 +1790,8 @@ again:
 	i_array_init(&sync_ctx.mails, 64);
 
 	sync_ctx.flags = flags;
-	sync_ctx.delay_writes = delay_writes || sync_ctx.mbox->mbox_readonly;
+	sync_ctx.delay_writes = delay_writes ||
+		sync_ctx.mbox->ibox.backend_readonly;
 
 	sync_ctx.sync_changes =
 		index_sync_changes_init(&mbox->ibox, index_sync_ctx,
@@ -1845,7 +1847,7 @@ again:
 	sync_ctx.index_sync_ctx = NULL;
 
 	if (ret == 0 && mbox->mbox_fd != -1 && mbox->ibox.keep_recent &&
-	    !sync_ctx.mbox->mbox_readonly) {
+	    !sync_ctx.mbox->ibox.backend_readonly) {
 		/* try to set atime back to its original value */
 		struct utimbuf buf;
 		struct stat st;


More information about the dovecot-cvs mailing list