[Devel] [PATCH RHEL7 COMMIT] fuse kio: Destroy rpc in work func

Konstantin Khorenko khorenko at virtuozzo.com
Tue Oct 16 18:09:25 MSK 2018


The commit is pushed to "branch-rh7-3.10.0-862.14.4.vz7.72.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.14.4.vz7.72.9
------>
commit 7ba0ca7d034c9471c431cc2664f5bf3ff8ab0154
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date:   Tue Oct 16 12:21:13 2018 +0300

    fuse kio: Destroy rpc in work func
    
    This is preparation to making socket callbacks
    use RCU to access sio pointers and for pinning
    ep to sio.
    
    v2: New (was "fuse kio: Free sockio in work func")
    
    Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
    Reviewed-by: Pavel Butsykin <pbutsykin at virtuozzo.com>
    
    =====================
    Patchset description:
    
    Order pcs_rpc and pcs_sockio destruction and close leaked socket
    
    https://pmc.acronis.com/browse/VSTOR-15305
    
    Ploop can asynchronously unmap regions by sending IOCB_CMD_UNMAP_ITER, but this
    command isn't quite correctly interpreted in Fuse. Moreover, in Fast-path mode,
    fallocate(FALLOC_FL_PUNCH_HOLE|FALLOC_FL_ZERO_RANGE) falls to fuse user daemon
    and it can lead to data corruption.
    
    Let's fix it.
    
    Kirill Tkhai (9):
          fuse kio: Use __maybe_unused
          fuse kio: Use sio eof instead of parent to determ abort
          fuse kio: Reorder callback assignment
          fuse kio: Add pcs_cleanup_wq
          fuse kio: Destroy rpc in work func
          fuse kio: Introduce pcs_sk_kick_queue()
          fuse kio: Dereference sk_user_data under rcu
          fuse kio: Fix rpc socket leak on rpc_abort()
          fuse kio: Hold pcs_rpc counter till sio may be freed
---
 fs/fuse/kio/pcs/pcs_rpc.c | 24 +++++++++++++++++++++++-
 fs/fuse/kio/pcs/pcs_rpc.h |  5 +++--
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/fs/fuse/kio/pcs/pcs_rpc.c b/fs/fuse/kio/pcs/pcs_rpc.c
index e7ae4bfd9feb..9035b504121b 100644
--- a/fs/fuse/kio/pcs/pcs_rpc.c
+++ b/fs/fuse/kio/pcs/pcs_rpc.c
@@ -296,7 +296,7 @@ void pcs_rpc_attach_new_ep(struct pcs_rpc * ep, struct pcs_rpc_engine * eng)
 	spin_unlock(&eng->lock);
 }
 
-void pcs_rpc_destroy(struct pcs_rpc * ep)
+static void pcs_rpc_destroy(struct pcs_rpc *ep)
 {
 	bool flush;
 	BUG_ON(ep->state != PCS_RPC_DESTROY);
@@ -328,6 +328,28 @@ void pcs_rpc_destroy(struct pcs_rpc * ep)
 	kfree(ep);
 }
 
+static LLIST_HEAD(rpc_cleanup_list);
+
+static void rpc_cleanup_func(struct work_struct *work)
+{
+	struct llist_node *list = llist_del_all(&rpc_cleanup_list);
+	struct pcs_rpc *rpc, *tmp;
+
+	if (unlikely(!list))
+		return;
+
+	llist_for_each_entry_safe(rpc, tmp, list, cleanup_node)
+		pcs_rpc_destroy(rpc);
+}
+
+static DECLARE_WORK(rpc_cleanup_work, rpc_cleanup_func);
+
+void __pcs_rpc_put(struct pcs_rpc *ep)
+{
+	if (llist_add(&ep->cleanup_node, &rpc_cleanup_list))
+		queue_work(pcs_cleanup_wq, &rpc_cleanup_work);
+}
+
 static void rpc_eof_cb(struct pcs_sockio * sio)
 {
 	struct pcs_rpc * ep = sio->parent;
diff --git a/fs/fuse/kio/pcs/pcs_rpc.h b/fs/fuse/kio/pcs/pcs_rpc.h
index 1181d84ba75c..8d3c571fd1e2 100644
--- a/fs/fuse/kio/pcs/pcs_rpc.h
+++ b/fs/fuse/kio/pcs/pcs_rpc.h
@@ -125,6 +125,7 @@ struct pcs_rpc
 	unsigned		kill_arrow;
 #define RPC_MAX_CALENDAR	PCS_MSG_MAX_CALENDAR
 	struct hlist_head	kill_calendar[RPC_MAX_CALENDAR];
+	struct llist_node	cleanup_node;
 
 	struct pcs_cs *		private;
 };
@@ -197,13 +198,13 @@ static inline struct pcs_rpc * pcs_rpc_get(struct pcs_rpc * p)
 	return p;
 }
 
-void pcs_rpc_destroy(struct pcs_rpc * p);
+extern void __pcs_rpc_put(struct pcs_rpc *ep);
 
 static inline void pcs_rpc_put(struct pcs_rpc * p)
 {
 	BUG_ON(atomic_read(&p->refcnt) <=0);
 	if (atomic_dec_and_test(&p->refcnt))
-		pcs_rpc_destroy(p);
+		__pcs_rpc_put(p);
 }
 
 /* Function provided by rpc engine */



More information about the Devel mailing list