diff options
Diffstat (limited to 'fs/fuse')
| -rw-r--r-- | fs/fuse/dev.c | 2 | ||||
| -rw-r--r-- | fs/fuse/file.c | 8 |
2 files changed, 8 insertions, 2 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 1f64ae6d7a69..8207855f9af2 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1989,7 +1989,7 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud, */ if (!oh.unique) { err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), cs); - goto out; + goto copy_finish; } err = -EINVAL; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 49659d1b2932..a8218a3bc0b4 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -355,8 +355,14 @@ void fuse_file_release(struct inode *inode, struct fuse_file *ff, * Make the release synchronous if this is a fuseblk mount, * synchronous RELEASE is allowed (and desirable) in this case * because the server can be trusted not to screw up. + * + * Always use the asynchronous file put because the current thread + * might be the fuse server. This can happen if a process starts some + * aio and closes the fd before the aio completes. Since aio takes its + * own ref to the file, the IO completion has to drop the ref, which is + * how the fuse server can end up closing its clients' files. */ - fuse_file_put(ff, ff->fm->fc->destroy); + fuse_file_put(ff, false); } void fuse_release_common(struct file *file, bool isdir) |
