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

Commit 6797fa5a authored by J. Bruce Fields's avatar J. Bruce Fields
Browse files

svcrpc: break up svc_recv



Matter of taste, I suppose, but svc_recv breaks up naturally into:

	allocate pages and setup arg
	dequeue (wait for, if necessary) next socket
	do something with that socket

And I find it easier to read when it doesn't go on for pages and pages.

Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 6741019c
Loading
Loading
Loading
Loading
+67 −36
Original line number Original line Diff line number Diff line
@@ -568,33 +568,12 @@ static void svc_check_conn_limits(struct svc_serv *serv)
	}
	}
}
}


/*
int svc_alloc_arg(struct svc_rqst *rqstp)
 * Receive the next request on any transport.  This code is carefully
 * organised not to touch any cachelines in the shared svc_serv
 * structure, only cachelines in the local svc_pool.
 */
int svc_recv(struct svc_rqst *rqstp, long timeout)
{
{
	struct svc_xprt		*xprt = NULL;
	struct svc_serv *serv = rqstp->rq_server;
	struct svc_serv *serv = rqstp->rq_server;
	struct svc_pool		*pool = rqstp->rq_pool;
	int			len, i;
	int			pages;
	struct xdr_buf *arg;
	struct xdr_buf *arg;
	DECLARE_WAITQUEUE(wait, current);
	int pages;
	long			time_left;
	int i;

	dprintk("svc: server %p waiting for data (to = %ld)\n",
		rqstp, timeout);

	if (rqstp->rq_xprt)
		printk(KERN_ERR
			"svc_recv: service %p, transport not NULL!\n",
			 rqstp);
	if (waitqueue_active(&rqstp->rq_wait))
		printk(KERN_ERR
			"svc_recv: service %p, wait queue active!\n",
			 rqstp);


	/* now allocate needed pages.  If we get a failure, sleep briefly */
	/* now allocate needed pages.  If we get a failure, sleep briefly */
	pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE;
	pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE;
@@ -624,11 +603,15 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
	arg->page_len = (pages-2)*PAGE_SIZE;
	arg->page_len = (pages-2)*PAGE_SIZE;
	arg->len = (pages-1)*PAGE_SIZE;
	arg->len = (pages-1)*PAGE_SIZE;
	arg->tail[0].iov_len = 0;
	arg->tail[0].iov_len = 0;
	return 0;
}


	try_to_freeze();
struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout)
	cond_resched();
{
	if (signalled() || kthread_should_stop())
	struct svc_xprt *xprt;
		return -EINTR;
	struct svc_pool		*pool = rqstp->rq_pool;
	DECLARE_WAITQUEUE(wait, current);
	long			time_left;


	/* Normally we will wait up to 5 seconds for any required
	/* Normally we will wait up to 5 seconds for any required
	 * cache information to be provided.
	 * cache information to be provided.
@@ -666,7 +649,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
		if (kthread_should_stop()) {
		if (kthread_should_stop()) {
			set_current_state(TASK_RUNNING);
			set_current_state(TASK_RUNNING);
			spin_unlock_bh(&pool->sp_lock);
			spin_unlock_bh(&pool->sp_lock);
			return -EINTR;
			return ERR_PTR(-EINTR);
		}
		}


		add_wait_queue(&rqstp->rq_wait, &wait);
		add_wait_queue(&rqstp->rq_wait, &wait);
@@ -687,19 +670,25 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
			spin_unlock_bh(&pool->sp_lock);
			spin_unlock_bh(&pool->sp_lock);
			dprintk("svc: server %p, no data yet\n", rqstp);
			dprintk("svc: server %p, no data yet\n", rqstp);
			if (signalled() || kthread_should_stop())
			if (signalled() || kthread_should_stop())
				return -EINTR;
				return ERR_PTR(-EINTR);
			else
			else
				return -EAGAIN;
				return ERR_PTR(-EAGAIN);
		}
		}
	}
	}
	spin_unlock_bh(&pool->sp_lock);
	spin_unlock_bh(&pool->sp_lock);
	return xprt;
}

static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt)
{
	struct svc_serv *serv = rqstp->rq_server;
	int len = 0;


	len = 0;
	if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
	if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
		dprintk("svc_recv: found XPT_CLOSE\n");
		dprintk("svc_recv: found XPT_CLOSE\n");
		svc_delete_xprt(xprt);
		svc_delete_xprt(xprt);
		/* Leave XPT_BUSY set on the dead xprt: */
		/* Leave XPT_BUSY set on the dead xprt: */
		goto out;
		return 0;
	}
	}
	if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
	if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
		struct svc_xprt *newxpt;
		struct svc_xprt *newxpt;
@@ -727,8 +716,9 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
			svc_xprt_received(newxpt);
			svc_xprt_received(newxpt);
		}
		}
	} else if (xprt->xpt_ops->xpo_has_wspace(xprt)) {
	} else if (xprt->xpt_ops->xpo_has_wspace(xprt)) {
		/* XPT_DATA|XPT_DEFERRED case: */
		dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n",
		dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n",
			rqstp, pool->sp_id, xprt,
			rqstp, rqstp->rq_pool->sp_id, xprt,
			atomic_read(&xprt->xpt_ref.refcount));
			atomic_read(&xprt->xpt_ref.refcount));
		rqstp->rq_deferred = svc_deferred_dequeue(xprt);
		rqstp->rq_deferred = svc_deferred_dequeue(xprt);
		if (rqstp->rq_deferred)
		if (rqstp->rq_deferred)
@@ -739,7 +729,48 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
		rqstp->rq_reserved = serv->sv_max_mesg;
		rqstp->rq_reserved = serv->sv_max_mesg;
		atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
		atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
	}
	}
	/* clear XPT_BUSY: */
	svc_xprt_received(xprt);
	svc_xprt_received(xprt);
	return len;
}

/*
 * Receive the next request on any transport.  This code is carefully
 * organised not to touch any cachelines in the shared svc_serv
 * structure, only cachelines in the local svc_pool.
 */
int svc_recv(struct svc_rqst *rqstp, long timeout)
{
	struct svc_xprt		*xprt = NULL;
	struct svc_serv		*serv = rqstp->rq_server;
	int			len, err;

	dprintk("svc: server %p waiting for data (to = %ld)\n",
		rqstp, timeout);

	if (rqstp->rq_xprt)
		printk(KERN_ERR
			"svc_recv: service %p, transport not NULL!\n",
			 rqstp);
	if (waitqueue_active(&rqstp->rq_wait))
		printk(KERN_ERR
			"svc_recv: service %p, wait queue active!\n",
			 rqstp);

	err = svc_alloc_arg(rqstp);
	if (err)
		return err;

	try_to_freeze();
	cond_resched();
	if (signalled() || kthread_should_stop())
		return -EINTR;

	xprt = svc_get_next_xprt(rqstp, timeout);
	if (IS_ERR(xprt))
		return PTR_ERR(xprt);

	len = svc_handle_xprt(rqstp, xprt);


	/* No data, incomplete (TCP) read, or accept() */
	/* No data, incomplete (TCP) read, or accept() */
	if (len <= 0)
	if (len <= 0)