]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Expunge mails in batches when deleting a mailbox.
authorsergey.kitov <sergey.kitov@open-xchange.com>
Tue, 8 Mar 2022 11:38:39 +0000 (13:38 +0200)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Mon, 28 Mar 2022 15:41:32 +0000 (15:41 +0000)
src/lib-storage/index/index-storage.c

index 3320d97b5ee33db3d67a179fef40b8cf3df48381..f23b5000aea598f0c8814e60beb6ee18a12189c1 100644 (file)
@@ -757,32 +757,46 @@ mailbox_delete_all_attributes(struct mailbox_transaction_context *t,
 
 static int mailbox_expunge_all_data(struct mailbox *box)
 {
-       struct mail_search_context *ctx;
        struct mailbox_transaction_context *t;
-       struct mail *mail;
        struct mail_search_args *search_args;
+       struct mailbox_status status;
+       struct mail_search_seqset_iter *seqset_iter;
        int ret;
 
        (void)mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ);
 
-       t = mailbox_transaction_begin(box, 0, __func__);
+       mailbox_get_open_status(box, STATUS_MESSAGES, &status);
 
        search_args = mail_search_build_init();
        mail_search_build_add_all(search_args);
-       ctx = mailbox_search_init(t, search_args, NULL, 0, NULL);
-       mail_search_args_unref(&search_args);
 
-       while (mailbox_search_next(ctx, &mail))
-               mail_expunge(mail);
+       seqset_iter = mail_search_seqset_iter_init(search_args, status.messages,
+                                                  MAIL_EXPUNGE_BATCH_SIZE);
 
-       ret = mailbox_search_deinit(&ctx);
-       if (ret == 0) {
-               if (mailbox_delete_all_attributes(t, MAIL_ATTRIBUTE_TYPE_PRIVATE) < 0 ||
-                   mailbox_delete_all_attributes(t, MAIL_ATTRIBUTE_TYPE_SHARED) < 0)
+       do {
+               struct mail_search_context *ctx;
+               struct mail *mail;
+
+               t = mailbox_transaction_begin(box, 0, __func__);
+               ctx = mailbox_search_init(t, search_args, NULL, 0, NULL);
+               while (mailbox_search_next(ctx, &mail))
+                       mail_expunge(mail);
+
+               ret = mailbox_search_deinit(&ctx);
+               if (mailbox_transaction_commit(&t) < 0)
                        ret = -1;
-       }
+       } while (ret >= 0 && mail_search_seqset_iter_next(seqset_iter));
+
+       mail_search_seqset_iter_deinit(&seqset_iter);
+       mail_search_args_unref(&search_args);
+
+       t = mailbox_transaction_begin(box, 0, __func__);
+       if (mailbox_delete_all_attributes(t, MAIL_ATTRIBUTE_TYPE_PRIVATE) < 0 ||
+           mailbox_delete_all_attributes(t, MAIL_ATTRIBUTE_TYPE_SHARED) < 0)
+               ret = -1;
        if (mailbox_transaction_commit(&t) < 0)
                ret = -1;
+
        /* sync to actually perform the expunges */
        if (mailbox_sync(box, 0) < 0)
                ret = -1;