changeset 12521:b22766c1aa51

lib-storage: Don't allocate index until mailbox_open()
author Timo Sirainen <tss@iki.fi>
date Sun, 05 Dec 2010 23:44:38 +0000
parents b26d6da05d48
children a4e683282d1a
files src/lib-storage/index/cydir/cydir-storage.c src/lib-storage/index/dbox-common/dbox-storage.c src/lib-storage/index/dbox-multi/mdbox-storage.c src/lib-storage/index/dbox-single/sdbox-storage.c src/lib-storage/index/index-storage.c src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/mbox/mbox-storage.c src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.c
diffstat 9 files changed, 115 insertions(+), 67 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/cydir/cydir-storage.c	Sun Dec 05 23:18:55 2010 +0000
+++ b/src/lib-storage/index/cydir/cydir-storage.c	Sun Dec 05 23:44:38 2010 +0000
@@ -55,10 +55,6 @@
 
 	index_storage_mailbox_alloc(&mbox->box, name, flags,
 				    CYDIR_INDEX_PREFIX);
-	mail_index_set_fsync_mode(mbox->box.index,
-				  storage->set->parsed_fsync_mode,
-				  MAIL_INDEX_SYNC_TYPE_APPEND |
-				  MAIL_INDEX_SYNC_TYPE_EXPUNGE);
 
 	ibox = INDEX_STORAGE_CONTEXT(&mbox->box);
 	ibox->save_commit_pre = cydir_transaction_save_commit_pre;
@@ -89,7 +85,13 @@
 					  box_path);
 		return -1;
 	}
-	return index_storage_mailbox_open(box, FALSE);
+	if (index_storage_mailbox_open(box, FALSE) < 0)
+		return -1;
+	mail_index_set_fsync_mode(box->index,
+				  box->storage->set->parsed_fsync_mode,
+				  MAIL_INDEX_SYNC_TYPE_APPEND |
+				  MAIL_INDEX_SYNC_TYPE_EXPUNGE);
+	return 0;
 }
 
 static int
--- a/src/lib-storage/index/dbox-common/dbox-storage.c	Sun Dec 05 23:18:55 2010 +0000
+++ b/src/lib-storage/index/dbox-common/dbox-storage.c	Sun Dec 05 23:44:38 2010 +0000
@@ -115,9 +115,9 @@
 {
 	const char *box_path = mailbox_get_path(box);
 
-	if (dbox_cleanup_if_exists(box->list, box_path)) {
-		return index_storage_mailbox_open(box, FALSE);
-	} else if (errno == ENOENT) {
+	if (dbox_cleanup_if_exists(box->list, box_path))
+		;
+	else if (errno == ENOENT) {
 		mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
 			T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
 		return -1;
@@ -130,6 +130,14 @@
 					  "stat(%s) failed: %m", box_path);
 		return -1;
 	}
+
+	if (index_storage_mailbox_open(box, FALSE) < 0)
+		return -1;
+	mail_index_set_fsync_mode(box->index,
+				  box->storage->set->parsed_fsync_mode,
+				  MAIL_INDEX_SYNC_TYPE_APPEND |
+				  MAIL_INDEX_SYNC_TYPE_EXPUNGE);
+	return 0;
 }
 
 static int dir_is_empty(struct mail_storage *storage, const char *path)
--- a/src/lib-storage/index/dbox-multi/mdbox-storage.c	Sun Dec 05 23:18:55 2010 +0000
+++ b/src/lib-storage/index/dbox-multi/mdbox-storage.c	Sun Dec 05 23:44:38 2010 +0000
@@ -101,10 +101,6 @@
 	mbox->box.mail_vfuncs = &mdbox_mail_vfuncs;
 
 	index_storage_mailbox_alloc(&mbox->box, name, flags, DBOX_INDEX_PREFIX);
