Messages in this thread | | | Date | Thu, 16 Oct 2014 14:31:17 +0400 | From | Maxim Patlasov <> | Subject | Re: [PATCH 0/5] fuse: handle release synchronously (v4) |
| |
Hi Miklos,
On 10/09/2014 12:14 PM, Miklos Szeredi wrote: > On Wed, Oct 1, 2014 at 1:28 PM, Maxim Patlasov <mpatlasov@parallels.com> wrote: >> Given those patches must die, do you have any ideas how to resolve that >> "spurious EBUSY" problem? > Check the "sync_release" branch of fuse: > > git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git sync_release > > And same branch name for libfuse: > > git://git.code.sf.net/p/fuse/fuse sync_release > > What it does is send RELEASE from ->flush() after checking the > refcount of file (being careful about RCU accesses). > > Lightly tested, more testing, as well as review, is welcome.
Thank you very much for efforts, highly appreciated! I've had a close look at your patches and found a few issues. Most of them can be easily fixed, but one puzzles me: the way how you detect last flush is not race free. Something as simple as:
int main(int argc, char *argv[]) { int fd = open(argv[1], O_RDWR); fork(); }
may easily dive into fuse_try_sync_release() concurrently and both observe file->f_count == 2. Then both return falling back to sending the release asynchronously. This makes sync/async behaviour unpredictable even for well-behaved applications which don't do any esoteric things like racing i/o with close or exiting while a descriptor is in-flight in a unix domain socket.
I cannot see any way to recognise last flush without help of VFS layer, can you?
Thanks, Maxim
| |