Messages in this thread | | | Date | Tue, 30 Sep 2014 09:43:49 +0200 | Subject | Re: [PATCH 0/5] fuse: handle release synchronously (v4) | From | Miklos Szeredi <> |
| |
On Tue, Sep 30, 2014 at 7:33 AM, Anand Avati <avati@gluster.org> wrote:
> In general that sounds reasonable. The problem (as described in the original > thread, at http://sourceforge.net/p/fuse/mailman/message/29889055/) happens > in the presence of dup(). Tools like dd (and others) call dup(), and a > second file descriptor is created for the same filp. Every descriptor's > close() results in a ->flush(). The final close() of course results in > ->release() as well. > > Because dup() is silently handled in VFS (and a FUSE filesystem is > completely unaware), from a FUSE filesystem's point of view this is how > operations look: > > - OPEN > - ... <I/O ops> > - FLUSH > - ... <I/O ops> > - FLUSH > - ... <many more FLUSHes and I/O> > - FLUSH > - RELEASE > > So, for a given open(), one release() is guaranteed. There can be one or > more (arbitrary number) of flush()es. If one wants to implement semantics > where a second concurrent open()er gets EBUSY, they have to pick between one > of the two evils: > > - Assume the first FLUSH is the last FLUSH and release internal locks/leases > and therefore break semantics > - Wait for RELEASE and asynchronously release internal locks/leases and > therefore result in spurious EBUSY (between last close() and ->release())
As I wrote, we may identify the last FLUSH, if there aren't any more references to the file. This is by far the most common case. Most obvious exceptions:
- mmaped file: there won't be a FLUSH after the file is closed, but there might well be I/O.
- file is sent over UNIX domain socket. There might or might not be a FLUSH depending on whether the file was received by the other end or not. There's no I/O while the file is being sent.
- close() racing with read()/write() in multithreaded app. FLUSH might get there first before the actual I/O.
In these cases the "last flush" flag will *not* be set.
So we can have several cases:
- "last flush" is set: this is indeed the last flush - "last flush" is not set and this is not the last flush - "last flush" is not set and this is the last flush, but there are still I/O coming before the release - "last flush" is not set and this is the last flush and no I/O happens before the release
Would this work for you?
Thanks, Miklos
| |