dovecot-2.2: lib-storage: Changed mailbox_attribute_get/set() AP...

dovecot at dovecot.org dovecot at dovecot.org
Thu Mar 14 15:41:49 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/f3cd9e5cbe99
changeset: 16024:f3cd9e5cbe99
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Mar 14 15:32:14 2013 +0200
description:
lib-storage: Changed mailbox_attribute_get/set() APIs to have a transaction and update index.
The _get() doesn't currently actually use the transaction. It was mainly put
there for future use where it could be useful. It's also possible that
_iter() will need a transaction also. For now these decisions seem good
enough.

diffstat:

 src/lib-imap-urlauth/imap-urlauth-backend.c |  60 +++++++++++++++++++++----
 src/lib-storage/index/index-attribute.c     |  69 ++++++++++++++++++++++------
 src/lib-storage/index/index-storage.c       |  49 ++++++++++---------
 src/lib-storage/index/index-storage.h       |   4 +-
 src/lib-storage/index/index-transaction.c   |  19 +++++++-
 src/lib-storage/mail-storage-private.h      |   9 ++-
 src/lib-storage/mail-storage.c              |  18 ++++---
 src/lib-storage/mail-storage.h              |  20 ++++++--
 8 files changed, 180 insertions(+), 68 deletions(-)

diffs (truncated from 447 to 300 lines):

diff -r db0136374bb0 -r f3cd9e5cbe99 src/lib-imap-urlauth/imap-urlauth-backend.c
--- a/src/lib-imap-urlauth/imap-urlauth-backend.c	Thu Mar 14 15:29:18 2013 +0200
+++ b/src/lib-imap-urlauth/imap-urlauth-backend.c	Thu Mar 14 15:32:14 2013 +0200
@@ -12,11 +12,14 @@
 
 #define IMAP_URLAUTH_KEY MAILBOX_ATTRIBUTE_PREFIX_DOVECOT"imap-urlauth"
 
-int imap_urlauth_backend_get_mailbox_key(struct mailbox *box, bool create,
-					 unsigned char mailbox_key_r[IMAP_URLAUTH_KEY_LEN],
-					 const char **error_r,
-					 enum mail_error *error_code_r)
+static int
+imap_urlauth_backend_trans_get_mailbox_key(struct mailbox_transaction_context *trans,
+					   bool create,
+					   unsigned char mailbox_key_r[IMAP_URLAUTH_KEY_LEN],
+					   const char **error_r,
+					   enum mail_error *error_code_r)
 {
+	struct mailbox *box = mailbox_transaction_get_mailbox(trans);
 	struct mail_user *user = mail_storage_get_user(mailbox_get_storage(box));
 	struct mail_attribute_value urlauth_key;
 	const char *mailbox_key_hex = NULL;
@@ -26,7 +29,7 @@
 	*error_r = "Internal server error";
 	*error_code_r = MAIL_ERROR_TEMP;
 
-	ret = mailbox_attribute_get(box, MAIL_ATTRIBUTE_TYPE_PRIVATE,
+	ret = mailbox_attribute_get(trans, MAIL_ATTRIBUTE_TYPE_PRIVATE,
 				    IMAP_URLAUTH_KEY, &urlauth_key);
 	if (ret < 0)
 		return -1;
@@ -44,7 +47,7 @@
 		random_fill(mailbox_key_r, IMAP_URLAUTH_KEY_LEN);
 		mailbox_key_hex = binary_to_hex(mailbox_key_r,
 						IMAP_URLAUTH_KEY_LEN);
-		ret = mailbox_attribute_set(box, MAIL_ATTRIBUTE_TYPE_PRIVATE,
+		ret = mailbox_attribute_set(trans, MAIL_ATTRIBUTE_TYPE_PRIVATE,
 					    IMAP_URLAUTH_KEY, mailbox_key_hex);
 		if (ret < 0)
 			return -1;
@@ -69,10 +72,48 @@
 	return 1;
 }
 
+int imap_urlauth_backend_get_mailbox_key(struct mailbox *box, bool create,
+					 unsigned char mailbox_key_r[IMAP_URLAUTH_KEY_LEN],
+					 const char **error_r,
+					 enum mail_error *error_code_r)
+{
+	struct mailbox_transaction_context *t;
+	int ret;
+
+	t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL);
+	ret = imap_urlauth_backend_trans_get_mailbox_key(t, create, mailbox_key_r, error_r, error_code_r);
+	if (mailbox_transaction_commit(&t) < 0)
+		ret = -1;
+	return ret;
+}
+
 int imap_urlauth_backend_reset_mailbox_key(struct mailbox *box)
 {
-	return mailbox_attribute_unset(box, MAIL_ATTRIBUTE_TYPE_PRIVATE,
-				       IMAP_URLAUTH_KEY) < 0 ? -1 : 1;
+	struct mailbox_transaction_context *t;
+	int ret;
+
+	t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL);
+	ret = mailbox_attribute_unset(t, MAIL_ATTRIBUTE_TYPE_PRIVATE,
+				      IMAP_URLAUTH_KEY) < 0 ? -1 : 1;
+	if (mailbox_transaction_commit(&t) < 0)
+		ret = -1;
+	return ret;
+}
+
+static int imap_urlauth_backend_mailbox_reset_key(struct mailbox *box)
+{
+	const char *errstr;
+	enum mail_error error;
+
+	if (mailbox_open(box) < 0) {
+		errstr = mailbox_get_last_error(box, &error);
+		if (error == MAIL_ERROR_NOTFOUND || error == MAIL_ERROR_PERM)
+			return 0;
+		i_error("urlauth key reset: Couldn't open mailbox %s: %s",
+			mailbox_get_vname(box), errstr);
+		return -1;
+	}
+	return imap_urlauth_backend_reset_mailbox_key(box) < 0 ? -1 : 0;
 }
 
 int imap_urlauth_backend_reset_all_keys(struct mail_user *user)
