[Devel] [PATCH RHEL7 COMMIT] fuse: pcs: missing timeout at authentication phase

Konstantin Khorenko khorenko at virtuozzo.com
Wed Jan 18 18:13:31 MSK 2023


The commit is pushed to "branch-rh7-3.10.0-1160.80.1.vz7.192.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1160.80.1.vz7.192.2
------>
commit 0e2dc592dba4490bd50d097e3c997124ef6ba3fd
Author: Alexey Kuznetsov <kuznet at acronis.com>
Date:   Tue Jan 17 13:31:03 2023 +0000

    fuse: pcs: missing timeout at authentication phase
    
    It was forgotten at kernel implementation since connect
    has been move to kernel. See commit b94eed73ce78 ("fs/fuse kio:
    implement internal cs connection")
    
    The result are accidental lockups at kernel level.
    Plain luck this happens not so frequently. It is necessary
    that a CS dies, its port was taken by another service, which
    does not respond to garbage messages, and that kernel decided
    to connect to CS without reacquiring new map, which is also
    rather an exception. Yet we were hit bad after 2 years.
    
    Affects: #VSTOR-62165
    https://pmc.acronis.work/browse/VSTOR-62165
    
    Signed-off-by: Alexey Kuznetsov <kuznet at acronis.com>
---
 fs/fuse/kio/pcs/pcs_sock_io.c | 33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/fs/fuse/kio/pcs/pcs_sock_io.c b/fs/fuse/kio/pcs/pcs_sock_io.c
index f159ca0d9636..066e48306067 100644
--- a/fs/fuse/kio/pcs/pcs_sock_io.c
+++ b/fs/fuse/kio/pcs/pcs_sock_io.c
@@ -758,6 +758,24 @@ static int pcs_sock_send_buf(struct socket *sock, void *buf, size_t size)
 	return ret < 0 ? ret : 0;
 }
 
+static int pcs_sock_set_rcv_timeo(struct socket * sock, int tmo)
+{
+	if (sock->sk == NULL)
+		return -EINVAL;
+
+	/* No need to lock the socket. We own it and this option does not
+	 * affect protocol.
+	 */
+
+	if (tmo <= 0) {
+		sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
+	} else {
+		sock->sk->sk_rcvtimeo = tmo;
+	}
+
+	return 0;
+}
+
 static int pcs_sock_recv_buf(struct socket *sock, void *buf, size_t size)
 {
 	struct msghdr msg = {
@@ -784,16 +802,22 @@ static int pcs_sock_sync_send(struct pcs_netio *netio, struct pcs_msg *msg)
 static int pcs_sock_sync_recv(struct pcs_netio *netio, struct pcs_msg **msg)
 {
 	struct pcs_sockio *sio = sio_from_netio(netio);
+	struct pcs_rpc *ep = netio->parent;
 	struct pcs_rpc_hdr hdr;
 	int err;
 
-	err = pcs_sock_recv_buf(sio->socket, &hdr, sizeof(hdr));
+	err = pcs_sock_set_rcv_timeo(sio->socket, ep->params.connect_timeout);
 	if (err)
 		return err;
 
+	err = pcs_sock_recv_buf(sio->socket, &hdr, sizeof(hdr));
+	if (err)
+		goto out;
+
+	err = -ENOMEM;
 	*msg = pcs_rpc_alloc_output_msg(hdr.len);
 	if (!*msg)
-		return -ENOMEM;
+		goto out;
 
 	memcpy((*msg)->_inline_buffer, &hdr, sizeof(hdr));
 
@@ -802,10 +826,11 @@ static int pcs_sock_sync_recv(struct pcs_netio *netio, struct pcs_msg **msg)
 	if (err) {
 		pcs_free_msg(*msg);
 		*msg = NULL;
-		return err;
 	}
 
-	return 0;
+out:
+	(void)pcs_sock_set_rcv_timeo(sio->socket, -1);
+	return err;
 }
 
 struct pcs_netio_tops pcs_sock_netio_tops = {


More information about the Devel mailing list