[Devel] [PATCH] fs/fuse kio: drop maps on file close

Pavel Butsykin pbutsykin at virtuozzo.com
Tue Jun 25 10:52:32 MSK 2019


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 at 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(+)

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,
 };
-- 
2.15.1



More information about the Devel mailing list