@@ -90,8 +131,7 @@
 						 MAILBOX_LIST_ITER_RETURN_NO_FLAGS);
 	while ((info = mailbox_list_iter_next(iter)) != NULL) {
 		box = mailbox_alloc(info->ns->list, info->vname, 0);
-		if (mailbox_attribute_unset(box, MAIL_ATTRIBUTE_TYPE_PRIVATE,
-					    IMAP_URLAUTH_KEY) < 0)
+		if (imap_urlauth_backend_mailbox_reset_key(box) < 0)
 			ret = -1;
 		mailbox_free(&box);
 	}
diff -r db0136374bb0 -r f3cd9e5cbe99 src/lib-storage/index/index-attribute.c
--- a/src/lib-storage/index/index-attribute.c	Thu Mar 14 15:29:18 2013 +0200
+++ b/src/lib-storage/index/index-attribute.c	Thu Mar 14 15:32:14 2013 +0200
@@ -147,33 +147,66 @@
 	i_unreached();
 }
 
-int index_storage_attribute_set(struct mailbox *box,
+static int
+index_storage_attribute_get_dict_trans(struct mailbox_transaction_context *t,
+				       enum mail_attribute_type type,
+				       struct dict_transaction_context **dtrans_r,
+				       const char **mailbox_prefix_r)
+{
+	struct dict_transaction_context **dtransp = NULL;
+	struct dict *dict;
+
+	switch (type) {
+	case MAIL_ATTRIBUTE_TYPE_PRIVATE:
+		dtransp = &t->attr_pvt_trans;
+		break;
+	case MAIL_ATTRIBUTE_TYPE_SHARED:
+		dtransp = &t->attr_shared_trans;
+		break;
+	}
+	i_assert(dtransp != NULL);
+
+	if (index_storage_get_dict(t->box, type, &dict, mailbox_prefix_r) < 0)
+		return -1;
+	*dtransp = *dtrans_r = dict_transaction_begin(dict);
+	return 0;
+}
+
+int index_storage_attribute_set(struct mailbox_transaction_context *t,
 				enum mail_attribute_type type,
 				const char *key, const char *value)
 {
 	struct dict_transaction_context *dtrans;
-	struct dict *dict;
 	const char *mailbox_prefix;
+	bool pvt = type == MAIL_ATTRIBUTE_TYPE_PRIVATE;
 
-	if (index_storage_get_dict(box, type, &dict, &mailbox_prefix) < 0)
+	if (strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT,
+		    strlen(MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT)) == 0) {
+		mail_storage_set_error(t->box->storage, MAIL_ERROR_PARAMS,
+			"Internal attributes cannot be changed directly");
+		return -1;
+	}
+
+	if (index_storage_attribute_get_dict_trans(t, type, &dtrans,
+						   &mailbox_prefix) < 0)
 		return -1;
 
 	T_BEGIN {
-		key = key_get_prefixed(type, mailbox_prefix, key);
-		dtrans = dict_transaction_begin(dict);
-		if (value != NULL)
-			dict_set(dtrans, key, value);
-		else
-			dict_unset(dtrans, key);
+		const char *prefixed_key =
+			key_get_prefixed(type, mailbox_prefix, key);
+
+		if (value != NULL) {
+			dict_set(dtrans, prefixed_key, value);
+			mail_index_attribute_set(t->itrans, pvt, key);
+		} else {
+			dict_unset(dtrans, prefixed_key);
+			mail_index_attribute_unset(t->itrans, pvt, key);
+		}
 	} T_END;
-	if (dict_transaction_commit(&dtrans) < 0) {
-		mail_storage_set_internal_error(box->storage);
-		return -1;
-	}
 	return 0;
 }
 
-int index_storage_attribute_get(struct mailbox *box,
+int index_storage_attribute_get(struct mailbox_transaction_context *t,
 				enum mail_attribute_type type, const char *key,
 				struct mail_attribute_value *value_r)
 {
@@ -183,14 +216,18 @@
 
 	memset(value_r, 0, sizeof(*value_r));
 
-	if (index_storage_get_dict(box, type, &dict, &mailbox_prefix) < 0)
+	if (strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT,
+		    strlen(MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT)) == 0)
+		return 0;
+
+	if (index_storage_get_dict(t->box, type, &dict, &mailbox_prefix) < 0)
 		return -1;
 
 	ret = dict_lookup(dict, pool_datastack_create(),
 			  key_get_prefixed(type, mailbox_prefix, key),
 			  &value_r->value);
 	if (ret < 0) {
-		mail_storage_set_internal_error(box->storage);
+		mail_storage_set_internal_error(t->box->storage);
 		return -1;
 	}
 	return ret;
diff -r db0136374bb0 -r f3cd9e5cbe99 src/lib-storage/index/index-storage.c
--- a/src/lib-storage/index/index-storage.c	Thu Mar 14 15:29:18 2013 +0200
+++ b/src/lib-storage/index/index-storage.c	Thu Mar 14 15:32:14 2013 +0200
@@ -601,7 +601,25 @@
 	return 0;
 }
 
-static int mailbox_expunge_all_mails(struct mailbox *box)
+static int
+mailbox_delete_all_attributes(struct mailbox_transaction_context *t,
+			      enum mail_attribute_type type)
+{
+	struct mailbox_attribute_iter *iter;
+	const char *key;
+	int ret = 0;
+
+	iter = mailbox_attribute_iter_init(t->box, type, "");
+	while ((key = mailbox_attribute_iter_next(iter)) != NULL) {
+		if (mailbox_attribute_unset(t, type, key) < 0)
+			ret = -1;
+	}
+	if (mailbox_attribute_iter_deinit(&iter) < 0)
+		ret = -1;
+	return ret;
+}
+
+static int mailbox_expunge_all_data(struct mailbox *box)
 {
 	struct mail_search_context *ctx;
         struct mailbox_transaction_context *t;
@@ -624,26 +642,15 @@
 		mailbox_transaction_rollback(&t);
 		return -1;
 	}
+
+	if (mailbox_delete_all_attributes(t, MAIL_ATTRIBUTE_TYPE_PRIVATE) < 0 ||
+	    mailbox_delete_all_attributes(t, MAIL_ATTRIBUTE_TYPE_SHARED) < 0) {
+		mailbox_transaction_rollback(&t);
+		return -1;
+	}
 	return mailbox_transaction_commit(&t);
 }
 
-static int
-mailbox_delete_all_attributes(struct mailbox *box, enum mail_attribute_type type)
-{
-	struct mailbox_attribute_iter *iter;
-	const char *key;
-	int ret = 0;
-
-	iter = mailbox_attribute_iter_init(box, type, "");
-	while ((key = mailbox_attribute_iter_next(iter)) != NULL) {
-		if (mailbox_attribute_unset(box, type, key) < 0)
-			ret = -1;
-	}
-	if (mailbox_attribute_iter_deinit(&iter) < 0)
-		ret = -1;
-	return ret;
-}
-
 int index_storage_mailbox_delete(struct mailbox *box)
 {
 	struct mailbox_metadata metadata;
@@ -672,11 +679,7 @@
 	*/
 
 	if (!box->deleting_must_be_empty) {
-		if (mailbox_expunge_all_mails(box) < 0)
-			return -1;
-		if (mailbox_delete_all_attributes(box, MAIL_ATTRIBUTE_TYPE_PRIVATE) < 0)
-			return -1;
-		if (mailbox_delete_all_attributes(box, MAIL_ATTRIBUTE_TYPE_SHARED) < 0)
+		if (mailbox_expunge_all_data(box) < 0)
 			return -1;
 	}
 	if (mailbox_mark_index_deleted(box, TRUE) < 0)
diff -r db0136374bb0 -r f3cd9e5cbe99 src/lib-storage/index/index-storage.h
--- a/src/lib-storage/index/index-storage.h	Thu Mar 14 15:29:18 2013 +0200
+++ b/src/lib-storage/index/index-storage.h	Thu Mar 14 15:32:14 2013 +0200
@@ -116,10 +116,10 @@
 			       enum mailbox_metadata_items items,
 			       struct mailbox_metadata *metadata_r);
 
-int index_storage_attribute_set(struct mailbox *box,
+int index_storage_attribute_set(struct mailbox_transaction_context *t,
 				enum mail_attribute_type type,
 				const char *key, const char *value);
-int index_storage_attribute_get(struct mailbox *box,
+int index_storage_attribute_get(struct mailbox_transaction_context *t,
 				enum mail_attribute_type type, const char *key,
 				struct mail_attribute_value *value_r);
 struct mailbox_attribute_iter *
diff -r db0136374bb0 -r f3cd9e5cbe99 src/lib-storage/index/index-transaction.c
--- a/src/lib-storage/index/index-transaction.c	Thu Mar 14 15:29:18 2013 +0200


More information about the dovecot-cvs mailing list