diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-03-30 17:53:32 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-03-30 17:53:32 -0400 |
commit | 65fb0d23fcddd8697c871047b700c78817bdaa43 (patch) | |
tree | 119e6e5f276622c4c862f6c9b6d795264ba1603a /net/sunrpc | |
parent | 8c083f081d0014057901c68a0a3e0f8ca7ac8d23 (diff) | |
parent | dfbbe89e197a77f2c8046a51c74e33e35f878080 (diff) |
Merge branch 'linus' into cpumask-for-linus
Conflicts:
arch/x86/kernel/cpu/common.c
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 2 | ||||
-rw-r--r-- | net/sunrpc/sched.c | 33 | ||||
-rw-r--r-- | net/sunrpc/xprt.c | 2 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 76 |
4 files changed, 61 insertions, 52 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 577385a4a5dc..9ced0628d69c 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -480,7 +480,7 @@ static int rpc_delete_dentry(struct dentry *dentry) | |||
480 | return 1; | 480 | return 1; |
481 | } | 481 | } |
482 | 482 | ||
483 | static struct dentry_operations rpc_dentry_operations = { | 483 | static const struct dentry_operations rpc_dentry_operations = { |
484 | .d_delete = rpc_delete_dentry, | 484 | .d_delete = rpc_delete_dentry, |
485 | }; | 485 | }; |
486 | 486 | ||
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 385f427bedad..ff50a0546865 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
@@ -293,11 +293,6 @@ static void rpc_make_runnable(struct rpc_task *task) | |||
293 | rpc_clear_queued(task); | 293 | rpc_clear_queued(task); |
294 | if (rpc_test_and_set_running(task)) | 294 | if (rpc_test_and_set_running(task)) |
295 | return; | 295 | return; |
296 | /* We might have raced */ | ||
297 | if (RPC_IS_QUEUED(task)) { | ||
298 | rpc_clear_running(task); | ||
299 | return; | ||
300 | } | ||
301 | if (RPC_IS_ASYNC(task)) { | 296 | if (RPC_IS_ASYNC(task)) { |
302 | int status; | 297 | int status; |
303 | 298 | ||
@@ -607,7 +602,9 @@ void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata) | |||
607 | */ | 602 | */ |
608 | static void __rpc_execute(struct rpc_task *task) | 603 | static void __rpc_execute(struct rpc_task *task) |
609 | { | 604 | { |
610 | int status = 0; | 605 | struct rpc_wait_queue *queue; |
606 | int task_is_async = RPC_IS_ASYNC(task); | ||
607 | int status = 0; | ||
611 | 608 | ||
612 | dprintk("RPC: %5u __rpc_execute flags=0x%x\n", | 609 | dprintk("RPC: %5u __rpc_execute flags=0x%x\n", |
613 | task->tk_pid, task->tk_flags); | 610 | task->tk_pid, task->tk_flags); |
@@ -647,15 +644,25 @@ static void __rpc_execute(struct rpc_task *task) | |||
647 | */ | 644 | */ |
648 | if (!RPC_IS_QUEUED(task)) | 645 | if (!RPC_IS_QUEUED(task)) |
649 | continue; | 646 | continue; |
650 | rpc_clear_running(task); | 647 | /* |
651 | if (RPC_IS_ASYNC(task)) { | 648 | * The queue->lock protects against races with |
652 | /* Careful! we may have raced... */ | 649 | * rpc_make_runnable(). |
653 | if (RPC_IS_QUEUED(task)) | 650 | * |
654 | return; | 651 | * Note that once we clear RPC_TASK_RUNNING on an asynchronous |
655 | if (rpc_test_and_set_running(task)) | 652 | * rpc_task, rpc_make_runnable() can assign it to a |
656 | return; | 653 | * different workqueue. We therefore cannot assume that the |
654 | * rpc_task pointer may still be dereferenced. | ||
655 | */ | ||
656 | queue = task->tk_waitqueue; | ||
657 | spin_lock_bh(&queue->lock); | ||
658 | if (!RPC_IS_QUEUED(task)) { | ||
659 | spin_unlock_bh(&queue->lock); | ||
657 | continue; | 660 | continue; |
658 | } | 661 | } |
662 | rpc_clear_running(task); | ||
663 | spin_unlock_bh(&queue->lock); | ||
664 | if (task_is_async) | ||
665 | return; | ||
659 | 666 | ||
660 | /* sync task: sleep here */ | 667 | /* sync task: sleep here */ |
661 | dprintk("RPC: %5u sync task going to sleep\n", task->tk_pid); | 668 | dprintk("RPC: %5u sync task going to sleep\n", task->tk_pid); |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 29e401bb612e..62098d101a1f 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -663,7 +663,7 @@ void xprt_connect(struct rpc_task *task) | |||
663 | xprt, (xprt_connected(xprt) ? "is" : "is not")); | 663 | xprt, (xprt_connected(xprt) ? "is" : "is not")); |
664 | 664 | ||
665 | if (!xprt_bound(xprt)) { | 665 | if (!xprt_bound(xprt)) { |
666 | task->tk_status = -EIO; | 666 | task->tk_status = -EAGAIN; |
667 | return; | 667 | return; |
668 | } | 668 | } |
669 | if (!xprt_lock_write(xprt, task)) | 669 | if (!xprt_lock_write(xprt, task)) |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 5cbb404c4cdf..568330eebbfe 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -467,7 +467,7 @@ static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, | |||
467 | int err, sent = 0; | 467 | int err, sent = 0; |
468 | 468 | ||
469 | if (unlikely(!sock)) | 469 | if (unlikely(!sock)) |
470 | return -ENOTCONN; | 470 | return -ENOTSOCK; |
471 | 471 | ||
472 | clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags); | 472 | clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags); |
473 | if (base != 0) { | 473 | if (base != 0) { |
@@ -577,6 +577,8 @@ static int xs_udp_send_request(struct rpc_task *task) | |||
577 | req->rq_svec->iov_base, | 577 | req->rq_svec->iov_base, |
578 | req->rq_svec->iov_len); | 578 | req->rq_svec->iov_len); |
579 | 579 | ||
580 | if (!xprt_bound(xprt)) | ||
581 | return -ENOTCONN; | ||
580 | status = xs_sendpages(transport->sock, | 582 | status = xs_sendpages(transport->sock, |
581 | xs_addr(xprt), | 583 | xs_addr(xprt), |
582 | xprt->addrlen, xdr, | 584 | xprt->addrlen, xdr, |
@@ -594,6 +596,10 @@ static int xs_udp_send_request(struct rpc_task *task) | |||
594 | } | 596 | } |
595 | 597 | ||
596 | switch (status) { | 598 | switch (status) { |
599 | case -ENOTSOCK: | ||
600 | status = -ENOTCONN; | ||
601 | /* Should we call xs_close() here? */ | ||
602 | break; | ||
597 | case -EAGAIN: | 603 | case -EAGAIN: |
598 | xs_nospace(task); | 604 | xs_nospace(task); |
599 | break; | 605 | break; |
@@ -693,6 +699,10 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
693 | } | 699 | } |
694 | 700 | ||
695 | switch (status) { | 701 | switch (status) { |
702 | case -ENOTSOCK: | ||
703 | status = -ENOTCONN; | ||
704 | /* Should we call xs_close() here? */ | ||
705 | break; | ||
696 | case -EAGAIN: | 706 | case -EAGAIN: |
697 | xs_nospace(task); | 707 | xs_nospace(task); |
698 | break; | 708 | break; |
@@ -1215,6 +1225,23 @@ out: | |||
1215 | read_unlock(&sk->sk_callback_lock); | 1225 | read_unlock(&sk->sk_callback_lock); |
1216 | } | 1226 | } |
1217 | 1227 | ||
1228 | static void xs_write_space(struct sock *sk) | ||
1229 | { | ||
1230 | struct socket *sock; | ||
1231 | struct rpc_xprt *xprt; | ||
1232 | |||
1233 | if (unlikely(!(sock = sk->sk_socket))) | ||
1234 | return; | ||
1235 | clear_bit(SOCK_NOSPACE, &sock->flags); | ||
1236 | |||
1237 | if (unlikely(!(xprt = xprt_from_sock(sk)))) | ||
1238 | return; | ||
1239 | if (test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags) == 0) | ||
1240 | return; | ||
1241 | |||
1242 | xprt_write_space(xprt); | ||
1243 | } | ||
1244 | |||
1218 | /** | 1245 | /** |
1219 | * xs_udp_write_space - callback invoked when socket buffer space | 1246 | * xs_udp_write_space - callback invoked when socket buffer space |
1220 | * becomes available | 1247 | * becomes available |
@@ -1230,23 +1257,9 @@ static void xs_udp_write_space(struct sock *sk) | |||
1230 | read_lock(&sk->sk_callback_lock); | 1257 | read_lock(&sk->sk_callback_lock); |
1231 | 1258 | ||
1232 | /* from net/core/sock.c:sock_def_write_space */ | 1259 | /* from net/core/sock.c:sock_def_write_space */ |
1233 | if (sock_writeable(sk)) { | 1260 | if (sock_writeable(sk)) |
1234 | struct socket *sock; | 1261 | xs_write_space(sk); |
1235 | struct rpc_xprt *xprt; | ||
1236 | |||
1237 | if (unlikely(!(sock = sk->sk_socket))) | ||
1238 | goto out; | ||
1239 | clear_bit(SOCK_NOSPACE, &sock->flags); | ||
1240 | |||
1241 | if (unlikely(!(xprt = xprt_from_sock(sk)))) | ||
1242 | goto out; | ||
1243 | if (test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags) == 0) | ||
1244 | goto out; | ||
1245 | 1262 | ||
1246 | xprt_write_space(xprt); | ||
1247 | } | ||
1248 | |||
1249 | out: | ||
1250 | read_unlock(&sk->sk_callback_lock); | 1263 | read_unlock(&sk->sk_callback_lock); |
1251 | } | 1264 | } |
1252 | 1265 | ||
@@ -1265,23 +1278,9 @@ static void xs_tcp_write_space(struct sock *sk) | |||
1265 | read_lock(&sk->sk_callback_lock); | 1278 | read_lock(&sk->sk_callback_lock); |
1266 | 1279 | ||
1267 | /* from net/core/stream.c:sk_stream_write_space */ | 1280 | /* from net/core/stream.c:sk_stream_write_space */ |
1268 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) { | 1281 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) |
1269 | struct socket *sock; | 1282 | xs_write_space(sk); |
1270 | struct rpc_xprt *xprt; | ||
1271 | |||
1272 | if (unlikely(!(sock = sk->sk_socket))) | ||
1273 | goto out; | ||
1274 | clear_bit(SOCK_NOSPACE, &sock->flags); | ||
1275 | |||
1276 | if (unlikely(!(xprt = xprt_from_sock(sk)))) | ||
1277 | goto out; | ||
1278 | if (test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags) == 0) | ||
1279 | goto out; | ||
1280 | 1283 | ||
1281 | xprt_write_space(xprt); | ||
1282 | } | ||
1283 | |||
1284 | out: | ||
1285 | read_unlock(&sk->sk_callback_lock); | 1284 | read_unlock(&sk->sk_callback_lock); |
1286 | } | 1285 | } |
1287 | 1286 | ||
@@ -1523,7 +1522,7 @@ static void xs_udp_connect_worker4(struct work_struct *work) | |||
1523 | struct socket *sock = transport->sock; | 1522 | struct socket *sock = transport->sock; |
1524 | int err, status = -EIO; | 1523 | int err, status = -EIO; |
1525 | 1524 | ||
1526 | if (xprt->shutdown || !xprt_bound(xprt)) | 1525 | if (xprt->shutdown) |
1527 | goto out; | 1526 | goto out; |
1528 | 1527 | ||
1529 | /* Start by resetting any existing state */ | 1528 | /* Start by resetting any existing state */ |
@@ -1564,7 +1563,7 @@ static void xs_udp_connect_worker6(struct work_struct *work) | |||
1564 | struct socket *sock = transport->sock; | 1563 | struct socket *sock = transport->sock; |
1565 | int err, status = -EIO; | 1564 | int err, status = -EIO; |
1566 | 1565 | ||
1567 | if (xprt->shutdown || !xprt_bound(xprt)) | 1566 | if (xprt->shutdown) |
1568 | goto out; | 1567 | goto out; |
1569 | 1568 | ||
1570 | /* Start by resetting any existing state */ | 1569 | /* Start by resetting any existing state */ |
@@ -1648,6 +1647,9 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | |||
1648 | write_unlock_bh(&sk->sk_callback_lock); | 1647 | write_unlock_bh(&sk->sk_callback_lock); |
1649 | } | 1648 | } |
1650 | 1649 | ||
1650 | if (!xprt_bound(xprt)) | ||
1651 | return -ENOTCONN; | ||
1652 | |||
1651 | /* Tell the socket layer to start connecting... */ | 1653 | /* Tell the socket layer to start connecting... */ |
1652 | xprt->stat.connect_count++; | 1654 | xprt->stat.connect_count++; |
1653 | xprt->stat.connect_start = jiffies; | 1655 | xprt->stat.connect_start = jiffies; |
@@ -1668,7 +1670,7 @@ static void xs_tcp_connect_worker4(struct work_struct *work) | |||
1668 | struct socket *sock = transport->sock; | 1670 | struct socket *sock = transport->sock; |
1669 | int err, status = -EIO; | 1671 | int err, status = -EIO; |
1670 | 1672 | ||
1671 | if (xprt->shutdown || !xprt_bound(xprt)) | 1673 | if (xprt->shutdown) |
1672 | goto out; | 1674 | goto out; |
1673 | 1675 | ||
1674 | if (!sock) { | 1676 | if (!sock) { |
@@ -1728,7 +1730,7 @@ static void xs_tcp_connect_worker6(struct work_struct *work) | |||
1728 | struct socket *sock = transport->sock; | 1730 | struct socket *sock = transport->sock; |
1729 | int err, status = -EIO; | 1731 | int err, status = -EIO; |
1730 | 1732 | ||
1731 | if (xprt->shutdown || !xprt_bound(xprt)) | 1733 | if (xprt->shutdown) |
1732 | goto out; | 1734 | goto out; |
1733 | 1735 | ||
1734 | if (!sock) { | 1736 | if (!sock) { |