From: sergey.kitov Date: Tue, 8 Mar 2022 11:38:39 +0000 (+0200) Subject: lib-storage: Expunge mails in batches when deleting a mailbox. X-Git-Tag: 2.4.0~4195 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=893d9a104f5048aada5217b695cfcf70a6dbe39d;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Expunge mails in batches when deleting a mailbox. --- diff --git a/src/lib-storage/index/index-storage.c b/src/lib-storage/index/index-storage.c index 3320d97b5e..f23b5000ae 100644 --- a/src/lib-storage/index/index-storage.c +++ b/src/lib-storage/index/index-storage.c @@ -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;