-	mail_index_set_fsync_mode(mbox->box.index,
-				  storage->set->parsed_fsync_mode,
-				  MAIL_INDEX_SYNC_TYPE_APPEND |
-				  MAIL_INDEX_SYNC_TYPE_EXPUNGE);
 
 	ibox = INDEX_STORAGE_CONTEXT(&mbox->box);
 	ibox->save_commit_pre = mdbox_transaction_save_commit_pre;
@@ -114,6 +110,16 @@
 		MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY;
 
 	mbox->storage = (struct mdbox_storage *)storage;
+	return &mbox->box;
+}
+
+static int mdbox_mailbox_open(struct mailbox *box)
+{
+	struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)box;
+
+	if (dbox_mailbox_open(box) < 0)
+		return -1;
+
 	mbox->ext_id =
 		mail_index_ext_register(mbox->box.index, "mdbox", 0,
 					sizeof(struct mdbox_mail_index_record),
@@ -124,7 +130,7 @@
 	mbox->guid_ext_id =
 		mail_index_ext_register(mbox->box.index, "guid",
 					0, MAIL_GUID_128_SIZE, 1);
-	return &mbox->box;
+	return 0;
 }
 
 static void mdbox_mailbox_close(struct mailbox *box)
@@ -389,7 +395,7 @@
 		index_storage_is_readonly,
 		index_storage_allow_new_keywords,
 		index_storage_mailbox_enable,
-		dbox_mailbox_open,
+		mdbox_mailbox_open,
 		mdbox_mailbox_close,
 		index_storage_mailbox_free,
 		dbox_mailbox_create,
--- a/src/lib-storage/index/dbox-single/sdbox-storage.c	Sun Dec 05 23:18:55 2010 +0000
+++ b/src/lib-storage/index/dbox-single/sdbox-storage.c	Sun Dec 05 23:44:38 2010 +0000
@@ -48,10 +48,6 @@
 	mbox->box.mail_vfuncs = &sdbox_mail_vfuncs;
 
 	index_storage_mailbox_alloc(&mbox->box, name, flags, DBOX_INDEX_PREFIX);
-	mail_index_set_fsync_mode(mbox->box.index,
-				  storage->set->parsed_fsync_mode,
-				  MAIL_INDEX_SYNC_TYPE_APPEND |
-				  MAIL_INDEX_SYNC_TYPE_EXPUNGE);
 
 	ibox = INDEX_STORAGE_CONTEXT(&mbox->box);
 	ibox->save_commit_pre = sdbox_transaction_save_commit_pre;
@@ -61,9 +57,6 @@
 		MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY;
 
 	mbox->storage = (struct sdbox_storage *)storage;
-	mbox->hdr_ext_id =
-		mail_index_ext_register(mbox->box.index, "dbox-hdr",
-					sizeof(struct sdbox_index_header), 0, 0);
 	return &mbox->box;
 }
 
@@ -226,6 +219,9 @@
 
 	if (dbox_mailbox_open(box) < 0)
 		return -1;
+	mbox->hdr_ext_id =
+		mail_index_ext_register(box->index, "dbox-hdr",
+					sizeof(struct sdbox_index_header), 0, 0);
 
 	/* get/generate mailbox guid */
 	if (sdbox_read_header(mbox, &hdr, FALSE) < 0) {
--- a/src/lib-storage/index/index-storage.c	Sun Dec 05 23:18:55 2010 +0000
+++ b/src/lib-storage/index/index-storage.c	Sun Dec 05 23:44:38 2010 +0000
@@ -27,22 +27,6 @@
 struct index_storage_module index_storage_module =
 	MODULE_CONTEXT_INIT(&mail_storage_module_register);
 
-static struct mail_index *
-index_storage_alloc(struct mailbox_list *list, const char *name,
-		    enum mailbox_flags flags, const char *prefix)
-{
-	const char *index_dir, *mailbox_path;
-
-	mailbox_path = mailbox_list_get_path(list, name,
-					     MAILBOX_LIST_PATH_TYPE_MAILBOX);
-	index_dir = (flags & MAILBOX_FLAG_NO_INDEX_FILES) != 0 ? "" :
-		mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_INDEX);
-	if (*index_dir == '\0')
-		index_dir = NULL;
-
-	return mail_index_alloc_cache_get(mailbox_path, index_dir, prefix);
-}
-
 static void set_cache_decisions(const char *set, const char *fields,
 				enum mail_cache_decision_type dec)
 {
@@ -150,6 +134,23 @@
 	ibox->last_notify_type = MAILBOX_LOCK_NOTIFY_NONE;
 }
 
