• Kirill Smelkov's avatar
    fuse: Add FOPEN_STREAM to use stream_open() · c9696a8f
    Kirill Smelkov authored
    commit bbd84f33652f852ce5992d65db4d020aba21f882 upstream.
    
    Starting from commit 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 commit 10dce8af3422 ("fs: stream_open - opener for
    stream-like files so that read and write can run simultaneously without
    deadlock") for details and e.g. commit 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 to adjust 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+. 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: stable@vger.kernel.org # v3.14+
    Signed-off-by: default avatarKirill Smelkov <kirr@nexedi.com>
    Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    c9696a8f
Name
Last commit
Last update
..
9p Loading commit data...
adfs Loading commit data...
affs Loading commit data...
afs Loading commit data...
autofs4 Loading commit data...
befs Loading commit data...
bfs Loading commit data...
btrfs Loading commit data...
cachefiles Loading commit data...
ceph Loading commit data...
cifs Loading commit data...
coda Loading commit data...
configfs Loading commit data...
cramfs Loading commit data...
debugfs Loading commit data...
devpts Loading commit data...
dlm Loading commit data...
ecryptfs Loading commit data...
efivarfs Loading commit data...
efs Loading commit data...
exofs Loading commit data...
exportfs Loading commit data...
ext2 Loading commit data...
ext4 Loading commit data...
f2fs Loading commit data...
fat Loading commit data...
freevxfs Loading commit data...
fscache Loading commit data...
fuse Loading commit data...
gfs2 Loading commit data...
hfs Loading commit data...
hfsplus Loading commit data...
hostfs Loading commit data...
hpfs Loading commit data...
hugetlbfs Loading commit data...
isofs Loading commit data...
jbd2 Loading commit data...
jffs2 Loading commit data...
jfs Loading commit data...
kernfs Loading commit data...
lockd Loading commit data...
logfs Loading commit data...
minix Loading commit data...
ncpfs Loading commit data...
nfs Loading commit data...
nfs_common Loading commit data...
nfsd Loading commit data...
nilfs2 Loading commit data...
nls Loading commit data...
notify Loading commit data...
ntfs Loading commit data...
ocfs2 Loading commit data...
omfs Loading commit data...
openpromfs Loading commit data...
overlayfs Loading commit data...
proc Loading commit data...
pstore Loading commit data...
qnx4 Loading commit data...
qnx6 Loading commit data...
quota Loading commit data...
ramfs Loading commit data...
reiserfs Loading commit data...
romfs Loading commit data...
squashfs Loading commit data...
sysfs Loading commit data...
sysv Loading commit data...
tracefs Loading commit data...
ubifs Loading commit data...
udf Loading commit data...
ufs Loading commit data...
xfs Loading commit data...
Kconfig Loading commit data...
Kconfig.binfmt Loading commit data...
Makefile Loading commit data...
aio.c Loading commit data...
anon_inodes.c Loading commit data...
attr.c Loading commit data...
bad_inode.c Loading commit data...
binfmt_aout.c Loading commit data...
binfmt_elf.c Loading commit data...
binfmt_elf_fdpic.c Loading commit data...
binfmt_em86.c Loading commit data...
binfmt_flat.c Loading commit data...
binfmt_misc.c Loading commit data...
binfmt_script.c Loading commit data...
block_dev.c Loading commit data...
buffer.c Loading commit data...
char_dev.c Loading commit data...
compat.c Loading commit data...
compat_binfmt_elf.c Loading commit data...
compat_ioctl.c Loading commit data...
coredump.c Loading commit data...
dax.c Loading commit data...
dcache.c Loading commit data...
dcookies.c Loading commit data...
direct-io.c Loading commit data...
drop_caches.c Loading commit data...
eventfd.c Loading commit data...
eventpoll.c Loading commit data...
exec.c Loading commit data...
fcntl.c Loading commit data...
fhandle.c Loading commit data...
file.c Loading commit data...
file_table.c Loading commit data...
filesystems.c Loading commit data...
fs-writeback.c Loading commit data...
fs_pin.c Loading commit data...
fs_struct.c Loading commit data...
inode.c Loading commit data...
internal.h Loading commit data...
ioctl.c Loading commit data...
libfs.c Loading commit data...
locks.c Loading commit data...
mbcache.c Loading commit data...
mount.h Loading commit data...
mpage.c Loading commit data...
namei.c Loading commit data...
namespace.c Loading commit data...
no-block.c Loading commit data...
nsfs.c Loading commit data...
open.c Loading commit data...
pipe.c Loading commit data...
pnode.c Loading commit data...
pnode.h Loading commit data...
posix_acl.c Loading commit data...
proc_namespace.c Loading commit data...
read_write.c Loading commit data...
readdir.c Loading commit data...
select.c Loading commit data...
seq_file.c Loading commit data...
signalfd.c Loading commit data...
splice.c Loading commit data...
stack.c Loading commit data...
stat.c Loading commit data...
statfs.c Loading commit data...
super.c Loading commit data...
sync.c Loading commit data...
timerfd.c Loading commit data...
userfaultfd.c Loading commit data...
utimes.c Loading commit data...
xattr.c Loading commit data...