diff options
| -rw-r--r-- | include/linux/sunrpc/xprt.h | 61 | ||||
| -rw-r--r-- | net/sunrpc/clnt.c | 2 | ||||
| -rw-r--r-- | net/sunrpc/xprt.c | 26 | ||||
| -rw-r--r-- | net/sunrpc/xprtsock.c | 12 |
4 files changed, 55 insertions, 46 deletions
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index d5223993fca9..bfbc492ae36d 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/include/linux/sunrpc/clnt_xprt.h | 2 | * linux/include/linux/sunrpc/xprt.h |
| 3 | * | 3 | * |
| 4 | * Declarations for the RPC transport interface. | 4 | * Declarations for the RPC transport interface. |
| 5 | * | 5 | * |
| @@ -150,8 +150,8 @@ struct rpc_xprt { | |||
| 150 | unsigned long cong; /* current congestion */ | 150 | unsigned long cong; /* current congestion */ |
| 151 | unsigned long cwnd; /* congestion window */ | 151 | unsigned long cwnd; /* congestion window */ |
| 152 | 152 | ||
| 153 | unsigned int rcvsize, /* socket receive buffer size */ | 153 | unsigned int rcvsize, /* transport rcv buffer size */ |
| 154 | sndsize; /* socket send buffer size */ | 154 | sndsize; /* transport send buffer size */ |
| 155 | 155 | ||
| 156 | size_t max_payload; /* largest RPC payload size, | 156 | size_t max_payload; /* largest RPC payload size, |
| 157 | in bytes */ | 157 | in bytes */ |
| @@ -184,12 +184,12 @@ struct rpc_xprt { | |||
| 184 | unsigned long tcp_copied, /* copied to request */ | 184 | unsigned long tcp_copied, /* copied to request */ |
| 185 | tcp_flags; | 185 | tcp_flags; |
| 186 | /* | 186 | /* |
| 187 | * Connection of sockets | 187 | * Connection of transports |
| 188 | */ | 188 | */ |
| 189 | struct work_struct sock_connect; | 189 | struct work_struct connect_worker; |
| 190 | unsigned short port; | 190 | unsigned short port; |
| 191 | /* | 191 | /* |
| 192 | * Disconnection of idle sockets | 192 | * Disconnection of idle transports |
| 193 | */ | 193 | */ |
| 194 | struct work_struct task_cleanup; | 194 | struct work_struct task_cleanup; |
| 195 | struct timer_list timer; | 195 | struct timer_list timer; |
| @@ -219,27 +219,36 @@ struct rpc_xprt { | |||
| 219 | 219 | ||
| 220 | #ifdef __KERNEL__ | 220 | #ifdef __KERNEL__ |
| 221 | 221 | ||
| 222 | struct rpc_xprt * xprt_create_proto(int proto, struct sockaddr_in *addr, | 222 | /* |
| 223 | struct rpc_timeout *toparms); | 223 | * Transport operations used by ULPs |
| 224 | void xprt_disconnect(struct rpc_xprt *); | 224 | */ |
| 225 | int xprt_destroy(struct rpc_xprt *); | 225 | struct rpc_xprt * xprt_create_proto(int proto, struct sockaddr_in *addr, struct rpc_timeout *to); |
| 226 | void xprt_set_timeout(struct rpc_timeout *, unsigned int, | 226 | void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long incr); |
| 227 | unsigned long); | 227 | |
| 228 | struct rpc_rqst * xprt_lookup_rqst(struct rpc_xprt *, u32); | 228 | /* |
| 229 | void xprt_complete_rqst(struct rpc_xprt *, | 229 | * Generic internal transport functions |
| 230 | struct rpc_rqst *, int); | 230 | */ |
| 231 | void xprt_reserve(struct rpc_task *); | 231 | void xprt_connect(struct rpc_task *task); |
| 232 | int xprt_prepare_transmit(struct rpc_task *); | 232 | void xprt_reserve(struct rpc_task *task); |
| 233 | void xprt_transmit(struct rpc_task *); | 233 | int xprt_prepare_transmit(struct rpc_task *task); |
| 234 | void xprt_receive(struct rpc_task *); | 234 | void xprt_transmit(struct rpc_task *task); |
| 235 | void xprt_wake_pending_tasks(struct rpc_xprt *, int); | ||
| 236 | int xprt_adjust_timeout(struct rpc_rqst *req); | 235 | int xprt_adjust_timeout(struct rpc_rqst *req); |
| 237 | void xprt_release(struct rpc_task *); | 236 | void xprt_release(struct rpc_task *task); |
| 238 | void xprt_connect(struct rpc_task *); | 237 | int xprt_destroy(struct rpc_xprt *xprt); |
| 239 | int xs_setup_udp(struct rpc_xprt *, | 238 | |
| 240 | struct rpc_timeout *); | 239 | /* |
| 241 | int xs_setup_tcp(struct rpc_xprt *, | 240 | * Transport switch helper functions |
| 242 | struct rpc_timeout *); | 241 | */ |
| 242 | void xprt_wake_pending_tasks(struct rpc_xprt *xprt, int status); | ||
| 243 | struct rpc_rqst * xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid); | ||
| 244 | void xprt_complete_rqst(struct rpc_xprt *xprt, struct rpc_rqst *req, int copied); | ||
| 245 | void xprt_disconnect(struct rpc_xprt *xprt); | ||
| 246 | |||
| 247 | /* | ||
| 248 | * Socket transport setup operations | ||
| 249 | */ | ||
| 250 | int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to); | ||
| 251 | int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to); | ||
| 243 | 252 | ||
| 244 | /* | 253 | /* |
| 245 | * Reserved bit positions in xprt->state | 254 | * Reserved bit positions in xprt->state |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 0d1b010a4a01..4677959d2834 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/net/sunrpc/rpcclnt.c | 2 | * linux/net/sunrpc/clnt.c |
| 3 | * | 3 | * |
| 4 | * This file contains the high-level RPC interface. | 4 | * This file contains the high-level RPC interface. |
| 5 | * It is modeled as a finite state machine to support both synchronous | 5 | * It is modeled as a finite state machine to support both synchronous |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 2f9cd468b953..247fa1ec870c 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
| @@ -10,12 +10,12 @@ | |||
| 10 | * one is available. Otherwise, it sleeps on the backlog queue | 10 | * one is available. Otherwise, it sleeps on the backlog queue |
| 11 | * (xprt_reserve). | 11 | * (xprt_reserve). |
| 12 | * - Next, the caller puts together the RPC message, stuffs it into | 12 | * - Next, the caller puts together the RPC message, stuffs it into |
| 13 | * the request struct, and calls xprt_call(). | 13 | * the request struct, and calls xprt_transmit(). |
| 14 | * - xprt_call transmits the message and installs the caller on the | 14 | * - xprt_transmit sends the message and installs the caller on the |
| 15 | * socket's wait list. At the same time, it installs a timer that | 15 | * transport's wait list. At the same time, it installs a timer that |
| 16 | * is run after the packet's timeout has expired. | 16 | * is run after the packet's timeout has expired. |
| 17 | * - When a packet arrives, the data_ready handler walks the list of | 17 | * - When a packet arrives, the data_ready handler walks the list of |
| 18 | * pending requests for that socket. If a matching XID is found, the | 18 | * pending requests for that transport. If a matching XID is found, the |
| 19 | * caller is woken up, and the timer removed. | 19 | * caller is woken up, and the timer removed. |
| 20 | * - When no reply arrives within the timeout interval, the timer is | 20 | * - When no reply arrives within the timeout interval, the timer is |
| 21 | * fired by the kernel and runs xprt_timer(). It either adjusts the | 21 | * fired by the kernel and runs xprt_timer(). It either adjusts the |
| @@ -32,6 +32,8 @@ | |||
| 32 | * tasks that rely on callbacks. | 32 | * tasks that rely on callbacks. |
| 33 | * | 33 | * |
| 34 | * Copyright (C) 1995-1997, Olaf Kirch <okir@monad.swb.de> | 34 | * Copyright (C) 1995-1997, Olaf Kirch <okir@monad.swb.de> |
| 35 | * | ||
| 36 | * Transport switch API copyright (C) 2005, Chuck Lever <cel@netapp.com> | ||
| 35 | */ | 37 | */ |
| 36 | 38 | ||
| 37 | #include <linux/module.h> | 39 | #include <linux/module.h> |
| @@ -52,8 +54,6 @@ | |||
| 52 | # define RPCDBG_FACILITY RPCDBG_XPRT | 54 | # define RPCDBG_FACILITY RPCDBG_XPRT |
| 53 | #endif | 55 | #endif |
| 54 | 56 | ||
| 55 | #define XPRT_MAX_BACKOFF (8) | ||
| 56 | |||
| 57 | /* | 57 | /* |
| 58 | * Local functions | 58 | * Local functions |
| 59 | */ | 59 | */ |
| @@ -65,9 +65,9 @@ static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *); | |||
| 65 | static int xprt_clear_backlog(struct rpc_xprt *xprt); | 65 | static int xprt_clear_backlog(struct rpc_xprt *xprt); |
| 66 | 66 | ||
| 67 | /* | 67 | /* |
| 68 | * Serialize write access to sockets, in order to prevent different | 68 | * Serialize write access to transports, in order to prevent different |
| 69 | * requests from interfering with each other. | 69 | * requests from interfering with each other. |
| 70 | * Also prevents TCP socket connects from colliding with writes. | 70 | * Also prevents transport connects from colliding with writes. |
| 71 | */ | 71 | */ |
| 72 | static int | 72 | static int |
| 73 | __xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task) | 73 | __xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task) |
| @@ -91,7 +91,7 @@ __xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task) | |||
| 91 | clear_bit(XPRT_LOCKED, &xprt->state); | 91 | clear_bit(XPRT_LOCKED, &xprt->state); |
| 92 | smp_mb__after_clear_bit(); | 92 | smp_mb__after_clear_bit(); |
| 93 | out_sleep: | 93 | out_sleep: |
| 94 | dprintk("RPC: %4d failed to lock socket %p\n", task->tk_pid, xprt); | 94 | dprintk("RPC: %4d failed to lock transport %p\n", task->tk_pid, xprt); |
| 95 | task->tk_timeout = 0; | 95 | task->tk_timeout = 0; |
| 96 | task->tk_status = -EAGAIN; | 96 | task->tk_status = -EAGAIN; |
| 97 | if (req && req->rq_ntrans) | 97 | if (req && req->rq_ntrans) |
| @@ -144,7 +144,7 @@ out_unlock: | |||
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | /* | 146 | /* |
| 147 | * Releases the socket for use by other requests. | 147 | * Releases the transport for use by other requests. |
| 148 | */ | 148 | */ |
| 149 | static void | 149 | static void |
| 150 | __xprt_release_write(struct rpc_xprt *xprt, struct rpc_task *task) | 150 | __xprt_release_write(struct rpc_xprt *xprt, struct rpc_task *task) |
| @@ -294,8 +294,7 @@ int xprt_adjust_timeout(struct rpc_rqst *req) | |||
| 294 | return status; | 294 | return status; |
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | static void | 297 | static void xprt_autoclose(void *args) |
| 298 | xprt_socket_autoclose(void *args) | ||
| 299 | { | 298 | { |
| 300 | struct rpc_xprt *xprt = (struct rpc_xprt *)args; | 299 | struct rpc_xprt *xprt = (struct rpc_xprt *)args; |
| 301 | 300 | ||
| @@ -329,7 +328,6 @@ xprt_init_autodisconnect(unsigned long data) | |||
| 329 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) | 328 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) |
| 330 | goto out_abort; | 329 | goto out_abort; |
| 331 | spin_unlock(&xprt->transport_lock); | 330 | spin_unlock(&xprt->transport_lock); |
| 332 | /* Let keventd close the socket */ | ||
| 333 | if (xprt_connecting(xprt)) | 331 | if (xprt_connecting(xprt)) |
| 334 | xprt_release_write(xprt, NULL); | 332 | xprt_release_write(xprt, NULL); |
| 335 | else | 333 | else |
| @@ -770,7 +768,7 @@ static struct rpc_xprt *xprt_setup(int proto, struct sockaddr_in *ap, struct rpc | |||
| 770 | 768 | ||
| 771 | INIT_LIST_HEAD(&xprt->free); | 769 | INIT_LIST_HEAD(&xprt->free); |
| 772 | INIT_LIST_HEAD(&xprt->recv); | 770 | INIT_LIST_HEAD(&xprt->recv); |
| 773 | INIT_WORK(&xprt->task_cleanup, xprt_socket_autoclose, xprt); | 771 | INIT_WORK(&xprt->task_cleanup, xprt_autoclose, xprt); |
| 774 | init_timer(&xprt->timer); | 772 | init_timer(&xprt->timer); |
| 775 | xprt->timer.function = xprt_init_autodisconnect; | 773 | xprt->timer.function = xprt_init_autodisconnect; |
| 776 | xprt->timer.data = (unsigned long) xprt; | 774 | xprt->timer.data = (unsigned long) xprt; |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 182da2edf61c..7f0b9f7f167b 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -11,6 +11,8 @@ | |||
| 11 | * Rewrite of larges part of the code in order to stabilize TCP stuff. | 11 | * Rewrite of larges part of the code in order to stabilize TCP stuff. |
| 12 | * Fix behaviour when socket buffer is full. | 12 | * Fix behaviour when socket buffer is full. |
| 13 | * (C) 1999 Trond Myklebust <trond.myklebust@fys.uio.no> | 13 | * (C) 1999 Trond Myklebust <trond.myklebust@fys.uio.no> |
| 14 | * | ||
| 15 | * IP socket transport implementation, (C) 2005 Chuck Lever <cel@netapp.com> | ||
| 14 | */ | 16 | */ |
| 15 | 17 | ||
| 16 | #include <linux/types.h> | 18 | #include <linux/types.h> |
| @@ -363,7 +365,7 @@ static void xs_destroy(struct rpc_xprt *xprt) | |||
| 363 | { | 365 | { |
| 364 | dprintk("RPC: xs_destroy xprt %p\n", xprt); | 366 | dprintk("RPC: xs_destroy xprt %p\n", xprt); |
| 365 | 367 | ||
| 366 | cancel_delayed_work(&xprt->sock_connect); | 368 | cancel_delayed_work(&xprt->connect_worker); |
| 367 | flush_scheduled_work(); | 369 | flush_scheduled_work(); |
| 368 | 370 | ||
| 369 | xprt_disconnect(xprt); | 371 | xprt_disconnect(xprt); |
| @@ -938,11 +940,11 @@ static void xs_connect(struct rpc_task *task) | |||
| 938 | if (!xprt_test_and_set_connecting(xprt)) { | 940 | if (!xprt_test_and_set_connecting(xprt)) { |
| 939 | if (xprt->sock != NULL) { | 941 | if (xprt->sock != NULL) { |
| 940 | dprintk("RPC: xs_connect delayed xprt %p\n", xprt); | 942 | dprintk("RPC: xs_connect delayed xprt %p\n", xprt); |
| 941 | schedule_delayed_work(&xprt->sock_connect, | 943 | schedule_delayed_work(&xprt->connect_worker, |
| 942 | RPC_REESTABLISH_TIMEOUT); | 944 | RPC_REESTABLISH_TIMEOUT); |
| 943 | } else { | 945 | } else { |
| 944 | dprintk("RPC: xs_connect scheduled xprt %p\n", xprt); | 946 | dprintk("RPC: xs_connect scheduled xprt %p\n", xprt); |
| 945 | schedule_work(&xprt->sock_connect); | 947 | schedule_work(&xprt->connect_worker); |
| 946 | /* flush_scheduled_work can sleep... */ | 948 | /* flush_scheduled_work can sleep... */ |
| 947 | if (!RPC_IS_ASYNC(task)) | 949 | if (!RPC_IS_ASYNC(task)) |
| 948 | flush_scheduled_work(); | 950 | flush_scheduled_work(); |
| @@ -989,7 +991,7 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
| 989 | /* XXX: header size can vary due to auth type, IPv6, etc. */ | 991 | /* XXX: header size can vary due to auth type, IPv6, etc. */ |
| 990 | xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); | 992 | xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); |
| 991 | 993 | ||
| 992 | INIT_WORK(&xprt->sock_connect, xs_connect_worker, xprt); | 994 | INIT_WORK(&xprt->connect_worker, xs_connect_worker, xprt); |
| 993 | 995 | ||
| 994 | xprt->ops = &xs_ops; | 996 | xprt->ops = &xs_ops; |
| 995 | 997 | ||
| @@ -1028,7 +1030,7 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
| 1028 | xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; | 1030 | xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; |
| 1029 | xprt->max_payload = (1U << 31) - 1; | 1031 | xprt->max_payload = (1U << 31) - 1; |
| 1030 | 1032 | ||
| 1031 | INIT_WORK(&xprt->sock_connect, xs_connect_worker, xprt); | 1033 | INIT_WORK(&xprt->connect_worker, xs_connect_worker, xprt); |
| 1032 | 1034 | ||
| 1033 | xprt->ops = &xs_ops; | 1035 | xprt->ops = &xs_ops; |
| 1034 | 1036 | ||
