[RHEL7,COMMIT] fs/fuse kio: drop maps on file close

Submitted by Konstantin Khorenko on June 25, 2019, 9:48 a.m.

Details

Message ID 201906250948.x5P9mjXi015322@finist-ce7.sw.ru
State New
Series "fs/fuse kio: drop maps on file close"
Headers show

Commit Message

Konstantin Khorenko June 25, 2019, 9:48 a.m.
The commit is pushed to "branch-rh7-3.10.0-957.12.2.vz7.96.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-957.12.2.vz7.96.18
------>
commit 9175828fad3e48179ac06efcd0bb278b9c0aa8b0
Author: Pavel Butsykin <pbutsykin@virtuozzo.com>
Date:   Tue Jun 25 12:48:44 2019 +0300

    fs/fuse kio: drop maps on file close
    
    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.
    
    https://pmc.acronis.com/browse/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,
 };