patch-2.2.19 linux/net/sunrpc/xprt.c
Next file: linux/net/unix/af_unix.c
Previous file: linux/net/sunrpc/svcsock.c
Back to the patch index
Back to the overall index
- Lines: 195
- Date:
Sun Mar 25 11:37:42 2001
- Orig file:
v2.2.18/net/sunrpc/xprt.c
- Orig date:
Sun Mar 25 11:28:40 2001
diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.18/net/sunrpc/xprt.c linux/net/sunrpc/xprt.c
@@ -1010,7 +1010,8 @@
switch (sk->state) {
case TCP_ESTABLISHED:
- xprt_set_connected(xprt);
+ if (xprt_test_and_set_connected(xprt))
+ break;
if (xprt->snd_task && xprt->snd_task->tk_rpcwait == &xprt->sending)
rpc_wake_up_task(xprt->snd_task);
rpc_wake_up(&xprt->reconn);
@@ -1045,16 +1046,14 @@
if (sock_wspace(sk) < min(sk->sndbuf,XPRT_MIN_WRITE_SPACE))
return;
- spin_lock_irqsave(&xprt_sock_lock, oldflags);
- if (xprt->write_space)
- goto out_unlock;
-
- xprt->write_space = 1;
+ if (xprt_test_and_set_wspace(xprt))
+ goto out;
+ spin_lock_irqsave(&xprt_sock_lock, oldflags);
if (xprt->snd_task && xprt->snd_task->tk_rpcwait == &xprt->sending)
rpc_wake_up_task(xprt->snd_task);
- out_unlock:
spin_unlock_irqrestore(&xprt_sock_lock, oldflags);
+ out:
wake_up_interruptible(sk->sleep);
}
@@ -1073,16 +1072,14 @@
if (sock_wspace(sk) < min(sk->sndbuf,XPRT_MIN_WRITE_SPACE))
return;
- spin_lock_irqsave(&xprt_sock_lock, oldflags);
- if (xprt->write_space)
- goto out_unlock;
-
- xprt->write_space = 1;
+ if (xprt_test_and_set_wspace(xprt))
+ goto out;
+ spin_lock_irqsave(&xprt_sock_lock, oldflags);
if (xprt->snd_task && xprt->snd_task->tk_rpcwait == &xprt->sending)
rpc_wake_up_task(xprt->snd_task);
- out_unlock:
spin_unlock_irqrestore(&xprt_sock_lock, oldflags);
+ out:
wake_up_interruptible(sk->sleep);
}
@@ -1115,8 +1112,10 @@
{
struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt;
struct rpc_rqst *req = task->tk_rqstp;
+ unsigned long oldflags;
xprt_delete_tcp_timer(xprt);
+ spin_lock_irqsave(&xprt_sock_lock, oldflags);
if (xprt->snd_task && xprt->snd_task != task) {
dprintk("RPC: %4d TCP write queue full (task %d)\n",
task->tk_pid, xprt->snd_task->tk_pid);
@@ -1130,6 +1129,7 @@
#endif
req->rq_bytes_sent = 0;
}
+ spin_unlock_irqrestore(&xprt_sock_lock, oldflags);
return xprt->snd_task == task;
}
@@ -1142,9 +1142,12 @@
struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt;
if (xprt->snd_task && xprt->snd_task == task) {
+ unsigned long oldflags;
+ spin_lock_irqsave(&xprt_sock_lock, oldflags);
xprt->snd_task = NULL;
if (!rpc_wake_up_next(&xprt->sending) && xprt->stream)
xprt_add_tcp_timer(xprt, RPCXPRT_TIMEOUT);
+ spin_unlock_irqrestore(&xprt_sock_lock, oldflags);
}
}
@@ -1209,7 +1212,7 @@
if (!xprt->inet)
break;
- xprt->write_space = 0;
+ xprt_clear_wspace(xprt);
status = -ENOMEM;
if (sock_wspace(xprt->inet) < req->rq_slen + MIN_WRITE_SPACE)
break;
@@ -1256,20 +1259,12 @@
case -ENOMEM:
/* Protect against (udp|tcp)_write_space */
spin_lock_irqsave(&xprt_sock_lock, oldflags);
- if (!xprt->write_space) {
+ if (!xprt_wspace(xprt)) {
task->tk_timeout = req->rq_timeout.to_current;
rpc_sleep_on(&xprt->sending, task, NULL, NULL);
}
spin_unlock_irqrestore(&xprt_sock_lock, oldflags);
return;
- case -EAGAIN:
- case -ECONNREFUSED:
- case -ENOTCONN:
- /* Keep holding the socket if it is blocked */
- if (!xprt->stream) {
- rpc_delay(task, HZ>>4);
- return;
- }
default:
goto out_release;
}
@@ -1297,7 +1292,7 @@
dprintk("RPC: %4d xprt_receive\n", task->tk_pid);
- req->rq_received= 0;
+ req->rq_received = 0;
task->tk_timeout = 0;
rpc_sleep_locked(&xprt->pending, task, NULL, NULL);
}
@@ -1420,6 +1415,62 @@
}
/*
+ * Reserve a ping RPC call slot.
+ */
+int
+xprt_ping_reserve(struct rpc_task *task)
+{
+ struct rpc_xprt *xprt = task->tk_xprt;
+ struct rpc_rqst *req;
+
+ /* We already have an initialized request. */
+ if (task->tk_rqstp)
+ return 0;
+ if (xprt->shutdown)
+ task->tk_status = -EIO;
+
+ dprintk("RPC: %4d xprt_ping_reserve cong = %ld cwnd = %ld\n",
+ task->tk_pid, xprt->cong, xprt->cwnd);
+ start_bh_atomic();
+ if ((req = xprt->free) != NULL) {
+ xprt->free = req->rq_next;
+ req->rq_next = NULL;
+ task->tk_rqstp = req;
+ xprt_request_init(task, xprt);
+ } else
+ task->tk_status = -ENOBUFS;
+ end_bh_atomic();
+ dprintk("RPC: %4d xprt_ping_reserve returns %d\n",
+ task->tk_pid, task->tk_status);
+ if (!req)
+ BUG();
+ return task->tk_status;
+}
+
+/*
+ * Release an RPC call slot
+ */
+void
+xprt_ping_release(struct rpc_task *task)
+{
+ struct rpc_xprt *xprt = task->tk_xprt;
+ struct rpc_rqst *req;
+
+ xprt_up_transmit(task);
+ if (!(req = task->tk_rqstp))
+ return;
+ task->tk_rqstp = NULL;
+ memset(req, 0, sizeof(*req)); /* mark unused */
+
+ dprintk("RPC: %4d release request %p\n", task->tk_pid, req);
+
+ start_bh_atomic();
+ req->rq_next = xprt->free;
+ xprt->free = req;
+ end_bh_atomic();
+}
+
+/*
* Set default timeout parameters
*/
void
@@ -1490,6 +1541,7 @@
xprt->sending = RPC_INIT_WAITQ("xprt_sending");
xprt->backlog = RPC_INIT_WAITQ("xprt_backlog");
xprt->reconn = RPC_INIT_WAITQ("xprt_reconn");
+ xprt->pingwait = RPC_INIT_WAITQ("xprt_pingwait");
/* initialize free list */
for (i = 0, req = xprt->slot; i < RPC_MAXREQS-1; i++, req++)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)