+static struct mail_index *
+index_mailbox_alloc_index(struct mailbox *box)
+{
+	const char *index_dir, *mailbox_path;
+
+	mailbox_path = mailbox_list_get_path(box->list, box->name,
+					     MAILBOX_LIST_PATH_TYPE_MAILBOX);
+	index_dir = (box->flags & MAILBOX_FLAG_NO_INDEX_FILES) != 0 ? "" :
+		mailbox_list_get_path(box->list, box->name,
+				      MAILBOX_LIST_PATH_TYPE_INDEX);
+	if (*index_dir == '\0')
+		index_dir = NULL;
+
+	return mail_index_alloc_cache_get(mailbox_path, index_dir,
+					  box->index_prefix);
+}
+
 int index_storage_mailbox_open(struct mailbox *box, bool move_to_memory)
 {
 	struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box);
@@ -175,6 +176,13 @@
 		return -1;
 	}
 
+	box->index = index_mailbox_alloc_index(box);
+	mail_index_set_fsync_mode(box->index,
+				  box->storage->set->parsed_fsync_mode, 0);
+	mail_index_set_lock_method(box->index,
+		box->storage->set->parsed_lock_method,
+		mail_storage_get_lock_timeout(box->storage, -1U));
+
 	/* make sure mail_index_set_permissions() has been called */
 	(void)mailbox_get_permissions(box);
 
@@ -232,7 +240,9 @@
 	vname = t_str_new(128);
 	mail_namespace_get_vname(box->list->ns, vname, name);
 	box->vname = p_strdup(box->pool, str_c(vname));
+
 	box->flags = flags;
