[RHEL7,COMMIT] fuse kio: Move abort & destroy block up in pcs_rpc_send()

Submitted by Konstantin Khorenko on Oct. 18, 2018, 12:01 p.m.

Details

Message ID 201810181201.w9IC1Ym0030139@finist-ce7.sw.ru
State New
Series "Order rpc destroy with rpc_queue_work()"
Headers show

Commit Message

Konstantin Khorenko Oct. 18, 2018, 12:01 p.m.
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.11
------>
commit 59c9cec735685f77d2fcc6b23face0db8f25540d
Author: Kirill Tkhai <ktkhai@virtuozzo.com>
Date:   Thu Oct 18 15:01:34 2018 +0300

    fuse kio: Move abort & destroy block up in pcs_rpc_send()
    
    On destruction we want to silently done all messages
    with error, and immediately return from work. But
    above pcs_rpc_get(ep) prevents to implement fine flush
    on destruction, since there we have finally decremented
    counter.
    
    Previous patch tought all potential places, which may
    touch msg->rpc from their msg->done callbacks, to skip
    doing this in case of msg->rpc is NULL. So, here we
    moves abort & destroy block at the top of function and
    avoid doing pcs_rpc_get() for them.
    
    Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
    Reviewed-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
    
    =====================
    Patchset description:
    
    Order rpc destroy with rpc_queue_work()
    
    Prevents use-after-free from work function.
    
    https://pmc.acronis.com/browse/VSTOR-16236
    
    Kirill Tkhai (3):
          fuse kio: Stop self-abuse of rpc counter in rpc_queue_work()
          fuse kio: Check for null ep in pcs_rpc_deaccount_msg()
          fuse kio: Move abort & destroy block up in pcs_rpc_send()
    
    Pavel Butsykin (1):
          fs/fuse kio_pcs: flush rpc work inside pcs_rpc_destroy()
---
 fs/fuse/kio/pcs/pcs_rpc.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/kio/pcs/pcs_rpc.c b/fs/fuse/kio/pcs/pcs_rpc.c
index 8c76bb44f0a2..0717eeb6e99f 100644
--- a/fs/fuse/kio/pcs/pcs_rpc.c
+++ b/fs/fuse/kio/pcs/pcs_rpc.c
@@ -632,6 +632,13 @@  static void pcs_rpc_send(struct pcs_rpc * ep, struct pcs_msg * msg, bool requeue
 
 	TRACE("ENTER ep:%p state:%d msg:%p\n", ep, ep->state, msg);
 
+	if (ep->state == PCS_RPC_ABORT || ep->state == PCS_RPC_DESTROY) {
+		pcs_set_rpc_error(&msg->error, PCS_ERR_NET_ABORT, ep);
+		pcs_msg_del_calendar(msg);
+		msg->done(msg);
+		return;
+	}
+
 	if (!requeue) {
 		msg->rpc = pcs_rpc_get(ep);
 		if (msg->timeout) {
@@ -654,13 +661,6 @@  static void pcs_rpc_send(struct pcs_rpc * ep, struct pcs_msg * msg, bool requeue
 		return;
 	}
 
-	if (ep->state == PCS_RPC_ABORT || ep->state == PCS_RPC_DESTROY) {
-		pcs_set_rpc_error(&msg->error, PCS_ERR_NET_ABORT, ep);
-		pcs_msg_del_calendar(msg);
-		msg->done(msg);
-		return;
-	}
-
 	list_add_tail(&msg->list, &ep->state_queue);
 	msg->stage = PCS_MSG_STAGE_UNSENT;