From: Aki Tuomi Date: Thu, 4 Aug 2016 06:51:40 +0000 (+0300) Subject: lib-storage: Change mailbox_attribute_get* API X-Git-Tag: 2.3.0.rc1~3198 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9f37ef2a9192e7d47e3d7ac959080fd01120f2e9;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Change mailbox_attribute_get* API lib-storage/mailbox-attribute.h: mailbox_attribute_get() and mailbox_attribute_get_stream() now has struct mailbox_transaction_context as their first parameter. This isn't good for performance, because opening a transaction requires opening mailbox indexes first. But reading attributes wouldn't actually require opening the indexes, so this is just wasteful. --- diff --git a/src/lib-storage/index/index-attribute.c b/src/lib-storage/index/index-attribute.c index 1c07a6cb3d..a9903256eb 100644 --- a/src/lib-storage/index/index-attribute.c +++ b/src/lib-storage/index/index-attribute.c @@ -191,7 +191,8 @@ index_storage_attribute_get_dict_trans(struct mailbox_transaction_context *t, int index_storage_attribute_set(struct mailbox_transaction_context *t, enum mail_attribute_type type, const char *key, - const struct mail_attribute_value *value) + const struct mail_attribute_value *value, + bool internal_attribute) { struct dict_transaction_context *dtrans; const char *mailbox_prefix; @@ -199,7 +200,7 @@ int index_storage_attribute_set(struct mailbox_transaction_context *t, time_t ts = value->last_change != 0 ? value->last_change : ioloop_time; int ret = 0; - if (!t->internal_attribute && + if (!internal_attribute && !MAILBOX_ATTRIBUTE_KEY_IS_USER_ACCESSIBLE(key)) { mail_storage_set_error(t->box->storage, MAIL_ERROR_PARAMS, "Internal attributes cannot be changed directly"); @@ -230,9 +231,10 @@ int index_storage_attribute_set(struct mailbox_transaction_context *t, return ret; } -int index_storage_attribute_get(struct mailbox_transaction_context *t, +int index_storage_attribute_get(struct mailbox *box, enum mail_attribute_type type, const char *key, - struct mail_attribute_value *value_r) + struct mail_attribute_value *value_r, + bool internal_attribute) { struct dict *dict; const char *mailbox_prefix, *error; @@ -240,18 +242,18 @@ int index_storage_attribute_get(struct mailbox_transaction_context *t, memset(value_r, 0, sizeof(*value_r)); - if (!t->internal_attribute && + if (!internal_attribute && !MAILBOX_ATTRIBUTE_KEY_IS_USER_ACCESSIBLE(key)) return 0; - if (index_storage_get_dict(t->box, type, &dict, &mailbox_prefix) < 0) + if (index_storage_get_dict(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, &error); if (ret < 0) { - mail_storage_set_critical(t->box->storage, + mail_storage_set_critical(box->storage, "Failed to set attribute %s: %s", key, error); return -1; } diff --git a/src/lib-storage/index/index-storage.h b/src/lib-storage/index/index-storage.h index ab1575ebd6..7a2b99dd48 100644 --- a/src/lib-storage/index/index-storage.h +++ b/src/lib-storage/index/index-storage.h @@ -120,10 +120,12 @@ int index_mailbox_get_physical_size(struct mailbox *box, int index_storage_attribute_set(struct mailbox_transaction_context *t, enum mail_attribute_type type, const char *key, - const struct mail_attribute_value *value); -int index_storage_attribute_get(struct mailbox_transaction_context *t, + const struct mail_attribute_value *value, + bool internal_attribute); +int index_storage_attribute_get(struct mailbox *box, enum mail_attribute_type type, const char *key, - struct mail_attribute_value *value_r); + struct mail_attribute_value *value_r, + bool internal_attribute); struct mailbox_attribute_iter * index_storage_attribute_iter_init(struct mailbox *box, enum mail_attribute_type type, diff --git a/src/lib-storage/mail-storage-private.h b/src/lib-storage/mail-storage-private.h index 072f2022b9..6ea7628564 100644 --- a/src/lib-storage/mail-storage-private.h +++ b/src/lib-storage/mail-storage-private.h @@ -194,10 +194,12 @@ struct mailbox_vfuncs { int (*attribute_set)(struct mailbox_transaction_context *t, enum mail_attribute_type type, const char *key, - const struct mail_attribute_value *value); - int (*attribute_get)(struct mailbox_transaction_context *t, + const struct mail_attribute_value *value, + bool internal_attribute); + int (*attribute_get)(struct mailbox *box, enum mail_attribute_type type, const char *key, - struct mail_attribute_value *value_r); + struct mail_attribute_value *value_r, + bool internal_attribute); struct mailbox_attribute_iter * (*attribute_iter_init)(struct mailbox *box, enum mail_attribute_type type, @@ -575,8 +577,6 @@ struct mailbox_transaction_context { bool stats_track:1; /* We've done some non-transactional (e.g. dovecot-uidlist updates) */ bool nontransactional_changes:1; - /* FIXME: v2.3: this should be in attribute_get/set() parameters */ - bool internal_attribute:1; }; union mail_search_module_context { diff --git a/src/lib-storage/mailbox-attribute-internal.c b/src/lib-storage/mailbox-attribute-internal.c index 62e97e0082..a9bc788e85 100644 --- a/src/lib-storage/mailbox-attribute-internal.c +++ b/src/lib-storage/mailbox-attribute-internal.c @@ -11,11 +11,12 @@ /* /private/specialuse (RFC 6154) */ static int -mailbox_attribute_specialuse_get(struct mailbox_transaction_context *t, - const char *key ATTR_UNUSED, - struct mail_attribute_value *value_r) +mailbox_attribute_specialuse_get(struct mailbox *box, + const char *key ATTR_UNUSED, + struct mail_attribute_value *value_r, + bool internal_attribute ATTR_UNUSED) { - const struct mailbox_settings *set = t->box->set; + const struct mailbox_settings *set = box->set; if (set == NULL || *set->special_use == '\0') return 0; @@ -36,11 +37,12 @@ iattr_mbox_prv_special_use = { /* /private/comment, /shared/comment (RFC 5464) */ static int -mailbox_attribute_comment_get(struct mailbox_transaction_context *t, +mailbox_attribute_comment_get(struct mailbox *box, const char *key ATTR_UNUSED, - struct mail_attribute_value *value_r) + struct mail_attribute_value *value_r, + bool internal_attribute ATTR_UNUSED) { - const struct mailbox_settings *set = t->box->set; + const struct mailbox_settings *set = box->set; if (set == NULL || *set->comment == '\0') return 0; @@ -73,11 +75,12 @@ iattr_mbox_shd_comment = { /* /shared/comment (RFC 5464) */ static int -server_attribute_comment_get(struct mailbox_transaction_context *t, +server_attribute_comment_get(struct mailbox *box, const char *key ATTR_UNUSED, - struct mail_attribute_value *value_r) + struct mail_attribute_value *value_r, + bool internal_attribute ATTR_UNUSED) { - const struct mail_storage_settings *set = t->box->storage->set; + const struct mail_storage_settings *set = box->storage->set; if (*set->mail_server_comment == '\0') return 0; @@ -98,11 +101,12 @@ iattr_serv_shd_comment = { /* /shared/admin (RFC 5464) */ static int -server_attribute_admin_get(struct mailbox_transaction_context *t, +server_attribute_admin_get(struct mailbox *box, const char *key ATTR_UNUSED, - struct mail_attribute_value *value_r) + struct mail_attribute_value *value_r, + bool internal_attribute ATTR_UNUSED) { - const struct mail_storage_settings *set = t->box->storage->set; + const struct mail_storage_settings *set = box->storage->set; if (*set->mail_server_admin == '\0') return 0; diff --git a/src/lib-storage/mailbox-attribute.c b/src/lib-storage/mailbox-attribute.c index be69634e48..1249eb10ae 100644 --- a/src/lib-storage/mailbox-attribute.c +++ b/src/lib-storage/mailbox-attribute.c @@ -174,7 +174,7 @@ mailbox_attribute_set_common(struct mailbox_transaction_context *t, case MAIL_ATTRIBUTE_INTERNAL_RANK_DEFAULT: case MAIL_ATTRIBUTE_INTERNAL_RANK_OVERRIDE: /* notify about assignment */ - if (iattr->set != NULL && iattr->set(t, key, value) < 0) + if (iattr->set != NULL && iattr->set(t, key, value, TRUE) < 0) return -1; break; case MAIL_ATTRIBUTE_INTERNAL_RANK_AUTHORITY: @@ -185,18 +185,13 @@ mailbox_attribute_set_common(struct mailbox_transaction_context *t, return -1; } /* assign internal attribute */ - return iattr->set(t, key, value); + return iattr->set(t, key, value, TRUE); default: i_unreached(); } } - /* FIXME: v2.3 should move the internal_attribute to attribute_set() - parameter (as flag). not done yet for API backwards compatibility */ - t->internal_attribute = iattr != NULL && - iattr->rank != MAIL_ATTRIBUTE_INTERNAL_RANK_AUTHORITY; - ret = t->box->v.attribute_set(t, type, key, value); - t->internal_attribute = FALSE; + ret = t->box->v.attribute_set(t, type, key, value, (iattr != NULL && iattr->rank != MAIL_ATTRIBUTE_INTERNAL_RANK_AUTHORITY)); return ret; } @@ -251,7 +246,7 @@ int mailbox_attribute_value_to_string(struct mail_storage *storage, } static int -mailbox_attribute_get_common(struct mailbox_transaction_context *t, +mailbox_attribute_get_common(struct mailbox *box, enum mail_attribute_type type, const char *key, struct mail_attribute_value *value_r) { @@ -261,7 +256,7 @@ mailbox_attribute_get_common(struct mailbox_transaction_context *t, iattr = mailbox_internal_attribute_get(type, key); /* allow internal server attributes only for the inbox */ - if (iattr != NULL && !t->box->inbox_user && + if (iattr != NULL && !box->inbox_user && strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT_SERVER, strlen(MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT_SERVER)) == 0) iattr = NULL; @@ -270,7 +265,7 @@ mailbox_attribute_get_common(struct mailbox_transaction_context *t, if (iattr != NULL) { switch (iattr->rank) { case MAIL_ATTRIBUTE_INTERNAL_RANK_OVERRIDE: - if ((ret = iattr->get(t, key, value_r)) != 0) { + if ((ret = iattr->get(box, key, value_r, TRUE)) != 0) { if (ret < 0) return -1; value_r->flags |= MAIL_ATTRIBUTE_VALUE_FLAG_READONLY; @@ -279,7 +274,7 @@ mailbox_attribute_get_common(struct mailbox_transaction_context *t, case MAIL_ATTRIBUTE_INTERNAL_RANK_DEFAULT: break; case MAIL_ATTRIBUTE_INTERNAL_RANK_AUTHORITY: - if ((ret = iattr->get(t, key, value_r)) <= 0) + if ((ret = iattr->get(box, key, value_r, TRUE)) <= 0) return ret; value_r->flags |= MAIL_ATTRIBUTE_VALUE_FLAG_READONLY; return 1; @@ -288,24 +283,20 @@ mailbox_attribute_get_common(struct mailbox_transaction_context *t, } } - /* user entries - FIXME: v2.3 should move the internal_attribute to - attribute_get() parameter (as flag). not done yet for API backwards - compatibility */ - t->internal_attribute = iattr != NULL && - iattr->rank != MAIL_ATTRIBUTE_INTERNAL_RANK_AUTHORITY; - ret = t->box->v.attribute_get(t, type, key, value_r); - t->internal_attribute = FALSE; + bool internal_attribute = (iattr != NULL && iattr->rank != MAIL_ATTRIBUTE_INTERNAL_RANK_AUTHORITY); + + ret = box->v.attribute_get(box, type, key, value_r, internal_attribute); if (ret != 0) return ret; /* default entries */ if (iattr != NULL) { switch (iattr->rank) { - case MAIL_ATTRIBUTE_INTERNAL_RANK_DEFAULT: + case MAIL_ATTRIBUTE_INTERNAL_RANK_DEFAULT: if (iattr->get == NULL) ret = 0; else { - if ((ret = iattr->get(t, key, value_r)) < 0) + if ((ret = iattr->get(box, key, value_r, internal_attribute)) < 0) return ret; } if (ret > 0) { @@ -321,19 +312,20 @@ mailbox_attribute_get_common(struct mailbox_transaction_context *t, return 0; } -int mailbox_attribute_get(struct mailbox_transaction_context *t, +int mailbox_attribute_get(struct mailbox *box, enum mail_attribute_type type, const char *key, struct mail_attribute_value *value_r) { int ret; memset(value_r, 0, sizeof(*value_r)); - if ((ret = mailbox_attribute_get_common(t, type, key, value_r)) <= 0) + if ((ret = mailbox_attribute_get_common(box, type, key, + value_r)) <= 0) return ret; i_assert(value_r->value != NULL); return 1; } -int mailbox_attribute_get_stream(struct mailbox_transaction_context *t, +int mailbox_attribute_get_stream(struct mailbox *box, enum mail_attribute_type type, const char *key, struct mail_attribute_value *value_r) { @@ -341,7 +333,8 @@ int mailbox_attribute_get_stream(struct mailbox_transaction_context *t, memset(value_r, 0, sizeof(*value_r)); value_r->flags |= MAIL_ATTRIBUTE_VALUE_FLAG_INT_STREAMS; - if ((ret = mailbox_attribute_get_common(t, type, key, value_r)) <= 0) + if ((ret = mailbox_attribute_get_common(box, type, key, + value_r)) <= 0) return ret; i_assert(value_r->value != NULL || value_r->value_stream != NULL); return 1; diff --git a/src/lib-storage/mailbox-attribute.h b/src/lib-storage/mailbox-attribute.h index aeba693647..d7e4b5d5a1 100644 --- a/src/lib-storage/mailbox-attribute.h +++ b/src/lib-storage/mailbox-attribute.h @@ -94,11 +94,11 @@ struct mailbox_attribute_internal { enum mail_attribute_internal_flags flags; /* Get the value of this internal attribute */ - int (*get)(struct mailbox_transaction_context *t, const char *key, - struct mail_attribute_value *value_r); + int (*get)(struct mailbox *box, const char *key, + struct mail_attribute_value *value_r, bool internal_attribute); /* Set the value of this internal attribute */ int (*set)(struct mailbox_transaction_context *t, const char *key, - const struct mail_attribute_value *value); + const struct mail_attribute_value *value, bool internal_attribute); }; void mailbox_attribute_register_internal( @@ -122,12 +122,12 @@ int mailbox_attribute_unset(struct mailbox_transaction_context *t, enum mail_attribute_type type, const char *key); /* Returns value for mailbox attribute key. Returns 1 if value was returned, 0 if value wasn't found (set to NULL), -1 if error */ -int mailbox_attribute_get(struct mailbox_transaction_context *t, +int mailbox_attribute_get(struct mailbox *box, enum mail_attribute_type type, const char *key, struct mail_attribute_value *value_r); /* Same as mailbox_attribute_get(), but the returned value may be either an input stream or a string. */ -int mailbox_attribute_get_stream(struct mailbox_transaction_context *t, +int mailbox_attribute_get_stream(struct mailbox *box, enum mail_attribute_type type, const char *key, struct mail_attribute_value *value_r);