From: Timo Sirainen Date: Fri, 18 Nov 2016 13:16:27 +0000 (+0200) Subject: lib-storage: Add support for storing "mail stubs" X-Git-Tag: 2.2.27~103 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=66c5edee90c92a4b276ea352dd9a11e41be57c39;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Add support for storing "mail stubs" These allow treating a storage backend as a cache where the mail bodies don't necessarily exist. --- diff --git a/src/lib-storage/mail-storage-private.h b/src/lib-storage/mail-storage-private.h index e5fc1bea81..9874152aa5 100644 --- a/src/lib-storage/mail-storage-private.h +++ b/src/lib-storage/mail-storage-private.h @@ -625,7 +625,7 @@ struct mail_save_data { time_t received_date, save_date; int received_tz_offset; - uint32_t uid; + uint32_t uid, stub_seq; char *guid, *pop3_uidl, *from_envelope; unsigned int pop3_order; diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index e7e790f8ea..d4618205db 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -1882,6 +1882,9 @@ mailbox_transaction_begin(struct mailbox *box, { struct mailbox_transaction_context *trans; + i_assert((flags & MAILBOX_TRANSACTION_FLAG_FILL_IN_STUB) == 0 || + (box->flags & MAILBOX_FLAG_USE_STUBS) != 0); + i_assert(box->opened); box->transaction_count++; @@ -2036,6 +2039,11 @@ void mailbox_save_set_from_envelope(struct mail_save_context *ctx, void mailbox_save_set_uid(struct mail_save_context *ctx, uint32_t uid) { ctx->data.uid = uid; + if ((ctx->transaction->flags & MAILBOX_TRANSACTION_FLAG_FILL_IN_STUB) != 0) { + if (!mail_index_lookup_seq(ctx->transaction->view, uid, + &ctx->data.stub_seq) < 0) + i_panic("Trying to fill in stub for nonexistent UID %u", uid); + } } void mailbox_save_set_guid(struct mail_save_context *ctx, const char *guid) @@ -2080,6 +2088,11 @@ int mailbox_save_begin(struct mail_save_context **ctx, struct istream *input) return -1; } + /* if we're filling in a stub, we must have set UID already + (which in turn sets stub_seq) */ + i_assert(((*ctx)->transaction->flags & MAILBOX_TRANSACTION_FLAG_FILL_IN_STUB) == 0 || + (*ctx)->data.stub_seq != 0); + if (!(*ctx)->copying_or_moving) { /* We're actually saving the mail. We're not being called by mail_storage_copy() because backend didn't support fast diff --git a/src/lib-storage/mail-storage.h b/src/lib-storage/mail-storage.h index db089580b7..4ba79cde99 100644 --- a/src/lib-storage/mail-storage.h +++ b/src/lib-storage/mail-storage.h @@ -55,7 +55,12 @@ enum mailbox_flags { inconsistent. For example this disables lazy_expunge plugin and quota updates (possibly resulting in broken quota). and This is useful for example when deleting entire user accounts. */ - MAILBOX_FLAG_DELETE_UNSAFE = 0x400 + MAILBOX_FLAG_DELETE_UNSAFE = 0x400, + /* Mailbox is used for caching purposes. Some of the mails may be + stubs, which exist in the index but that don't have a mail body. + The backend shouldn't treat it as corruption if a mail body isn't + found. */ + MAILBOX_FLAG_USE_STUBS = 0x800, }; enum mailbox_feature { @@ -189,7 +194,11 @@ enum mailbox_transaction_flags { /* Don't trigger any notifications for this transaction. This especially means the notify plugin. This would normally be used only with _FLAG_SYNC. */ - MAILBOX_TRANSACTION_FLAG_NO_NOTIFY = 0x40 + MAILBOX_TRANSACTION_FLAG_NO_NOTIFY = 0x40, + /* Append fills in an existing stub mail for the specified UID, + instead of saving a new mail. This requires mailbox to be opened + with MAILBOX_FLAG_USE_STUBS. */ + MAILBOX_TRANSACTION_FLAG_FILL_IN_STUB = 0x80, }; enum mailbox_sync_flags {