aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/auth.c18
-rw-r--r--net/sunrpc/xprtsock.c58
2 files changed, 58 insertions, 18 deletions
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 436bf1b4b76c..cb216b2df666 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -228,19 +228,21 @@ static int
228rpcauth_prune_expired(struct list_head *free, int nr_to_scan) 228rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
229{ 229{
230 spinlock_t *cache_lock; 230 spinlock_t *cache_lock;
231 struct rpc_cred *cred; 231 struct rpc_cred *cred, *next;
232 unsigned long expired = jiffies - RPC_AUTH_EXPIRY_MORATORIUM; 232 unsigned long expired = jiffies - RPC_AUTH_EXPIRY_MORATORIUM;
233 233
234 while (!list_empty(&cred_unused)) { 234 list_for_each_entry_safe(cred, next, &cred_unused, cr_lru) {
235 cred = list_entry(cred_unused.next, struct rpc_cred, cr_lru); 235
236 /* Enforce a 60 second garbage collection moratorium */
237 if (time_in_range(cred->cr_expire, expired, jiffies) &&
238 test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0)
239 continue;
240
236 list_del_init(&cred->cr_lru); 241 list_del_init(&cred->cr_lru);
237 number_cred_unused--; 242 number_cred_unused--;
238 if (atomic_read(&cred->cr_count) != 0) 243 if (atomic_read(&cred->cr_count) != 0)
239 continue; 244 continue;
240 /* Enforce a 5 second garbage collection moratorium */ 245
241 if (time_in_range(cred->cr_expire, expired, jiffies) &&
242 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0)
243 continue;
244 cache_lock = &cred->cr_auth->au_credcache->lock; 246 cache_lock = &cred->cr_auth->au_credcache->lock;
245 spin_lock(cache_lock); 247 spin_lock(cache_lock);
246 if (atomic_read(&cred->cr_count) == 0) { 248 if (atomic_read(&cred->cr_count) == 0) {
@@ -453,7 +455,7 @@ need_lock:
453 } 455 }
454 if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0) 456 if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0)
455 rpcauth_unhash_cred(cred); 457 rpcauth_unhash_cred(cred);
456 else if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) { 458 if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) {
457 cred->cr_expire = jiffies; 459 cred->cr_expire = jiffies;
458 list_add_tail(&cred->cr_lru, &cred_unused); 460 list_add_tail(&cred->cr_lru, &cred_unused);
459 number_cred_unused++; 461 number_cred_unused++;
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index f9ce3c9949d5..82a9b6286dd3 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -249,6 +249,7 @@ struct sock_xprt {
249 void (*old_data_ready)(struct sock *, int); 249 void (*old_data_ready)(struct sock *, int);
250 void (*old_state_change)(struct sock *); 250 void (*old_state_change)(struct sock *);
251 void (*old_write_space)(struct sock *); 251 void (*old_write_space)(struct sock *);
252 void (*old_error_report)(struct sock *);
252}; 253};
253 254
254/* 255/*
@@ -696,8 +697,9 @@ static int xs_tcp_send_request(struct rpc_task *task)
696 case -EAGAIN: 697 case -EAGAIN:
697 xs_nospace(task); 698 xs_nospace(task);
698 break; 699 break;
699 case -ECONNREFUSED:
700 case -ECONNRESET: 700 case -ECONNRESET:
701 xs_tcp_shutdown(xprt);
702 case -ECONNREFUSED:
701 case -ENOTCONN: 703 case -ENOTCONN:
702 case -EPIPE: 704 case -EPIPE:
703 status = -ENOTCONN; 705 status = -ENOTCONN;
@@ -740,6 +742,22 @@ out_release:
740 xprt_release_xprt(xprt, task); 742 xprt_release_xprt(xprt, task);
741} 743}
742 744
745static void xs_save_old_callbacks(struct sock_xprt *transport, struct sock *sk)
746{
747 transport->old_data_ready = sk->sk_data_ready;
748 transport->old_state_change = sk->sk_state_change;
749 transport->old_write_space = sk->sk_write_space;
750 transport->old_error_report = sk->sk_error_report;
751}
752
753static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *sk)
754{
755 sk->sk_data_ready = transport->old_data_ready;
756 sk->sk_state_change = transport->old_state_change;
757 sk->sk_write_space = transport->old_write_space;
758 sk->sk_error_report = transport->old_error_report;
759}
760
743/** 761/**
744 * xs_close - close a socket 762 * xs_close - close a socket
745 * @xprt: transport 763 * @xprt: transport
@@ -763,9 +781,8 @@ static void xs_close(struct rpc_xprt *xprt)
763 transport->sock = NULL; 781 transport->sock = NULL;
764 782
765 sk->sk_user_data = NULL; 783 sk->sk_user_data = NULL;
766 sk->sk_data_ready = transport->old_data_ready; 784
767 sk->sk_state_change = transport->old_state_change; 785 xs_restore_old_callbacks(transport, sk);
768 sk->sk_write_space = transport->old_write_space;
769 write_unlock_bh(&sk->sk_callback_lock); 786 write_unlock_bh(&sk->sk_callback_lock);
770 787
771 sk->sk_no_check = 0; 788 sk->sk_no_check = 0;
@@ -1178,6 +1195,28 @@ static void xs_tcp_state_change(struct sock *sk)
1178} 1195}
1179 1196
1180/** 1197/**
1198 * xs_tcp_error_report - callback mainly for catching RST events
1199 * @sk: socket
1200 */
1201static void xs_tcp_error_report(struct sock *sk)
1202{
1203 struct rpc_xprt *xprt;
1204
1205 read_lock(&sk->sk_callback_lock);
1206 if (sk->sk_err != ECONNRESET || sk->sk_state != TCP_ESTABLISHED)
1207 goto out;
1208 if (!(xprt = xprt_from_sock(sk)))
1209 goto out;
1210 dprintk("RPC: %s client %p...\n"
1211 "RPC: error %d\n",
1212 __func__, xprt, sk->sk_err);
1213
1214 xprt_force_disconnect(xprt);
1215out:
1216 read_unlock(&sk->sk_callback_lock);
1217}
1218
1219/**
1181 * xs_udp_write_space - callback invoked when socket buffer space 1220 * xs_udp_write_space - callback invoked when socket buffer space
1182 * becomes available 1221 * becomes available
1183 * @sk: socket whose state has changed 1222 * @sk: socket whose state has changed
@@ -1452,10 +1491,9 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
1452 1491
1453 write_lock_bh(&sk->sk_callback_lock); 1492 write_lock_bh(&sk->sk_callback_lock);
1454 1493
1494 xs_save_old_callbacks(transport, sk);
1495
1455 sk->sk_user_data = xprt; 1496 sk->sk_user_data = xprt;
1456 transport->old_data_ready = sk->sk_data_ready;
1457 transport->old_state_change = sk->sk_state_change;
1458 transport->old_write_space = sk->sk_write_space;
1459 sk->sk_data_ready = xs_udp_data_ready; 1497 sk->sk_data_ready = xs_udp_data_ready;
1460 sk->sk_write_space = xs_udp_write_space; 1498 sk->sk_write_space = xs_udp_write_space;
1461 sk->sk_no_check = UDP_CSUM_NORCV; 1499 sk->sk_no_check = UDP_CSUM_NORCV;
@@ -1587,13 +1625,13 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
1587 1625
1588 write_lock_bh(&sk->sk_callback_lock); 1626 write_lock_bh(&sk->sk_callback_lock);
1589 1627
1628 xs_save_old_callbacks(transport, sk);
1629
1590 sk->sk_user_data = xprt; 1630 sk->sk_user_data = xprt;
1591 transport->old_data_ready = sk->sk_data_ready;
1592 transport->old_state_change = sk->sk_state_change;
1593 transport->old_write_space = sk->sk_write_space;
1594 sk->sk_data_ready = xs_tcp_data_ready; 1631 sk->sk_data_ready = xs_tcp_data_ready;
1595 sk->sk_state_change = xs_tcp_state_change; 1632 sk->sk_state_change = xs_tcp_state_change;
1596 sk->sk_write_space = xs_tcp_write_space; 1633 sk->sk_write_space = xs_tcp_write_space;
1634 sk->sk_error_report = xs_tcp_error_report;
1597 sk->sk_allocation = GFP_ATOMIC; 1635 sk->sk_allocation = GFP_ATOMIC;
1598 1636
1599 /* socket options */ 1637 /* socket options */