]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Add support for storing "mail stubs"
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 18 Nov 2016 13:16:27 +0000 (15:16 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 18 Nov 2016 13:20:45 +0000 (15:20 +0200)
These allow treating a storage backend as a cache where the mail bodies
don't necessarily exist.

src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage.c
src/lib-storage/mail-storage.h

index e5fc1bea81468df1ed9c146259f8c9b5e1b82438..9874152aa5155c05cf6cb14b6d5621754fc9e227 100644 (file)
@@ -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;
 
index e7e790f8ea5b8ba98599c28d39dd8ee74500e1da..d4618205db971df6271cbdbdb1dbd4f77851343e 100644 (file)
@@ -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
index db089580b74fcbf3d92108f948f81c0350aee6ce..4ba79cde99d05123b8c8d99153090c560c3e03fe 100644 (file)
@@ -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 {