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 <ktk...@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 <ktk...@virtuozzo.com> Reviewed-by: Pavel Butsykin <pbutsy...@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 */ _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel