diff options
author | Vivek Goyal <vgoyal@redhat.com> | 2020-04-20 17:01:34 +0200 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2020-04-20 17:01:34 +0200 |
commit | bb737bbe48bea9854455cb61ea1dc06e92ce586c (patch) | |
tree | 71a1a272091c32f5f9a8e28a7bf3a280109f904a /fs/fuse/fuse_i.h | |
parent | ae83d0b416db002fe95601e7f97f64b59514d936 (diff) | |
download | lwn-bb737bbe48bea9854455cb61ea1dc06e92ce586c.tar.gz lwn-bb737bbe48bea9854455cb61ea1dc06e92ce586c.zip |
virtiofs: schedule blocking async replies in separate worker
In virtiofs (unlike in regular fuse) processing of async replies is
serialized. This can result in a deadlock in rare corner cases when
there's a circular dependency between the completion of two or more async
replies.
Such a deadlock can be reproduced with xfstests:generic/503 if TEST_DIR ==
SCRATCH_MNT (which is a misconfiguration):
- Process A is waiting for page lock in worker thread context and blocked
(virtio_fs_requests_done_work()).
- Process B is holding page lock and waiting for pending writes to
finish (fuse_wait_on_page_writeback()).
- Write requests are waiting in virtqueue and can't complete because
worker thread is blocked on page lock (process A).
Fix this by creating a unique work_struct for each async reply that can
block (O_DIRECT read).
Fixes: a62a8ef9d97d ("virtio-fs: add virtiofs filesystem")
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/fuse/fuse_i.h')
-rw-r--r-- | fs/fuse/fuse_i.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index ca344bf71404..d7cde216fc87 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -249,6 +249,7 @@ struct fuse_args { bool out_argvar:1; bool page_zeroing:1; bool page_replace:1; + bool may_block:1; struct fuse_in_arg in_args[3]; struct fuse_arg out_args[2]; void (*end)(struct fuse_conn *fc, struct fuse_args *args, int error); |