I get a similar behavior between dovecot quota plugin and courier quota with the attached patch.
When the client change flags, then is forced to recalc. This is because I don't know how to get the changed flags on quota sync method. The courier quota behavior is avoid to count all deleted mails, include "mark as deleted" mails. -- Antonio Pérez-Aranda Alcaide aperezara...@yaco.es Yaco Sistemas S.L. http://www.yaco.es/ C/ Rioja 5, 41001 Sevilla Teléfono +34 954 50 00 57 Fax +34 954 50 09 29
diff -u dovecot-2.0.7/src/plugins/quota/quota-maildir.c.orig dovecot-2.0.7/src/plugins/quota/quota-maildir.c --- dovecot-2.0.7/src/plugins/quota/quota-maildir.c.orig 2010-11-04 21:58:48.000000000 +0300 +++ dovecot-2.0.7/src/plugins/quota/quota-maildir.c 2010-12-27 12:04:29.465254865 +0300 @@ -81,7 +81,11 @@ if (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || dp->d_name[1] == '.')) continue; - + /* YACO: Avoid to count in dirsize Trash Marked mails*/ + p = strchr(dp->d_name, 'T'); + if (p != NULL){ + continue; + } p = strstr(dp->d_name, ",S="); num = (uoff_t)-1; if (p != NULL) { diff -u dovecot-2.0.7/src/plugins/quota/quota-storage.c.orig dovecot-2.0.7/src/plugins/quota/quota-storage.c --- dovecot-2.0.7/src/plugins/quota/quota-storage.c.orig 2010-11-04 21:58:48.000000000 +0300 +++ dovecot-2.0.7/src/plugins/quota/quota-storage.c 2010-12-27 13:01:01.203201539 +0300 @@ -248,6 +248,7 @@ quota_mailbox_sync_cleanup(qbox); if (qbox->expunge_qt != NULL) (void)quota_transaction_commit(&qbox->expunge_qt); + qbox->recalculate = FALSE; } @@ -263,7 +264,8 @@ if (qbox->module_ctx.super.sync_notify != NULL) qbox->module_ctx.super.sync_notify(box, uid, sync_type); - if (sync_type != MAILBOX_SYNC_TYPE_EXPUNGE || qbox->recalculate) { + if ( (sync_type != MAILBOX_SYNC_TYPE_EXPUNGE && sync_type != MAILBOX_SYNC_TYPE_FLAGS) + || qbox->recalculate) { if (uid == 0) { /* free the transaction before view syncing begins, otherwise it'll crash. */ @@ -273,7 +275,7 @@ } /* we're in the middle of syncing the mailbox, so it's a bad idea to - try and get the message sizes at this point. Rely on sizes that + try and get the message sizes at this point. Rely on sizes that we saved earlier, or recalculate the whole quota if we don't know the size. */ if (!array_is_created(&qbox->expunge_uids)) { @@ -285,32 +287,41 @@ break; } } - if (qbox->expunge_qt == NULL) qbox->expunge_qt = quota_transaction_begin(box); - if (i != count) { /* we already know the size */ sizep = array_idx(&qbox->expunge_sizes, i); quota_free_bytes(qbox->expunge_qt, *sizep); return; } - + /* try to look up the size. this works only if it's cached. */ if (qbox->expunge_qt->tmp_mail == NULL) { qbox->expunge_trans = mailbox_transaction_begin(box, 0); qbox->expunge_qt->tmp_mail = mail_alloc(qbox->expunge_trans, - MAIL_FETCH_PHYSICAL_SIZE, NULL); + MAIL_FETCH_PHYSICAL_SIZE, NULL); + } + + if (sync_type == MAILBOX_SYNC_TYPE_EXPUNGE) { + if (mail_set_uid(qbox->expunge_qt->tmp_mail, uid) && + mail_get_physical_size(qbox->expunge_qt->tmp_mail, &size) == 0) + quota_free_bytes(qbox->expunge_qt, size); + else { + /* there's no way to get the size. recalculate the quota. */ + quota_recalculate(qbox->expunge_qt); + qbox->recalculate = TRUE; + } } - if (mail_set_uid(qbox->expunge_qt->tmp_mail, uid) && - mail_get_physical_size(qbox->expunge_qt->tmp_mail, &size) == 0) - quota_free_bytes(qbox->expunge_qt, size); + else { - /* there's no way to get the size. recalculate the quota. */ + /* If flags changed, recalculate quota */ + /* FIX: Recalculate only when flag \delete is store */ quota_recalculate(qbox->expunge_qt); qbox->recalculate = TRUE; } + } static int quota_mailbox_sync_deinit(struct mailbox_sync_context *ctx, @@ -397,6 +408,8 @@ qbox->module_ctx.super.free(box); } + + void quota_mailbox_allocated(struct mailbox *box) { struct mailbox_vfuncs *v = box->vlast;