# HG changeset patch # User Timo Sirainen # Date 1150042358 -10800 # Node ID 79e7c206a75cf7ad62780a883949d53c1a4ed066 # Parent dbae2347dcdb4ef785eef2e01d8578cf442baaa3 Update quota when deleting a mailbox. diff -r dbae2347dcdb -r 79e7c206a75c src/plugins/quota/quota-storage.c --- a/src/plugins/quota/quota-storage.c Thu Jun 08 22:26:53 2006 +0300 +++ b/src/plugins/quota/quota-storage.c Sun Jun 11 19:12:38 2006 +0300 @@ -3,6 +3,7 @@ #include "lib.h" #include "array.h" #include "istream.h" +#include "mail-search.h" #include "mail-storage-private.h" #include "quota-private.h" #include "quota-plugin.h" @@ -248,6 +249,49 @@ return box; } +static int quota_mailbox_delete(struct mail_storage *storage, const char *name) +{ + struct quota_mail_storage *qstorage = QUOTA_CONTEXT(storage); + struct mailbox *box; + struct mail_search_context *ctx; + struct mailbox_transaction_context *t; + struct quota_transaction_context *qt; + struct mail *mail; + struct mail_search_arg search_arg; + int ret; + + /* This is a bit annoying to handle. We'll have to open the mailbox + and free the quota for all the messages existing in it. Open the + mailbox locked so that other processes can't mess up the quota + calculations by adding/removing mails while we're doing this. */ + box = mailbox_open(storage, name, NULL, MAILBOX_OPEN_FAST | + MAILBOX_OPEN_KEEP_RECENT | MAILBOX_OPEN_KEEP_LOCKED); + if (box == NULL) + return -1; + + memset(&search_arg, 0, sizeof(search_arg)); + search_arg.type = SEARCH_ALL; + + t = mailbox_transaction_begin(box, 0); + qt = QUOTA_CONTEXT(t); + ctx = mailbox_search_init(t, NULL, &search_arg, NULL); + + mail = mail_alloc(t, 0, NULL); + while (mailbox_search_next(ctx, mail) > 0) + quota_free(qt, mail); + mail_free(&mail); + + ret = mailbox_search_deinit(&ctx); + if (ret < 0) + mailbox_transaction_rollback(&t); + else + ret = mailbox_transaction_commit(&t, 0); + mailbox_close(&box); + /* FIXME: here's an unfortunate race condition */ + return ret < 0 ? -1 : + qstorage->super.mailbox_delete(storage, name); +} + static void quota_storage_destroy(struct mail_storage *storage) { struct quota_mail_storage *qstorage = QUOTA_CONTEXT(storage); @@ -282,6 +326,7 @@ qstorage->super = storage->v; storage->v.destroy = quota_storage_destroy; storage->v.mailbox_open = quota_mailbox_open; + storage->v.mailbox_delete = quota_mailbox_delete; ARRAY_CREATE(&qstorage->roots, storage->pool, struct quota_root *, 4);