• Kirill Smelkov's avatar
    fuse: Add FOPEN_STREAM and use stream_open() if filesystem returned that from open handler · dc47c061
    Kirill Smelkov authored
    Starting from 9c225f26 (vfs: atomic f_pos accesses as per POSIX) files
    opened even via nonseekable_open gate read and write via lock and do not
    allow them to be run simultaneously. This can create read vs write
    deadlock if a filesystem is trying to implement a socket-like file which
    is intended to be simultaneously used for both read and write from
    filesystem client. See previous patch "fs: stream_open - opener for
    stream-like files so that read and write can run simultaneously without
    deadlock" for details and e.g. 581d21a2 (xenbus: fix deadlock on
    writes to /proc/xen/xenbus) for a similar deadlock example on /proc/xen/xenbus.
    
    To avoid such deadlock it was tempting fuse_finish_open to use
    stream_open instead of nonseekable_open on just FOPEN_NONSEEKABLE flags,
    but grepping through Debian codesearch shows users of FOPEN_NONSEEKABLE,
    and in particular GVFS which actually uses offset in its read and write
    handlers
    
    	https://codesearch.debian.net/search?q=-%3Enonseekable+%3D
    	https://gitlab.gnome.org/GNOME/gvfs/blob/1.40.0-6-gcbc54396/client/gvfsfusedaemon.c#L1080
    	https://gitlab.gnome.org/GNOME/gvfs/blob/1.40.0-6-gcbc54396/client/gvfsfusedaemon.c#L1247-1346
    	https://gitlab.gnome.org/GNOME/gvfs/blob/1.40.0-6-gcbc54396/client/gvfsfusedaemon.c#L1399-1481
    
    so if we would do such a change it will break a real user.
    
    -> Add another flag (FOPEN_STREAM) for filesystem servers to indicate
    that the opened handler is having stream-like semantics; does not use
    file position and thus the kernel is free to issue simultaneous read and
    write request on opened file handle.
    
    This patch together with stream_open should be added to stable kernels starting from
    v3.14+ (the kernel where 9c225f26 first appeared). This will allow to patch
    OSSPD and other FUSE filesystems that provide stream-like files to return
    FOPEN_STREAM | FOPEN_NONSEEKABLE in open handler and this way avoid the deadlock on
    all kernel versions. This should work because fuse_finish_open ignores unknown open
    flags returned from a filesystem and so passing FOPEN_STREAM to a kernel that
    is not aware of this flag cannot hurt. In turn the kernel that is not aware of
    FOPEN_STREAM will be < v3.14 where just FOPEN_NONSEEKABLE is sufficient to
    implement streams without read vs write deadlock.
    
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Michael Kerrisk <mtk.manpages@gmail.com>
    Cc: Yongzhi Pan <panyongzhi@gmail.com>
    Cc: Jonathan Corbet <corbet@lwn.net>
    Cc: David Vrabel <david.vrabel@citrix.com>
    Cc: Juergen Gross <jgross@suse.com>
    Cc: Tejun Heo <tj@kernel.org>
    Cc: Kirill Tkhai <ktkhai@virtuozzo.com>
    Cc: Arnd Bergmann <arnd@arndb.de>
    Cc: Christoph Hellwig <hch@lst.de>
    Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: Julia Lawall <Julia.Lawall@lip6.fr>
    Cc: Nikolaus Rath <Nikolaus@rath.org>
    Cc: Han-Wen Nienhuys <hanwen@google.com>
    Signed-off-by: Kirill Smelkov's avatarKirill Smelkov <kirr@nexedi.com>
    dc47c061
file.c 77.5 KB