summaryrefslogtreecommitdiffstats
path: root/fs/fuse/file.c
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2021-10-22 17:03:01 +0200
committerMiklos Szeredi <mszeredi@redhat.com>2021-10-22 17:03:01 +0200
commit36ea23374d1f7b6a9d96a2b61d38830fdf23e45d (patch)
tree6f4c14172f81b51aee4d208aa252c1a66a4b2adc /fs/fuse/file.c
parent5c791fe1e2a4f401f819065ea4fc0450849f1818 (diff)
downloadlinux-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.c15
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);
}
/*