diff options
author | Miklos Szeredi <mszeredi@redhat.com> | 2021-10-22 17:03:01 +0200 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2021-10-22 17:03:01 +0200 |
commit | 36ea23374d1f7b6a9d96a2b61d38830fdf23e45d (patch) | |
tree | 6f4c14172f81b51aee4d208aa252c1a66a4b2adc /fs/fuse/file.c | |
parent | 5c791fe1e2a4f401f819065ea4fc0450849f1818 (diff) | |
download | linux-36ea23374d1f7b6a9d96a2b61d38830fdf23e45d.tar.bz2 |
fuse: write inode in fuse_vma_close() instead of fuse_release()
Fuse ->release() is otherwise asynchronous for the reason that it can
happen in contexts unrelated to close/munmap.
Inode is already written back from fuse_flush(). Add it to
fuse_vma_close() as well to make sure inode dirtying from mmaps also get
written out before the file is released.
Also add error handling.
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/fuse/file.c')
-rw-r--r-- | fs/fuse/file.c | 15 |
1 files changed, 6 insertions, 9 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 5c5ed58d91a7..01d9b3272015 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -339,12 +339,6 @@ static int fuse_open(struct inode *inode, struct file *file) static int fuse_release(struct inode *inode, struct file *file) { - struct fuse_conn *fc = get_fuse_conn(inode); - - /* see fuse_vma_close() for !writeback_cache case */ - if (fc->writeback_cache) - write_inode_now(inode, 1); - fuse_release_common(file, false); /* return value is ignored by VFS */ @@ -2351,12 +2345,15 @@ static int fuse_launder_page(struct page *page) } /* - * Write back dirty pages now, because there may not be any suitable - * open files later + * Write back dirty data/metadata now (there may not be any suitable + * open files later for data) */ static void fuse_vma_close(struct vm_area_struct *vma) { - filemap_write_and_wait(vma->vm_file->f_mapping); + int err; + + err = write_inode_now(vma->vm_file->f_mapping->host, 1); + mapping_set_error(vma->vm_file->f_mapping, err); } /* |