Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c7fb3f06 authored by Trond Myklebust's avatar Trond Myklebust Committed by J. Bruce Fields
Browse files

SUNRPC: svc_tcp_write_space: don't clear SOCK_NOSPACE prematurely



If requests are queued in the socket inbuffer waiting for an
svc_tcp_has_wspace() requirement to be satisfied, then we do not want
to clear the SOCK_NOSPACE flag until we've satisfied that requirement.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 0971374e
Loading
Loading
Loading
Loading
+21 −18
Original line number Diff line number Diff line
@@ -446,11 +446,31 @@ static void svc_write_space(struct sock *sk)
	}
}

static int svc_tcp_has_wspace(struct svc_xprt *xprt)
{
	struct svc_sock *svsk =	container_of(xprt, struct svc_sock, sk_xprt);
	struct svc_serv *serv = svsk->sk_xprt.xpt_server;
	int required;

	if (test_bit(XPT_LISTENER, &xprt->xpt_flags))
		return 1;
	required = atomic_read(&xprt->xpt_reserved) + serv->sv_max_mesg;
	if (sk_stream_wspace(svsk->sk_sk) >= required ||
	    (sk_stream_min_wspace(svsk->sk_sk) == 0 &&
	     atomic_read(&xprt->xpt_reserved) == 0))
		return 1;
	set_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
	return 0;
}

static void svc_tcp_write_space(struct sock *sk)
{
	struct svc_sock *svsk = (struct svc_sock *)(sk->sk_user_data);
	struct socket *sock = sk->sk_socket;

	if (sk_stream_is_writeable(sk) && sock)
	if (!sk_stream_is_writeable(sk) || !sock)
		return;
	if (!svsk || svc_tcp_has_wspace(&svsk->sk_xprt))
		clear_bit(SOCK_NOSPACE, &sock->flags);
	svc_write_space(sk);
}
@@ -1198,23 +1218,6 @@ static void svc_tcp_prep_reply_hdr(struct svc_rqst *rqstp)
	svc_putnl(resv, 0);
}

static int svc_tcp_has_wspace(struct svc_xprt *xprt)
{
	struct svc_sock *svsk =	container_of(xprt, struct svc_sock, sk_xprt);
	struct svc_serv *serv = svsk->sk_xprt.xpt_server;
	int required;

	if (test_bit(XPT_LISTENER, &xprt->xpt_flags))
		return 1;
	required = atomic_read(&xprt->xpt_reserved) + serv->sv_max_mesg;
	if (sk_stream_wspace(svsk->sk_sk) >= required ||
	    (sk_stream_min_wspace(svsk->sk_sk) == 0 &&
	     atomic_read(&xprt->xpt_reserved) == 0))
		return 1;
	set_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
	return 0;
}

static struct svc_xprt *svc_tcp_create(struct svc_serv *serv,
				       struct net *net,
				       struct sockaddr *sa, int salen,