Closed Artefact2 closed 3 years ago
I don't see a problem with link()/unlink(). That is the standard way to deliver mail to maildir folders, and I doubt that a file system can reorder operations in the way you describe. Please have a look at the maildir documentation and the Wikipedia article on maildir.
I don't see any mention in those two links that you have to use link/unlink. Filesystems can and do reorder a lot of writes especially metadata (that's why write(tmpfile) rename(tmpfile,a) can leave you with a truncated a and no tmpfile).
Why not use rename(), which is guaranteed to be atomic?
Yes, you can use rename() too. But you don't have to, since maildir does not require the link()/unlink() pair to be atomic.
Hello,
I am reading the source here https://github.com/marlam/mpop-mirror/blob/master/src/delivery.c#L389-L423 and am wondering if it is possible to lose e-mails after a crash (very inconvenient especially if the server doesn't keep messages).
As I understand it, mpop writes the received e-mail in a temp file,
fsync()
s it,link()
s it to its final pathname thenunlink()
s the temp file. Once mpop is done, thelink()
/unlink()
calls have yet to hit the disk and the filesystem can reorder them. So it's possible that, after a crash,unlink()
was persisted to disk, but notlink()
, resulting in a lost e-mail.To my understanding, POSIX does not guarantee ordering of such operations, and many filesystems don't either.
One fix would be to
fsync()
the newly linked file and its directory entry before unlinking, like below: