fs/fuse kio: drop maps on file close

Submitted by Pavel Butsykin on June 25, 2019, 7:52 a.m.

Details

Message ID 20190625075232.11995-1-pbutsykin@virtuozzo.com
State New
Series "fs/fuse kio: drop maps on file close"
Headers show

Commit Message

Pavel Butsykin June 25, 2019, 7:52 a.m.
This patch synchronizes cached maps on file closing between kernel and
user-space. In the processing of FUSE_RELEASE request in userspace, all maps
belonging to this inode are truncated, while in the kernel the same maps
remain cached. So, after reopen they are reused and when an error happens,
kernel queries user-space, but user-space doesn't have any map, so that it
cannot do correct request to mds.

#VSTOR-24004

Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
---
 fs/fuse/file.c                     |  3 +++
 fs/fuse/fuse_i.h                   |  2 ++
 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 19 +++++++++++++++++++
 3 files changed, 24 insertions(+)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 90921df2601c..79e64069e06a 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -467,6 +467,9 @@  static int fuse_release(struct inode *inode, struct file *file)
 		 */
 		mutex_lock(&inode->i_mutex);
 		fuse_sync_writes(inode);
+
+		if (ff->fc->kio.op->file_close)
+			ff->fc->kio.op->file_close(ff->fc, file, inode);
 		mutex_unlock(&inode->i_mutex);
 	}
 
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 8f3456b57d13..93ae1fe0ccdb 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -535,6 +535,8 @@  struct fuse_kio_ops {
 	/* Inode scope hooks */
 	int  (*file_open)(struct fuse_conn *fc, struct file *file,
 			  struct inode *inode);
+	void (*file_close)(struct fuse_conn *fc, struct file *file,
+			   struct inode *inode);
 	void (*inode_release)(struct fuse_inode *fi);
 	void (*kill_requests)(struct fuse_conn *fc, struct inode *inode);
 
diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
index bdaca666f6e9..f9470d31c8a9 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -420,6 +420,24 @@  int kpcs_file_open(struct fuse_conn *fc, struct file *file, struct inode *inode)
 	return ret;
 }
 
+static void kpcs_file_close(struct fuse_conn *fc, struct file *file,
+			    struct inode *inode)
+{
+	struct fuse_inode *fi = get_fuse_inode(inode);
+	struct pcs_dentry_info *di = fi->private;
+
+	lockdep_assert_held(&inode->i_mutex);
+
+	TRACE("file close - fi: %p, di: %p", fi, di);
+
+	if (!di)
+		return;
+
+	WARN_ON_ONCE(!list_empty(&di->size.queue));
+	WARN_ON_ONCE(!list_empty(&di->kq));
+	pcs_mapping_invalidate(&di->mapping);
+}
+
 void kpcs_inode_release(struct fuse_inode *fi)
 {
 	struct pcs_dentry_info *di = fi->private;
@@ -1667,6 +1685,7 @@  static struct fuse_kio_ops kio_pcs_ops = {
 	.req_classify	= kpcs_req_classify,
 	.req_send	= kpcs_req_send,
 	.file_open	= kpcs_file_open,
+	.file_close	= kpcs_file_close,
 	.inode_release	= kpcs_inode_release,
 	.kill_requests	= kpcs_kill_requests,
 };