[Devel] [PATCH] fs/fuse kio: invalidate files for kio

Pavel Butsykin pbutsykin at virtuozzo.com
Fri Jan 18 16:43:32 MSK 2019


Make fuse_invalidate_files() work for kio. This is necessary to maintain
vstorage revoke in FPath mode. To do this, let's add a list of inflight kio
requests to be able to handle this list in fuse_invalidate_files(). The list
will also be useful to implement the full-featured .vstorage.info and
fuse_abort_conn() for kio.

#VSTOR-19620

Signed-off-by: Pavel Butsykin <pbutsykin at virtuozzo.com>
---
 fs/fuse/fuse_i.h                   |  4 ++++
 fs/fuse/inode.c                    |  8 ++++++--
 fs/fuse/kio/pcs/fuse_io.c          |  5 +++++
 fs/fuse/kio/pcs/pcs_cluster.c      |  2 ++
 fs/fuse/kio/pcs/pcs_cluster.h      |  1 +
 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 16 ++++++++++++++++
 6 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 4c27bfa0e74d..0914940d6735 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -528,6 +528,7 @@ struct fuse_kio_ops {
 	int  (*file_open)(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);
 
 };
 int fuse_register_kio(struct fuse_kio_ops *ops);
@@ -1107,4 +1108,7 @@ struct fuse_file *fuse_write_file(struct fuse_conn *fc, struct fuse_inode *fi);
 
 void fuse_release_ff(struct inode *inode, struct fuse_file *ff);
 
+void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode,
+			struct list_head *req_list);
+
 #endif /* _FS_FUSE_I_H */
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 34e52262d37e..cb275ff21991 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -369,8 +369,8 @@ int fuse_reverse_inval_inode(struct super_block *sb, u64 nodeid,
 	return 0;
 }
 
-static void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode,
-			       struct list_head *req_list)
+void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode,
+			struct list_head *req_list)
 {
 	struct fuse_req *req;
 
@@ -393,6 +393,7 @@ static void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode,
 			req->num_pages = 0;
 		}
 }
+EXPORT_SYMBOL_GPL(fuse_kill_requests);
 
 int fuse_invalidate_files(struct fuse_conn *fc, u64 nodeid)
 {
@@ -442,6 +443,9 @@ int fuse_invalidate_files(struct fuse_conn *fc, u64 nodeid)
 		}
 		fuse_kill_requests(fc, inode, &fc->main_iq.pending);
 		fuse_kill_requests(fc, inode, &fc->bg_queue);
+		if (fc->kio.op && fc->kio.op->kill_requests)
+			fc->kio.op->kill_requests(fc, inode);
+
 		wake_up(&fi->page_waitq); /* readpage[s] can wait on fuse wb */
 		spin_unlock(&fc->lock);
 
diff --git a/fs/fuse/kio/pcs/fuse_io.c b/fs/fuse/kio/pcs/fuse_io.c
index 61a2e7f1eac6..00a72c878efb 100644
--- a/fs/fuse/kio/pcs/fuse_io.c
+++ b/fs/fuse/kio/pcs/fuse_io.c
@@ -205,6 +205,7 @@ static void prepare_io_(struct pcs_fuse_req *r, unsigned short type, off_t offse
 static void ioreq_complete(pcs_api_iorequest_t *ioreq)
 {
 	struct pcs_fuse_req *r = ioreq->datasource;
+	struct fuse_conn *fc = cl_from_req(r)->fc;
 
 	BUG_ON(ioreq != &r->exec.io.req);
 
@@ -217,6 +218,10 @@ static void ioreq_complete(pcs_api_iorequest_t *ioreq)
 		r->req.out.h.error = 0;
 	}
 
+	spin_lock(&fc->lock);
+	list_del_init(&r->req.list);
+	spin_unlock(&fc->lock);
+
 	switch (ioreq->type) {
 	case PCS_REQ_T_READ:
 		on_read_done(r, ioreq->size);
diff --git a/fs/fuse/kio/pcs/pcs_cluster.c b/fs/fuse/kio/pcs/pcs_cluster.c
index 5df263f01f98..6b8f38db5c40 100644
--- a/fs/fuse/kio/pcs/pcs_cluster.c
+++ b/fs/fuse/kio/pcs/pcs_cluster.c
@@ -608,6 +608,8 @@ int pcs_cluster_init(struct pcs_fuse_cluster *pfc, struct workqueue_struct *wq,
 	pfc->cc.op.ireq_on_error   = ireq_on_error_;
 	pfc->cc.op.ireq_check_redo = ireq_check_redo_;
 
+	INIT_LIST_HEAD(&pfc->kio_queue);
+
 	return 0;
 }
 
diff --git a/fs/fuse/kio/pcs/pcs_cluster.h b/fs/fuse/kio/pcs/pcs_cluster.h
index 9c537cb43b30..8a3ae3244b80 100644
--- a/fs/fuse/kio/pcs/pcs_cluster.h
+++ b/fs/fuse/kio/pcs/pcs_cluster.h
@@ -32,6 +32,7 @@ struct pcs_fuse_req {
 struct pcs_fuse_cluster {
 	struct pcs_cluster_core cc;
 	struct fuse_conn *fc;
+	struct list_head kio_queue;
 };
 
 struct pcs_fuse_work {
diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
index cdd4fe578128..1ca27b80b002 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -983,6 +983,12 @@ error:
 	return;
 
 submit:
+	if (!lk)
+		spin_lock(&pfc->fc->lock);
+	list_add_tail(&req->list, &pfc->kio_queue);
+	if (!lk)
+		spin_unlock(&pfc->fc->lock);
+
 	if (async)
 		pcs_cc_submit(ireq->cc, ireq);
 	else
@@ -1488,6 +1494,15 @@ void __kfuse_trace(struct fuse_conn * fc, unsigned long ip, const char * fmt, ..
 	put_cpu();
 }
 
+static void kpcs_kill_requests(struct fuse_conn *fc, struct inode *inode)
+{
+	struct pcs_fuse_cluster *pfc = (struct pcs_fuse_cluster*)fc->kio.ctx;
+
+	assert_spin_locked(&fc->lock);
+
+	return fuse_kill_requests(fc, inode, &pfc->kio_queue);
+}
+
 static struct fuse_kio_ops kio_pcs_ops = {
 	.name		= "pcs",
 	.owner		= THIS_MODULE,
@@ -1500,6 +1515,7 @@ static struct fuse_kio_ops kio_pcs_ops = {
 	.req_send	= kpcs_req_send,
 	.file_open	= kpcs_file_open,
 	.inode_release	= kpcs_inode_release,
+	.kill_requests	= kpcs_kill_requests,
 };
 
 
-- 
2.15.1



More information about the Devel mailing list