Mercurial > dovecot > core-2.2
changeset 15310:41aac09497ee
dict quota: Fixed a potential crash if quota recalculation was triggered at deinit.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 16 Oct 2012 03:34:51 +0300 |
parents | 0262ede193e5 |
children | 022d0d21e56d |
files | src/plugins/quota/quota-dict.c src/plugins/quota/quota-dirsize.c src/plugins/quota/quota-fs.c src/plugins/quota/quota-maildir.c src/plugins/quota/quota-private.h src/plugins/quota/quota-storage.c |
diffstat | 6 files changed, 35 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/plugins/quota/quota-dict.c Tue Oct 16 03:08:21 2012 +0300 +++ b/src/plugins/quota/quota-dict.c Tue Oct 16 03:34:51 2012 +0300 @@ -86,10 +86,8 @@ { struct dict_quota_root *root = (struct dict_quota_root *)_root; - if (root->dict != NULL) { - (void)dict_wait(root->dict); + if (root->dict != NULL) dict_deinit(&root->dict); - } i_free(root); } @@ -208,6 +206,13 @@ return 0; } +static void dict_quota_flush(struct quota_root *_root) +{ + struct dict_quota_root *root = (struct dict_quota_root *)_root; + + (void)dict_wait(root->dict); +} + struct quota_backend quota_backend_dict = { "dict", @@ -221,6 +226,7 @@ dict_quota_root_get_resources, dict_quota_get_resource, dict_quota_update, - NULL + NULL, + dict_quota_flush } };
--- a/src/plugins/quota/quota-dirsize.c Tue Oct 16 03:08:21 2012 +0300 +++ b/src/plugins/quota/quota-dirsize.c Tue Oct 16 03:34:51 2012 +0300 @@ -219,6 +219,7 @@ dirsize_quota_root_get_resources, dirsize_quota_get_resource, dirsize_quota_update, + NULL, NULL } };
--- a/src/plugins/quota/quota-fs.c Tue Oct 16 03:08:21 2012 +0300 +++ b/src/plugins/quota/quota-fs.c Tue Oct 16 03:34:51 2012 +0300 @@ -831,7 +831,8 @@ fs_quota_get_resource, fs_quota_update, - fs_quota_match_box + fs_quota_match_box, + NULL } };
--- a/src/plugins/quota/quota-maildir.c Tue Oct 16 03:08:21 2012 +0300 +++ b/src/plugins/quota/quota-maildir.c Tue Oct 16 03:34:51 2012 +0300 @@ -913,6 +913,7 @@ maildir_quota_root_get_resources, maildir_quota_get_resource, maildir_quota_update, + NULL, NULL } };
--- a/src/plugins/quota/quota-private.h Tue Oct 16 03:08:21 2012 +0300 +++ b/src/plugins/quota/quota-private.h Tue Oct 16 03:34:51 2012 +0300 @@ -67,7 +67,7 @@ int (*update)(struct quota_root *root, struct quota_transaction_context *ctx); bool (*match_box)(struct quota_root *root, struct mailbox *box); - + void (*flush)(struct quota_root *root); }; struct quota_backend {
--- a/src/plugins/quota/quota-storage.c Tue Oct 16 03:08:21 2012 +0300 +++ b/src/plugins/quota/quota-storage.c Tue Oct 16 03:34:51 2012 +0300 @@ -366,14 +366,34 @@ return ret; } +static void quota_roots_flush(struct quota *quota) +{ + struct quota_root *const *roots; + unsigned int i, count; + + roots = array_get("a->roots, &count); + for (i = 0; i < count; i++) { + if (roots[i]->backend.v.flush != NULL) + roots[i]->backend.v.flush(roots[i]); + } +} + static void quota_mailbox_close(struct mailbox *box) { struct quota_mailbox *qbox = QUOTA_CONTEXT(box); + struct quota_user *quser = QUOTA_USER_CONTEXT(box->storage->user); /* sync_notify() may be called outside sync_begin()..sync_deinit(). make sure we apply changes at close time at latest. */ quota_mailbox_sync_commit(qbox); + /* make sure quota backend flushes all data. this could also be done + somewhat later, but user.deinit() is too late, since the flushing + can trigger quota recalculation which isn't safe to do anymore + at user.deinit() when most of the loaded plugins have already been + deinitialized. */ + quota_roots_flush(quser->quota); + qbox->module_ctx.super.close(box); }