Discussion:
maildirsize is recalculated too often
Teodor Milkov
2014-07-03 15:36:38 UTC
Permalink
Hi,

After upgrading to vpopmail 5.4.33 I started seeing much more IO
requests. I see that in 5.4.32 the following code was added to
maildirquota.c:

/*
Maildir++ specification says to rebuild the maildirsize file if the
file is 5120 or more bytes, or is more than 15 minutes old
*/

ret = fstat(f, statptr);
if ((ret != -1) && ((statptr->st_size >= 5120) || (time(NULL) >
statptr->st_mtime + (15*60)))) {
unlink(filename);
close(f);
return -1;
}

I think this is not correct interpretation of the specs from
www.courier-mta.org/imap/README.maildirquota.html which says:

/If the numbers we got indicated that the Maildir++ *is over quota*,
some additional logic is in order: if we did not recalculate
//maildirsize//, if the numbers in //maildirsize//indicated that we are
over quota, then if //maildirsize//was more than one line long, or if
the timestamp on //maildirsize//indicated that it's at least 15 minutes
old, throw out the totals, and recalculate //maildirsize//from scratch./

I.e. the 15 minute logic should be applied only if the Maildir is
currently over quota. This logic was already implemented in
maildirquota.c dockeckquota() where it says if (maildirsize_nlines == 1
&& tm < stat_buf.st_mtime + 15*60), but it didn't work, because
/stat_buf/ is not set in maildirsize_read().

Please find attached a patch against 5.4.33, which I'm using in
production. In addition to the minimal fix (initializing stat_buf) it
has some documentation as well as some magic numbers converted to
constants -- feel free to use it however you like.


Best regards,
Teodor


!DSPAM:53b5788881086521514644!
Matt Brookings
2014-07-14 15:50:40 UTC
Permalink
Thanks, Teodor! I'll take a look at this.
Hi,
After upgrading to vpopmail 5.4.33 I started seeing much more IO requests. I see that in 5.4.32
/* Maildir++ specification says to rebuild the maildirsize file if the file is 5120 or more
bytes, or is more than 15 minutes old */
ret = fstat(f, statptr); if ((ret != -1) && ((statptr->st_size >= 5120) || (time(NULL) >
statptr->st_mtime + (15*60)))) { unlink(filename); close(f); return -1; }
I think this is not correct interpretation of the specs from
/If the numbers we got indicated that the Maildir++ *is over quota*, some additional logic is in
order: if we did not recalculate //maildirsize//, if the numbers in //maildirsize//indicated that
we are over quota, then if //maildirsize//was more than one line long, or if the timestamp on
//maildirsize//indicated that it's at least 15 minutes old, throw out the totals, and
recalculate //maildirsize//from scratch./
I.e. the 15 minute logic should be applied only if the Maildir is currently over quota. This
logic was already implemented in maildirquota.c dockeckquota() where it says if
(maildirsize_nlines == 1 && tm < stat_buf.st_mtime + 15*60), but it didn't work, because
/stat_buf/ is not set in maildirsize_read().
Please find attached a patch against 5.4.33, which I'm using in production. In addition to the
minimal fix (initializing stat_buf) it has some documentation as well as some magic numbers
converted to constants ? feel free to use it however you like.
- --
/*
Matt Brookings <***@inter7.com> GnuPG Key 62817373
Software developer Systems technician
Inter7 Internet Technologies, Inc. (815)776-9465
*/

Loading...