[dovecot] Re: [bincimap] Re: Re: bincimap

Timo Sirainen tss at iki.fi
Mon Feb 17 21:39:20 EET 2003


On Mon, 2003-02-17 at 20:59, Andreas Aardal Hanssen wrote:
> >From maildir-storage.c, line 325:
> 
>         while (rename(src, dest) < 0 && count < 2) {
>                 if (errno != EEXIST) {
> 
> rename can never return EEXIST in errno.

Sure it can:

       ENOTEMPTY or EEXIST
              newpath  is  a non-empty directory, i.e., contains entries other
              than "." and "..".

But looks like I've missed the ENOTEMPTY check there, adding. I'm
renaming directories there, not files.

>         /* move the file into new/ directory - syncing will pick it
>            up from there */
>         if (rename(tmp_path, new_path) == 0)
>                 failed = FALSE;
> 
> Here you can lose emails if the new/ folder contains a message whose base 
> name is equal.

In theory, yes. In practice, I'd say not. It can only happen with broken
MUAs, are there any? User could of course deliberately break it, but is
there some gain in it?

> The only way to avoid this is:
> 
> 1) use link and unlink, not rename

..and if it crashes (or loses NFS link) between those calls, you'll
suddenly see two mails. I prefer atomic operations.

> Anyway, Maildir has a strict consistency criteria which says that all
> messages that are linked from tmp/ into new/ _must_ use time(NULL) plus a
> number that is guaranteed not to lapse within one second, and which does
> not collide with other messages in new/. new/ is the single entry point
> into cur/, and messages in new/ can not be "older" than the messages in
> cur/.

It only has requirement that the file name is unique. There's other ways
to do that than time(NULL). http://cr.yp.to/proto/maildir.html lists
some.

> 2) leave messages that have a time_t part equal to or higher than 
>    time(NULL).
..
> The simple reasoning for this is that you can never guarantee that there
> is no message in cur/ that has the same base name, but perhaps different
> flags. It follows that when moving a message from new/ to cur/, it is
> required that the server only picks messages that are older than one
> second.

I'm not sure what you mean by this.. What's special in files that were
just created? What changes after it's older than one second? Or are you
changing the base name when moving it to cur/? (What makes you sure that
the new base name still doesn't exist?)

I don't think you should rely on checking timestamps in any case. What
if the maildir is accessed via NFS and some other computer with
different time created the file?

But about the flags, looks like maildir spec says they could be used
only in cur/ directory, so I guess my code is broken because it allows
setting them already in new/.. Well, I'll fix it anyway later by moving
mails directly from tmp/ into cur/ when implementing UIDPLUS extension.




More information about the dovecot mailing list