Skip to main content.
April 17th, 2007

flush, dup and FUSE

At work, we’re developing a FUSE filesystem which uses IMAP as a data-store. Everything’s fine, ’till we change something and try this:

$ echo 'hello' > hello.txt

This should make a new mail, with only content ‘hello’. And it works, BUT create also an empty mail message before. Why?

Our policy is to commit the mail to the IMAP server only in front of a flush. So, we look at syscalls given by fuse to us:

...
open
fgetattr
flush
write
flush
...

Oh, nice. nice? not at all. What’s that first “flush” in the sequence?! Well, simple; let’s strace the bash’s echo:


...
open("hello.txt", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
fcntl64(1, F_GETFD) = 0
fcntl64(1, F_DUPFD, 10) = 10
fcntl64(1, F_GETFD) = 0
fcntl64(10, F_SETFD, FD_CLOEXEC) = 0
dup2(3, 1) = 1
close(3) = 0
write(1, "ciao\n", 5) = 5
dup2(10, 1) = 1
fcntl64(10, F_GETFD) = 0x1 (flags FD_CLOEXEC)
close(10) = 0
...

Try to guess now… yes, it’s the dup2. Evidently, the dup2, before making the file descriptor duplication, flush them so to be sure they’re in sync, and this causes the extra flush() at the beginning, just after the open. What a nice world…

Posted by mattia as dup, flush, fuse at 11:56 AM CEST

No Comments »