changeset 12536:9d947390a875

lib-storage: Removed mailbox.backend_readonly. Backends set it internally lazily now.
author Timo Sirainen <tss@iki.fi>
date Mon, 06 Dec 2010 01:47:50 +0000
parents b399c8dd1650
children 16929d83a00c
files src/lib-storage/index/index-storage.c src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/maildir/maildir-storage.h 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 src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.c
diffstat 12 files changed, 82 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/index-storage.c	Mon Dec 06 01:27:11 2010 +0000
+++ b/src/lib-storage/index/index-storage.c	Mon Dec 06 01:47:50 2010 +0000
@@ -476,16 +476,7 @@
 
 bool index_storage_is_readonly(struct mailbox *box)
 {
-	if ((box->flags & MAILBOX_FLAG_READONLY) != 0)
-		return TRUE;
-
-	if (box->backend_readonly) {
-		/* return read-only only if there are no private flags
-		   (that are stored in index files) */
-		if (mailbox_get_private_flags_mask(box) == 0)
-			return TRUE;
-	}
-	return FALSE;
+	return (box->flags & MAILBOX_FLAG_READONLY) != 0;
 }
 
 bool index_storage_allow_new_keywords(struct mailbox *box)
--- a/src/lib-storage/index/maildir/maildir-storage.c	Mon Dec 06 01:27:11 2010 +0000
+++ b/src/lib-storage/index/maildir/maildir-storage.c	Mon Dec 06 01:47:50 2010 +0000
@@ -292,7 +292,6 @@
 static int maildir_mailbox_open_existing(struct mailbox *box)
 {
 	struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
-	const char *box_path = mailbox_get_path(box);
 
 	mbox->uidlist = maildir_uidlist_init(mbox);
 	mbox->keywords = maildir_keywords_init(mbox);
@@ -305,9 +304,6 @@
 						 mbox);
 	}
 
-	if (access(t_strconcat(box_path, "/cur", NULL), W_OK) < 0 &&
-	    errno == EACCES)
-		mbox->box.backend_readonly = TRUE;
 	if (index_storage_mailbox_open(box, FALSE) < 0)
 		return -1;
 
@@ -317,6 +313,22 @@
 	return 0;
 }
 
+static bool maildir_storage_is_readonly(struct mailbox *box)
+{
+	struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
+
+	if (index_storage_is_readonly(box))
+		return TRUE;
+
+	if (maildir_is_backend_readonly(mbox)) {
+		/* return read-only only if there are no private flags
+		   (that are stored in index files) */
+		if (mailbox_get_private_flags_mask(box) == 0)
+			return TRUE;
+	}
+	return FALSE;
+}
+
 static int maildir_mailbox_open(struct mailbox *box)
 {
 	const char *box_path = mailbox_get_path(box);
@@ -589,6 +601,19 @@
 	return mbox->_private_flags_mask;
 }
 
