Re: [PATCH 0/5] fuse: handle release synchronously (v4)

From: Miklos Szeredi
Date: Tue Sep 30 2014 - 03:43:54 EST


On Tue, Sep 30, 2014 at 7:33 AM, Anand Avati <avati@xxxxxxxxxxx> 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
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/