[BUG?] Double quota calulation when special folder is present
Mark Moseley
moseleymark at gmail.com
Wed Apr 10 05:00:31 EEST 2019
On Wed, Apr 3, 2019 at 9:37 PM Mark Moseley <moseleymark at gmail.com> wrote:
>
> On Wed, Mar 20, 2019 at 2:13 PM Mark Moseley <moseleymark at gmail.com>
> wrote:
>
>> Just hoping to get some dev eyes on this. I'm incredibly reluctant to
>> throw the word 'bug' around
>> (since 99 times out of 100, it's not -- it's almost always the config),
>> but I can't think of any way
>> that this could be a config issue, esp when the pre-2.2.34 version works
>> as expected.
>>
>> I noticed during troubleshooting that dovecot errors out if I try to
>> create a subfolder called
>> 'INBOX' but it'll happily create a subfolder called INBOX.SomethingElse
>> (i.e. a folder called
>> INBOX.INBOX.SomethingElse - resulting in a directory called
>> .INBOX.SomethingElse on the
>> filesystem, and leading to the problem described below). Is that
>> sub-subfolder creation (where
>> the top level subfolder matches the namespace name) supposed to be
>> allowed? It seems
>> odd that 'INBOX' (as a subfolder of INBOX) would be blocked but
>> INBOX.SomethingElse (as
>> a subfolder of INBOX) would be allowed. I'd expect INBOX.SomethingElse
>> (i.e.
>> INBOX.INBOX.SomethingElse) would be blocked as well.
>>
>>
>> On Wed, Mar 13, 2019 at 4:46 AM Bernd Wurst via dovecot <
>> dovecot at dovecot.org> wrote:
>>
>>> Hello,
>>>
>>> we're operating dovecot on a small server. Some years ago, we migrated
>>> from courier IMAP to dovecot. Therefore, we defined our default
>>> Namespace "inbox" with prefix "INBOX." to have this compatible. I found
>>> this in some migration docs those days. Generally, everything worked as
>>> expected.
>>>
>>> Our only namespace is configured like this:
>>>
>>> namespace inbox {
>>> separator = .
>>> prefix = INBOX.
>>> inbox = yes
>>> }
>>>
>>> Regularly, there is no folder named INBOX or .INBOX in the file system,
>>> I suppose this is correct. But I found a special corner case today when
>>> it comes to quota calculation.
>>>
>>> When - for whatever reason - a folder .INBOX.foo (for arbitrary values
>>> of foo) exists, the whole mailbox is counted twice in quota
>>> recalculation. Just creating .INBOX does nothing but a subfolder
>>> triggers the problem.
>>>
>>> This is my shell view (replaced username and file path and deleted
>>> unnecessary debug output)
>>>
>>> $ cat maildirsize
>>> 268435456S
>>> 14697 17
>>> $ maildirmake .INBOX.foo
>>> $ sudo doveadm -D quota recalc -u <user>
>>> [...]
>>> doveadm(<user>): Debug: Namespace inbox: type=private, prefix=INBOX.,
>>> sep=., inbox=yes, hidden=no, list=yes, subscriptions=yes
>>> location=maildir:/home/.../test
>>> doveadm(<user>): Debug: maildir++: root=/home/.../test, index=,
>>> indexpvt=, control=, inbox=/home/.../test, alt=
>>> doveadm(<user>): Debug: Namespace : type=private, prefix=, sep=,
>>> inbox=no, hidden=yes, list=no, subscriptions=no
>>> location=fail::LAYOUT=none
>>> doveadm(<user>): Debug: none: root=, index=, indexpvt=, control=,
>>> inbox=, alt=
>>> doveadm(<user>): Debug: quota: quota_over_flag check: quota_over_script
>>> unset - skipping
>>> doveadm(<user>): Debug: Quota root User quota: Recalculated relative
>>> rules with bytes=268435456 count=0. Now grace=26843545
>>> doveadm(<user>): Debug: Namespace INBOX.: Using permissions from
>>> /home/.../test: mode=0700 gid=default
>>>
>>> $ cat maildirsize
>>> 268435456S
>>> 29394 34
>>>
>>>
>>> So the used quota has exactly been doubled by just creating an empty
>>> subfolder.
>>>
>>> Do you have any pointers for fixing my configuration or is this a bug in
>>> dovecot?
>>>
>>>
>> I coincidentally resurrected a months-old thread with this same issue a
>> few days ago. I'm seeing the exact same after upgrading from 2.2.32 to
>> 2.2.36.
>>
>> The original poster (who also narrowed it down to something in 2.2.34)
>> mentioned a workaround that does indeed work, namely setting
>> mailbox_list_index=no:
>>
>> > doveadm -o 'mailbox_list_index=no' quota recalc -u myuser
>>
>> I've been staring at diffs of 2.2.33 and 2.2.34 without anything jumping
>> out at me (not a C guy, sadly). Maybe src/lib-storage/index/index-storage.c
>> or src/lib-storage/list/mailbox-list-fs-iter.c or
>> src/lib-storage/list/mailbox-list-index-iter.c
>> or src/lib-storage/list/mailbox-list-index.c?
>>
>> The latter few have some added strcmp's against "INBOX". Then again,
>> there's a lot of new code in the diffs under src/lib-storage that
>> references INBOX specifically.
>>
>
> Can the Dovecot team confirm whether this is indeed a bug or not? I've
> not yet been able to test 2.3.x to see if the problem exists there as well.
>
I've bisected this down to this commit:
git diff
7620195ceeea805137cbd1bae104e385eee474a9..97473a513feb2bbd763051869c8b7b83e24b37fa
diff --git a/src/lib-storage/list/mailbox-list-index-iter.c
b/src/lib-storage/list/mailbox-list-index-iter.c
index c9afc7a..49cd941 100644
--- a/src/lib-storage/list/mailbox-list-index-iter.c
+++ b/src/lib-storage/list/mailbox-list-index-iter.c
@@ -90,13 +90,18 @@ mailbox_list_index_update_info(struct
mailbox_list_index_iterate_context *ctx)
if (strcmp(ctx->info.vname, "INBOX") != 0) {
/* non-INBOX */
ctx->info.vname = p_strdup(ctx->info_pool, ctx->info.vname);
- } else {
+ } else if (!ctx->prefix_inbox_list) {
/* listing INBOX itself */
ctx->info.vname = "INBOX";
if (mail_namespace_is_inbox_noinferiors(ctx->info.ns)) {
ctx->info.flags &=
~(MAILBOX_CHILDREN|MAILBOX_NOCHILDREN);
ctx->info.flags |= MAILBOX_NOINFERIORS;
}
+ } else {
+ /* listing INBOX/INBOX */
+ ctx->info.vname = p_strconcat(ctx->info_pool,
+ ctx->ctx.list->ns->prefix, "INBOX", NULL);
+ ctx->info.flags |= MAILBOX_NONEXISTENT;
}
if ((node->flags & MAILBOX_LIST_INDEX_FLAG_NONEXISTENT) != 0)
ctx->info.flags |= MAILBOX_NONEXISTENT;
@@ -126,6 +131,14 @@ mailbox_list_index_update_next(struct
mailbox_list_index_iterate_context *ctx,
{
struct mailbox_list_index_node *node = ctx->next_node;
+ if (!ctx->prefix_inbox_list && ctx->ctx.list->ns->prefix_len > 0 &&
+ strcmp(node->name, "INBOX") == 0 && node->parent == NULL &&
+ node->children != NULL) {
+ /* prefix/INBOX has children */
+ ctx->prefix_inbox_list = TRUE;
+ return;
+ }
+
if (node->children != NULL && follow_children) {
ctx->parent_len = str_len(ctx->path);
ctx->next_node = node->children;
diff --git a/src/lib-storage/list/mailbox-list-index.h
b/src/lib-storage/list/mailbox-list-index.h
index 9dc1c48..e4b042a 100644
--- a/src/lib-storage/list/mailbox-list-index.h
+++ b/src/lib-storage/list/mailbox-list-index.h
@@ -138,6 +138,7 @@ struct mailbox_list_index_iterate_context {
struct mailbox_list_index_node *next_node;
unsigned int failed:1;
+ unsigned int prefix_inbox_list:1;
};
extern MODULE_CONTEXT_DEFINE(mailbox_list_index_module,
Prior to this commit, anything updating the quota would do the right thing
for any .INBOX.<something> folders (i.e. not double count the contents of
"INBOX" against the quota). After this commit, anything updating quota (new
mail, quota recalc, etc) does the double counting of INBOX.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://dovecot.org/pipermail/dovecot/attachments/20190409/65a7cc6c/attachment-0001.html>
More information about the dovecot
mailing list