[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