On Jul 9, 2008, at 3:48 PM, Edgar Fuß wrote:
Apparently it doesn't like that I try to fsync() a read-only
directory file descriptor. I would argue that NetBSD is correct in this.Posix says:
The fsync() function shall request that all data for the open file
descriptor named by fildes is to be transferred to the storage
device associated with the file described by fildes.I read this a being about the file descriptor, not the file. Which
would imply that fsync()ing an O_RDONLY descriptor doesn't make sense.However, the wording for fdatasync() is slightly different and not
as clear, whether intentional or not. But fdatasync() seems to be
conceptually about regular files anyway.
Dovecot isn't the only program trying to fsync directories. For
example sendmail does it too.
From an admittedly non-Linux perspective, I'm unsure why one would
need to perform a flush on a directory in the first place.
To make sure that if server crashes all the directory entries have
been written to disk by that time. So that:
- fsync(tmp/newmail)
- rename(tmp/newmail, new/newmail)
- fsync(new/)
- Reply OK to the sender
If there is no 3 and the server crashes just after 4, I don't think
the rename() was guaranteed to have reached the disk. The fsync(new/)
is supposed to guarantee this. If NetBSD doesn't support this, what
other way is there to do it? I'm guessing I could fsync(new/newmail)
again. But if I was creating a lot of mails, would I have to fsync()
all of the files?
(The reason why fsync(tmp/newmail) is done before rename is so that
half-written files won't show up in new/ directory in case of crashes,
so moving the fsync after rename doesn't solve the problem.)