+	box->index_prefix = p_strdup(box->pool, index_prefix);
 
 	p_array_init(&box->search_results, box->pool, 16);
 	array_create(&box->module_contexts,
@@ -244,16 +254,10 @@
 	ibox->next_lock_notify = time(NULL) + LOCK_NOTIFY_INTERVAL;
 	MODULE_CONTEXT_SET(box, index_storage_module, ibox);
 
-	box->index = index_storage_alloc(box->list, name, flags, index_prefix);
 	box->inbox_user = strcmp(name, "INBOX") == 0 &&
 		(box->list->ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0;
 	box->inbox_any = strcmp(name, "INBOX") == 0 &&
 		(box->list->ns->flags & NAMESPACE_FLAG_INBOX_ANY) != 0;
-	mail_index_set_fsync_mode(box->index,
-				  box->storage->set->parsed_fsync_mode, 0);
-	mail_index_set_lock_method(box->index,
-		box->storage->set->parsed_lock_method,
-		mail_storage_get_lock_timeout(box->storage, -1U));
 }
 
 int index_storage_mailbox_enable(struct mailbox *box,
@@ -295,7 +299,8 @@
 
 void index_storage_mailbox_free(struct mailbox *box)
 {
-	mail_index_alloc_cache_unref(&box->index);
+	if (box->index != NULL)
+		mail_index_alloc_cache_unref(&box->index);
 }
 
 void index_storage_mailbox_update_cache_fields(struct mailbox *box,
@@ -499,6 +504,8 @@
 {
 	unsigned int i, idx;
 
+	i_assert(box->opened);
+
 	/* if it already exists, skip validity checks */
 	if (mail_index_keyword_lookup(box->index, keyword, &idx))
 		return TRUE;
@@ -549,6 +556,8 @@
 	const char *error;
 	unsigned int i;
 
+	i_assert(box->opened);
+
 	for (i = 0; keywords[i] != NULL; i++) {
 		if (mailbox_keyword_is_valid(box, keywords[i], &error))
 			continue;
@@ -571,10 +580,12 @@
 }
 
 struct mail_keywords *
-index_keywords_create_from_indexes(struct mailbox *_box,
+index_keywords_create_from_indexes(struct mailbox *box,
 				   const ARRAY_TYPE(keyword_indexes) *idx)
 {
-	return mail_index_keywords_create_from_indexes(_box->index, idx);
+	i_assert(box->opened);
+
+	return mail_index_keywords_create_from_indexes(box->index, idx);
 }
 
 void index_keywords_ref(struct mail_keywords *keywords)
--- a/src/lib-storage/index/maildir/maildir-storage.c	Sun Dec 05 23:18:55 2010 +0000
+++ b/src/lib-storage/index/maildir/maildir-storage.c	Sun Dec 05 23:44:38 2010 +0000
@@ -286,9 +286,6 @@
 	ibox->save_rollback = maildir_transaction_save_rollback;
 
 	mbox->storage = (struct maildir_storage *)storage;
-	mbox->maildir_ext_id =
-		mail_index_ext_register(mbox->box.index, "maildir",
-					sizeof(mbox->maildir_hdr), 0, 0);
 	return &mbox->box;
 }
 
@@ -316,7 +313,13 @@
 	if (access(t_strconcat(box_path, "/cur", NULL), W_OK) < 0 &&
 	    errno == EACCES)
 		mbox->box.backend_readonly = TRUE;
-	return index_storage_mailbox_open(box, FALSE);
+	if (index_storage_mailbox_open(box, FALSE) < 0)
+		return -1;
+
+	mbox->maildir_ext_id =
+		mail_index_ext_register(mbox->box.index, "maildir",
+					sizeof(mbox->maildir_hdr), 0, 0);
+	return 0;
 }
 
 static int maildir_mailbox_open(struct mailbox *box)
--- a/src/lib-storage/index/mbox/mbox-storage.c	Sun Dec 05 23:18:55 2010 +0000
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Sun Dec 05 23:44:38 2010 +0000
@@ -369,13 +369,6 @@
 	mbox->storage = (struct mbox_storage *)storage;
 	mbox->mbox_fd = -1;
 	mbox->mbox_lock_type = F_UNLCK;
-	mbox->mbox_ext_idx =
-		mail_index_ext_register(mbox->box.index, "mbox",
-					sizeof(mbox->mbox_hdr),
-					sizeof(uint64_t), sizeof(uint64_t));
-	mbox->md5hdr_ext_idx =
-		mail_index_ext_register(mbox->box.index, "header-md5",
-					0, 16, 1);
 
 	if ((storage->flags & MAIL_STORAGE_FLAG_KEEP_HEADER_MD5) != 0)
 		mbox->mbox_save_md5 = TRUE;
@@ -387,6 +380,22 @@
 	mbox_dotlock_touch(mbox);
 }
 
+static int
+mbox_mailbox_open_finish(struct mbox_mailbox *mbox, bool move_to_memory)
+{
+	if (index_storage_mailbox_open(&mbox->box, move_to_memory) < 0)
+		return -1;
+
+	mbox->mbox_ext_idx =
+		mail_index_ext_register(mbox->box.index, "mbox",
+					sizeof(mbox->mbox_hdr),
+					sizeof(uint64_t), sizeof(uint64_t));
+	mbox->md5hdr_ext_idx =
+		mail_index_ext_register(mbox->box.index, "header-md5",
+					0, 16, 1);
+	return 0;
+}
+
 static int mbox_mailbox_open_existing(struct mbox_mailbox *mbox)
 {
 	struct mailbox *box = &mbox->box;
@@ -420,7 +429,7 @@
 					    mbox_lock_touch_timeout, mbox);
 		}
 	}