+bool maildir_is_backend_readonly(struct maildir_mailbox *mbox)
+{
+	if (!mbox->backend_readonly_set) {
+		const char *box_path = mailbox_get_path(&mbox->box);
+
+		mbox->backend_readonly_set = TRUE;
+		if (access(t_strconcat(box_path, "/cur", NULL), W_OK) < 0 &&
+		    errno == EACCES)
+			mbox->backend_readonly = TRUE;
+	}
+	return mbox->backend_readonly;
+}
+
 struct mail_storage maildir_storage = {
 	.name = MAILDIR_STORAGE_NAME,
 	.class_flags = 0,
@@ -608,7 +633,7 @@
 
 struct mailbox maildir_mailbox = {
 	.v = {
-		index_storage_is_readonly,
+		maildir_storage_is_readonly,
 		index_storage_allow_new_keywords,
 		index_storage_mailbox_enable,
 		maildir_mailbox_open,
--- a/src/lib-storage/index/maildir/maildir-storage.h	Mon Dec 06 01:27:11 2010 +0000
+++ b/src/lib-storage/index/maildir/maildir-storage.h	Mon Dec 06 01:47:50 2010 +0000
@@ -91,6 +91,8 @@
 	unsigned int synced:1;
 	unsigned int syncing_commit:1;
 	unsigned int private_flags_mask_set:1;
+	unsigned int backend_readonly:1;
+	unsigned int backend_readonly_set:1;
 };
 
 extern struct mail_vfuncs maildir_mail_vfuncs;
@@ -115,6 +117,7 @@
 bool maildir_set_deleted(struct mailbox *box);
 uint32_t maildir_get_uidvalidity_next(struct mailbox_list *list);
 int maildir_lose_unexpected_dir(struct mail_storage *storage, const char *path);
+bool maildir_is_backend_readonly(struct maildir_mailbox *mbox);
 
 struct mail_save_context *
 maildir_save_alloc(struct mailbox_transaction_context *_t);
--- a/src/lib-storage/index/maildir/maildir-sync-index.c	Mon Dec 06 01:27:11 2010 +0000
+++ b/src/lib-storage/index/maildir/maildir-sync-index.c	Mon Dec 06 01:47:50 2010 +0000
@@ -244,7 +244,7 @@
 		maildir_keywords_sync_init(mbox->keywords, _box->index);
 	ctx->sync_changes =
 		index_sync_changes_init(ctx->sync_ctx, ctx->view, ctx->trans,
-					mbox->box.backend_readonly);
+					maildir_is_backend_readonly(mbox));
 	ctx->start_time = time(NULL);
 
 	*ctx_r = ctx;
--- a/src/lib-storage/index/mbox/mbox-file.c	Mon Dec 06 01:27:11 2010 +0000
+++ b/src/lib-storage/index/mbox/mbox-file.c	Mon Dec 06 01:47:50 2010 +0000
@@ -21,14 +21,14 @@
 
 	if (mbox->mbox_file_stream != NULL) {
 		/* read-only mbox stream */
-		i_assert(mbox->box.backend_readonly);
+		i_assert(mbox_is_backend_readonly(mbox));
 		return 0;
 	}
 
 	fd = open(mailbox_get_path(&mbox->box),
-		  mbox->box.backend_readonly ? O_RDONLY : O_RDWR);
-	if (fd == -1 && errno == EACCES && !mbox->box.backend_readonly) {
-                mbox->box.backend_readonly = TRUE;
+		  mbox_is_backend_readonly(mbox) ? O_RDONLY : O_RDWR);
+	if (fd == -1 && errno == EACCES && !mbox->backend_readonly) {
+		mbox->backend_readonly = TRUE;
 		fd = open(mailbox_get_path(&mbox->box), O_RDONLY);
 	}
 
@@ -68,7 +68,7 @@
 
 	if (mbox->mbox_file_stream != NULL) {
 		/* read-only mbox stream */
-		i_assert(mbox->mbox_fd == -1 && mbox->box.backend_readonly);
+		i_assert(mbox->mbox_fd == -1 && mbox_is_backend_readonly(mbox));
 	} else {
 		if (mbox->mbox_fd == -1) {
 			if (mbox_file_open(mbox) < 0)
@@ -104,7 +104,7 @@
 
 	if (ibox->recent_flags_count > 0 &&
 	    (mbox->box.flags & MAILBOX_FLAG_KEEP_RECENT) != 0 &&
-	    mbox->mbox_fd != -1 && !mbox->box.backend_readonly) {
+	    mbox->mbox_fd != -1 && !mbox_is_backend_readonly(mbox)) {
 		/* 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 */
@@ -133,7 +133,7 @@
 	if (mbox->mbox_file_stream != NULL) {
 		if (mbox->mbox_fd == -1) {
 			/* read-only mbox stream */
-			i_assert(mbox->box.backend_readonly);
+			i_assert(mbox_is_backend_readonly(mbox));
 			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	Mon Dec 06 01:27:11 2010 +0000
+++ b/src/lib-storage/index/mbox/mbox-lock.c	Mon Dec 06 01:47:50 2010 +0000
@@ -708,7 +708,7 @@
 
 	if (mbox->mbox_fd == -1 && mbox->mbox_file_stream != NULL) {
 		/* read-only mbox stream. no need to lock. */
-		i_assert(mbox->box.backend_readonly);
+		i_assert(mbox_is_backend_readonly(mbox));
 		mbox->mbox_lock_type = lock_type;
 		return 1;
 	}
--- a/src/lib-storage/index/mbox/mbox-save.c	Mon Dec 06 01:27:11 2010 +0000
+++ b/src/lib-storage/index/mbox/mbox-save.c	Mon Dec 06 01:47:50 2010 +0000
@@ -261,7 +261,7 @@
 	bool empty = FALSE;
 	int ret;
 
-	if (ctx->mbox->box.backend_readonly) {
+	if (mbox_is_backend_readonly(ctx->mbox)) {
 		mail_storage_set_error(storage, MAIL_ERROR_PERM,
 				       "Read-only mbox");
 		return -1;
--- a/src/lib-storage/index/mbox/mbox-storage.c	Mon Dec 06 01:27:11 2010 +0000
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Mon Dec 06 01:47:50 2010 +0000
@@ -402,13 +402,6 @@
 	const char *rootdir, *box_path = mailbox_get_path(box);
 	bool move_to_memory;
 
-	if (access(box_path, R_OK|W_OK) < 0) {
-		if (errno != EACCES) {
-			mbox_set_syscall_error(mbox, "access()");
-			return -1;
-		}
-		mbox->box.backend_readonly = TRUE;
-	}
 	move_to_memory = want_memory_indexes(mbox->storage, box_path);
 
 	if (box->inbox_any || strcmp(box->name, "INBOX") == 0) {
@@ -432,6 +425,22 @@
 	return mbox_mailbox_open_finish(mbox, move_to_memory);
 }
 
+static bool mbox_storage_is_readonly(struct mailbox *box)
+{
+	struct mbox_mailbox *mbox = (struct mbox_mailbox *)box;
+
+	if (index_storage_is_readonly(box))
+		return TRUE;
+
+	if (mbox_is_backend_readonly(mbox)) {
+		/* return read-only only if there are no private flags
+		   (that are stored in index files) */
+		if (mailbox_get_private_flags_mask(box) == 0)
+			return TRUE;
+	}
+	return FALSE;
+}
+
 static int mbox_mailbox_open(struct mailbox *box)
 {
 	struct mbox_mailbox *mbox = (struct mbox_mailbox *)box;
@@ -441,7 +450,8 @@
 	if (box->input != NULL) {
 		i_stream_ref(box->input);
 		mbox->mbox_file_stream = box->input;
-		mbox->box.backend_readonly = TRUE;
+		mbox->backend_readonly = TRUE;
+		mbox->backend_readonly_set = TRUE;
 		mbox->no_mbox_file = TRUE;
 		return mbox_mailbox_open_finish(mbox, FALSE);
 	}
@@ -561,7 +571,7 @@
 	if (box->view != NULL) {
 		hdr = mail_index_get_header(box->view);
 		if ((hdr->flags & MAIL_INDEX_HDR_FLAG_HAVE_DIRTY) != 0 &&
-		    !mbox->box.backend_readonly) {
+		    !mbox_is_backend_readonly(mbox)) {
 			/* we've done changes to mbox which haven't been
 			   written yet. do it now. */
 			sync_flags |= MBOX_SYNC_REWRITE;
@@ -696,6 +706,17 @@
 	mbox_transaction_unlock(box, lock_id);
 }
 
+bool mbox_is_backend_readonly(struct mbox_mailbox *mbox)
+{
+	if (!mbox->backend_readonly_set) {
+		mbox->backend_readonly_set = TRUE;
+		if (access(mailbox_get_path(&mbox->box), R_OK|W_OK) < 0 &&
+		    errno == EACCES)
+			mbox->backend_readonly = TRUE;
+	}
+	return mbox->backend_readonly;
+}
+
 struct mail_storage mbox_storage = {
 	.name = MBOX_STORAGE_NAME,
 	.class_flags = MAIL_STORAGE_CLASS_FLAG_MAILBOX_IS_FILE |
@@ -716,7 +737,7 @@
 
 struct mailbox mbox_mailbox = {
 	.v = {
-		index_storage_is_readonly,
+		mbox_storage_is_readonly,
 		index_storage_allow_new_keywords,
 		index_storage_mailbox_enable,
 		mbox_mailbox_open,
--- a/src/lib-storage/index/mbox/mbox-storage.h	Mon Dec 06 01:27:11 2010 +0000
+++ b/src/lib-storage/index/mbox/mbox-storage.h	Mon Dec 06 01:47:50 2010 +0000
@@ -57,6 +57,8 @@
 	unsigned int mbox_used_privileges:1;
 	unsigned int mbox_privileged_locking:1;
 	unsigned int syncing:1;
+	unsigned int backend_readonly:1;
+	unsigned int backend_readonly_set:1;
 };
 
 struct mbox_transaction_context {
@@ -87,4 +89,6 @@
 				       struct mail_index_transaction_commit_result *result);
 void mbox_transaction_save_rollback(struct mail_save_context *ctx);
 
+bool mbox_is_backend_readonly(struct mbox_mailbox *mbox);
+
 #endif
--- a/src/lib-storage/index/mbox/mbox-sync.c	Mon Dec 06 01:27:11 2010 +0000
+++ b/src/lib-storage/index/mbox/mbox-sync.c	Mon Dec 06 01:47:50 2010 +0000
@@ -1733,7 +1733,7 @@
 	int ret, changed;
 	bool delay_writes, readonly;
 
-	readonly = mbox->box.backend_readonly ||
+	readonly = mbox_is_backend_readonly(mbox) ||
 		(flags & MBOX_SYNC_READONLY) != 0;
 	delay_writes = readonly ||
 		((flags & MBOX_SYNC_REWRITE) == 0 &&
@@ -1791,7 +1791,8 @@
 			/* try as read-only */
 			if (mbox_lock(mbox, F_RDLCK, lock_id) <= 0)
 				return -1;
-			mbox->box.backend_readonly = readonly = TRUE;
+			mbox->backend_readonly = readonly = TRUE;
+			mbox->backend_readonly_set = TRUE;
 			delay_writes = TRUE;
 		}
 	}
--- a/src/lib-storage/mail-storage-private.h	Mon Dec 06 01:27:11 2010 +0000
+++ b/src/lib-storage/mail-storage-private.h	Mon Dec 06 01:47:50 2010 +0000
@@ -280,8 +280,6 @@
 	unsigned int opened:1;
 	/* Mailbox was deleted while we had it open. */
 	unsigned int mailbox_deleted:1;
-	/* we've discovered there aren't enough permissions to modify mailbox */
-	unsigned int backend_readonly:1;
 	/* Mailbox is being deleted */
 	unsigned int deleting:1;
 	/* Mailbox was already marked as deleted within this allocation. */
--- a/src/lib-storage/mail-storage.c	Mon Dec 06 01:27:11 2010 +0000
+++ b/src/lib-storage/mail-storage.c	Mon Dec 06 01:47:50 2010 +0000
@@ -652,7 +652,6 @@
 
 	box->opened = FALSE;
 	box->mailbox_deleted = FALSE;
-	box->backend_readonly = FALSE;
 	array_clear(&box->search_results);
 }