changeset 8626:a9dd29e7dc4f HEAD

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.
author Timo Sirainen <tss@iki.fi>
date Wed, 14 Jan 2009 13:56:01 -0500
parents de27a19a8721
children b920d841f8fe
files src/lib-storage/index/index-storage.c src/lib-storage/index/index-storage.h src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/maildir/maildir-sync-index.c src/lib-storage/index/mbox/mbox-file.c src/lib-storage/index/mbox/mbox-lock.c src/lib-storage/index/mbox/mbox-save.c src/lib-storage/index/mbox/mbox-storage.c src/lib-storage/index/mbox/mbox-storage.h src/lib-storage/index/mbox/mbox-sync.c
diffstat 10 files changed, 33 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- 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:56:01 2009 -0500
@@ -463,7 +463,6 @@
 	array_create(&ibox->box.module_contexts,
 		     ibox->box.pool, sizeof(void *), 5);
 
-	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;
@@ -514,15 +513,14 @@
 {
 	struct index_mailbox *ibox = (struct index_mailbox *) box;
 
-	return ibox->readonly;
+	return (ibox->box.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)
--- 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:56:01 2009 -0500
@@ -55,7 +55,8 @@
 
 	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;
--- 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:56:01 2009 -0500
@@ -468,7 +468,7 @@
 
 	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;
--- 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:56:01 2009 -0500
@@ -193,10 +193,10 @@
 	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;
--- 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:56:01 2009 -0500
@@ -19,13 +19,13 @@
 
 	if (mbox->mbox_file_stream != NULL) {
 		/* read-only mbox stream */
-		i_assert(mbox->mbox_readonly);
+		i_assert(mbox->ibox.backend_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;
+	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 @@
 
 	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)
@@ -95,7 +95,7 @@
 	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 */
@@ -124,7 +124,7 @@
 	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);
--- 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:56:01 2009 -0500
@@ -621,7 +621,7 @@
 
 	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;
 	}
--- 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:56:01 2009 -0500
@@ -254,7 +254,7 @@
 	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;
--- 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:56:01 2009 -0500
@@ -615,10 +615,8 @@
 	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) {
@@ -652,7 +650,7 @@
 
 	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)";
@@ -785,7 +783,7 @@
 	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;
--- 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:56:01 2009 -0500
@@ -41,7 +41,7 @@
 	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;
--- 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:56:01 2009 -0500
@@ -173,7 +173,7 @@
 	}
 
 	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;
 	}
@@ -1535,7 +1535,8 @@
 		/* 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. */
@@ -1672,7 +1673,7 @@
 	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);
 
@@ -1715,7 +1716,7 @@
 		   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)
@@ -1724,7 +1725,7 @@
 			/* try as read-only */
 			if (mbox_lock(mbox, F_RDLCK, lock_id) <= 0)
 				return -1;
-			mbox->mbox_readonly = TRUE;
+			mbox->ibox.backend_readonly = TRUE;
 		}
 	}
 
@@ -1790,7 +1791,8 @@
 	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,
@@ -1846,7 +1848,7 @@
 	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;