-	return index_storage_mailbox_open(box, move_to_memory);
+	return mbox_mailbox_open_finish(mbox, move_to_memory);
 }
 
 static int mbox_mailbox_open(struct mailbox *box)
@@ -434,7 +443,7 @@
 		mbox->mbox_file_stream = box->input;
 		mbox->box.backend_readonly = TRUE;
 		mbox->no_mbox_file = TRUE;
-		return index_storage_mailbox_open(box, FALSE);
+		return mbox_mailbox_open_finish(mbox, FALSE);
 	}
 
 	ret = stat(mailbox_get_path(box), &st);
--- a/src/lib-storage/mail-storage-private.h	Sun Dec 05 23:18:55 2010 +0000
+++ b/src/lib-storage/mail-storage-private.h	Sun Dec 05 23:44:38 2010 +0000
@@ -230,10 +230,14 @@
 	gid_t file_create_gid;
 	/* origin (e.g. path) where the file_create_gid was got from */
 	const char *file_create_gid_origin;
+
+	bool mail_index_permissions_set;
 };
 
 struct mailbox {
 	const char *name;
+	/* mailbox's virtual name (from mail_namespace_get_vname()) */
+	const char *vname;
 	struct mail_storage *storage;
 	struct mailbox_list *list;
 
@@ -253,9 +257,8 @@
 	/* default vfuncs for new struct mails. */
 	const struct mail_vfuncs *mail_vfuncs;
 
-	/* mailbox's virtual name (from mail_namespace_get_vname()) */
-	const char *vname;
 	struct istream *input;
+	const char *index_prefix;
 	enum mailbox_flags flags;
 	unsigned int transaction_count;
 	enum mailbox_feature enabled_features;
--- a/src/lib-storage/mail-storage.c	Sun Dec 05 23:18:55 2010 +0000
+++ b/src/lib-storage/mail-storage.c	Sun Dec 05 23:44:38 2010 +0000
@@ -1470,32 +1470,42 @@
 	return box->_path;
 }
 
-const struct mailbox_permissions *mailbox_get_permissions(struct mailbox *box)
+static void mailbox_get_permissions_if_not_set(struct mailbox *box)
 {
 	const char *origin, *dir_origin;
 	gid_t dir_gid;
 
 	if (box->_perm.file_create_mode != 0)
-		return &box->_perm;
+		return;
 
 	if (box->input != NULL) {
 		box->_perm.file_create_mode = 0600;
 		box->_perm.dir_create_mode = 0700;
 		box->_perm.file_create_gid = (gid_t)-1;
 		box->_perm.file_create_gid_origin = "defaults";
-		return &box->_perm;
+		return;
 	}
 
 	mailbox_list_get_permissions(box->list, box->name,
 				     &box->_perm.file_create_mode,
 				     &box->_perm.file_create_gid, &origin);
-	mail_index_set_permissions(box->index, box->_perm.file_create_mode,
-				   box->_perm.file_create_gid, origin);
-
 	box->_perm.file_create_gid_origin = p_strdup(box->pool, origin);
 	mailbox_list_get_dir_permissions(box->list, box->name,
 					 &box->_perm.dir_create_mode,
 					 &dir_gid, &dir_origin);
+}
+
+const struct mailbox_permissions *mailbox_get_permissions(struct mailbox *box)
+{
+	mailbox_get_permissions_if_not_set(box);
+
+	if (!box->_perm.mail_index_permissions_set && box->index != NULL) {
+		box->_perm.mail_index_permissions_set = TRUE;
+		mail_index_set_permissions(box->index,
+					   box->_perm.file_create_mode,
+					   box->_perm.file_create_gid,
+					   box->_perm.file_create_gid_origin);
+	}
 	return &box->_perm;
 }