aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Tucker <tom@opengridcomputing.com>2007-12-30 22:07:53 -0500
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-02-01 16:42:11 -0500
commit7a18208383ab3f3ce4a1f4e0536acc9372523d81 (patch)
tree851a1cc29d753297c2e7cf4cb4a95c4af7868427
parentbb5cf160b282644c4491afbf76fbc66f5dc35030 (diff)
svc: Make close transport independent
Move sk_list and sk_ready to svc_xprt. This involves close because these lists are walked by svcs when closing all their transports. So I combined the moving of these lists to svc_xprt with making close transport independent. The svc_force_sock_close has been changed to svc_close_all and takes a list as an argument. This removes some svc internals knowledge from the svcs. This code races with module removal and transport addition. Thanks to Simon Holm Thøgersen for a compile fix. Signed-off-by: Tom Tucker <tom@opengridcomputing.com> Acked-by: Neil Brown <neilb@suse.de> Reviewed-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Greg Banks <gnb@sgi.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Cc: Simon Holm Thøgersen <odie@cs.aau.dk>
-rw-r--r--fs/lockd/svc.c6
-rw-r--r--fs/nfsd/nfssvc.c4
-rw-r--r--include/linux/sunrpc/svc_xprt.h2
-rw-r--r--include/linux/sunrpc/svcsock.h4
-rw-r--r--net/sunrpc/svc.c9
-rw-r--r--net/sunrpc/svc_xprt.c2
-rw-r--r--net/sunrpc/svcsock.c104
7 files changed, 62 insertions, 69 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 868691535115..a8e79a907202 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -221,10 +221,10 @@ lockd(struct svc_rqst *rqstp)
221 221
222static int find_xprt(struct svc_serv *serv, char *proto) 222static int find_xprt(struct svc_serv *serv, char *proto)
223{ 223{
224 struct svc_sock *svsk; 224 struct svc_xprt *xprt;
225 int found = 0; 225 int found = 0;
226 list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) 226 list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list)
227 if (strcmp(svsk->sk_xprt.xpt_class->xcl_name, proto) == 0) { 227 if (strcmp(xprt->xpt_class->xcl_name, proto) == 0) {
228 found = 1; 228 found = 1;
229 break; 229 break;
230 } 230 }
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index a828b0b0fb67..9647b0f7bc0c 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -155,8 +155,8 @@ static int killsig; /* signal that was used to kill last nfsd */
155static void nfsd_last_thread(struct svc_serv *serv) 155static void nfsd_last_thread(struct svc_serv *serv)
156{ 156{
157 /* When last nfsd thread exits we need to do some clean-up */ 157 /* When last nfsd thread exits we need to do some clean-up */
158 struct svc_sock *svsk; 158 struct svc_xprt *xprt;
159 list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) 159 list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list)
160 lockd_down(); 160 lockd_down();
161 nfsd_serv = NULL; 161 nfsd_serv = NULL;
162 nfsd_racache_shutdown(); 162 nfsd_racache_shutdown();
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index 4042cdfec4fe..0a3e09b42a83 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -36,6 +36,8 @@ struct svc_xprt {
36 struct svc_xprt_class *xpt_class; 36 struct svc_xprt_class *xpt_class;
37 struct svc_xprt_ops *xpt_ops; 37 struct svc_xprt_ops *xpt_ops;
38 struct kref xpt_ref; 38 struct kref xpt_ref;
39 struct list_head xpt_list;
40 struct list_head xpt_ready;
39 unsigned long xpt_flags; 41 unsigned long xpt_flags;
40#define XPT_BUSY 0 /* enqueued/receiving */ 42#define XPT_BUSY 0 /* enqueued/receiving */
41#define XPT_CONN 1 /* conn pending */ 43#define XPT_CONN 1 /* conn pending */
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index 92d4cc99c60d..060508ba358b 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -17,8 +17,6 @@
17 */ 17 */
18struct svc_sock { 18struct svc_sock {
19 struct svc_xprt sk_xprt; 19 struct svc_xprt sk_xprt;
20 struct list_head sk_ready; /* list of ready sockets */
21 struct list_head sk_list; /* list of all sockets */
22 struct socket * sk_sock; /* berkeley socket layer */ 20 struct socket * sk_sock; /* berkeley socket layer */
23 struct sock * sk_sk; /* INET layer */ 21 struct sock * sk_sk; /* INET layer */
24 22
@@ -51,7 +49,7 @@ struct svc_sock {
51/* 49/*
52 * Function prototypes. 50 * Function prototypes.
53 */ 51 */
54void svc_force_close_socket(struct svc_sock *); 52void svc_close_all(struct list_head *);
55int svc_recv(struct svc_rqst *, long); 53int svc_recv(struct svc_rqst *, long);
56int svc_send(struct svc_rqst *); 54int svc_send(struct svc_rqst *);
57void svc_drop(struct svc_rqst *); 55void svc_drop(struct svc_rqst *);
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 8281a0402652..a5eb2d6b14ae 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -459,9 +459,6 @@ svc_create_pooled(struct svc_program *prog, unsigned int bufsize,
459void 459void
460svc_destroy(struct svc_serv *serv) 460svc_destroy(struct svc_serv *serv)
461{ 461{
462 struct svc_sock *svsk;
463 struct svc_sock *tmp;
464
465 dprintk("svc: svc_destroy(%s, %d)\n", 462 dprintk("svc: svc_destroy(%s, %d)\n",
466 serv->sv_program->pg_name, 463 serv->sv_program->pg_name,
467 serv->sv_nrthreads); 464 serv->sv_nrthreads);
@@ -476,14 +473,12 @@ svc_destroy(struct svc_serv *serv)
476 473
477 del_timer_sync(&serv->sv_temptimer); 474 del_timer_sync(&serv->sv_temptimer);
478 475
479 list_for_each_entry_safe(svsk, tmp, &serv->sv_tempsocks, sk_list) 476 svc_close_all(&serv->sv_tempsocks);
480 svc_force_close_socket(svsk);
481 477
482 if (serv->sv_shutdown) 478 if (serv->sv_shutdown)
483 serv->sv_shutdown(serv); 479 serv->sv_shutdown(serv);
484 480
485 list_for_each_entry_safe(svsk, tmp, &serv->sv_permsocks, sk_list) 481 svc_close_all(&serv->sv_permsocks);
486 svc_force_close_socket(svsk);
487 482
488 BUG_ON(!list_empty(&serv->sv_permsocks)); 483 BUG_ON(!list_empty(&serv->sv_permsocks));
489 BUG_ON(!list_empty(&serv->sv_tempsocks)); 484 BUG_ON(!list_empty(&serv->sv_tempsocks));
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index ea17b533db74..95186b548099 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -97,6 +97,8 @@ void svc_xprt_init(struct svc_xprt_class *xcl, struct svc_xprt *xprt,
97 xprt->xpt_ops = xcl->xcl_ops; 97 xprt->xpt_ops = xcl->xcl_ops;
98 kref_init(&xprt->xpt_ref); 98 kref_init(&xprt->xpt_ref);
99 xprt->xpt_server = serv; 99 xprt->xpt_server = serv;
100 INIT_LIST_HEAD(&xprt->xpt_list);
101 INIT_LIST_HEAD(&xprt->xpt_ready);
100} 102}
101EXPORT_SYMBOL_GPL(svc_xprt_init); 103EXPORT_SYMBOL_GPL(svc_xprt_init);
102 104
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index f86538e1dec6..6f63a5ca6a91 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -81,11 +81,11 @@
81 81
82static struct svc_sock *svc_setup_socket(struct svc_serv *, struct socket *, 82static struct svc_sock *svc_setup_socket(struct svc_serv *, struct socket *,
83 int *errp, int flags); 83 int *errp, int flags);
84static void svc_delete_socket(struct svc_sock *svsk); 84static void svc_delete_xprt(struct svc_xprt *xprt);
85static void svc_udp_data_ready(struct sock *, int); 85static void svc_udp_data_ready(struct sock *, int);
86static int svc_udp_recvfrom(struct svc_rqst *); 86static int svc_udp_recvfrom(struct svc_rqst *);
87static int svc_udp_sendto(struct svc_rqst *); 87static int svc_udp_sendto(struct svc_rqst *);
88static void svc_close_socket(struct svc_sock *svsk); 88static void svc_close_xprt(struct svc_xprt *xprt);
89static void svc_sock_detach(struct svc_xprt *); 89static void svc_sock_detach(struct svc_xprt *);
90static void svc_sock_free(struct svc_xprt *); 90static void svc_sock_free(struct svc_xprt *);
91 91
@@ -293,7 +293,7 @@ svc_sock_enqueue(struct svc_sock *svsk)
293 wake_up(&rqstp->rq_wait); 293 wake_up(&rqstp->rq_wait);
294 } else { 294 } else {
295 dprintk("svc: socket %p put into queue\n", svsk->sk_sk); 295 dprintk("svc: socket %p put into queue\n", svsk->sk_sk);
296 list_add_tail(&svsk->sk_ready, &pool->sp_sockets); 296 list_add_tail(&svsk->sk_xprt.xpt_ready, &pool->sp_sockets);
297 BUG_ON(svsk->sk_xprt.xpt_pool != pool); 297 BUG_ON(svsk->sk_xprt.xpt_pool != pool);
298 } 298 }
299 299
@@ -313,8 +313,8 @@ svc_sock_dequeue(struct svc_pool *pool)
313 return NULL; 313 return NULL;
314 314
315 svsk = list_entry(pool->sp_sockets.next, 315 svsk = list_entry(pool->sp_sockets.next,
316 struct svc_sock, sk_ready); 316 struct svc_sock, sk_xprt.xpt_ready);
317 list_del_init(&svsk->sk_ready); 317 list_del_init(&svsk->sk_xprt.xpt_ready);
318 318
319 dprintk("svc: socket %p dequeued, inuse=%d\n", 319 dprintk("svc: socket %p dequeued, inuse=%d\n",
320 svsk->sk_sk, atomic_read(&svsk->sk_xprt.xpt_ref.refcount)); 320 svsk->sk_sk, atomic_read(&svsk->sk_xprt.xpt_ref.refcount));
@@ -572,7 +572,7 @@ svc_sock_names(char *buf, struct svc_serv *serv, char *toclose)
572 if (!serv) 572 if (!serv)
573 return 0; 573 return 0;
574 spin_lock_bh(&serv->sv_lock); 574 spin_lock_bh(&serv->sv_lock);
575 list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) { 575 list_for_each_entry(svsk, &serv->sv_permsocks, sk_xprt.xpt_list) {
576 int onelen = one_sock_name(buf+len, svsk); 576 int onelen = one_sock_name(buf+len, svsk);
577 if (toclose && strcmp(toclose, buf+len) == 0) 577 if (toclose && strcmp(toclose, buf+len) == 0)
578 closesk = svsk; 578 closesk = svsk;
@@ -584,7 +584,7 @@ svc_sock_names(char *buf, struct svc_serv *serv, char *toclose)
584 /* Should unregister with portmap, but you cannot 584 /* Should unregister with portmap, but you cannot
585 * unregister just one protocol... 585 * unregister just one protocol...
586 */ 586 */
587 svc_close_socket(closesk); 587 svc_close_xprt(&closesk->sk_xprt);
588 else if (toclose) 588 else if (toclose)
589 return -ENOENT; 589 return -ENOENT;
590 return len; 590 return len;
@@ -1427,12 +1427,12 @@ svc_sock_update_bufs(struct svc_serv *serv)
1427 spin_lock_bh(&serv->sv_lock); 1427 spin_lock_bh(&serv->sv_lock);
1428 list_for_each(le, &serv->sv_permsocks) { 1428 list_for_each(le, &serv->sv_permsocks) {
1429 struct svc_sock *svsk = 1429 struct svc_sock *svsk =
1430 list_entry(le, struct svc_sock, sk_list); 1430 list_entry(le, struct svc_sock, sk_xprt.xpt_list);
1431 set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags); 1431 set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags);
1432 } 1432 }
1433 list_for_each(le, &serv->sv_tempsocks) { 1433 list_for_each(le, &serv->sv_tempsocks) {
1434 struct svc_sock *svsk = 1434 struct svc_sock *svsk =
1435 list_entry(le, struct svc_sock, sk_list); 1435 list_entry(le, struct svc_sock, sk_xprt.xpt_list);
1436 set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags); 1436 set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags);
1437 } 1437 }
1438 spin_unlock_bh(&serv->sv_lock); 1438 spin_unlock_bh(&serv->sv_lock);
@@ -1469,7 +1469,7 @@ static void svc_check_conn_limits(struct svc_serv *serv)
1469 */ 1469 */
1470 svsk = list_entry(serv->sv_tempsocks.prev, 1470 svsk = list_entry(serv->sv_tempsocks.prev,
1471 struct svc_sock, 1471 struct svc_sock,
1472 sk_list); 1472 sk_xprt.xpt_list);
1473 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); 1473 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
1474 svc_xprt_get(&svsk->sk_xprt); 1474 svc_xprt_get(&svsk->sk_xprt);
1475 } 1475 }
@@ -1576,7 +1576,7 @@ svc_recv(struct svc_rqst *rqstp, long timeout)
1576 len = 0; 1576 len = 0;
1577 if (test_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags)) { 1577 if (test_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags)) {
1578 dprintk("svc_recv: found XPT_CLOSE\n"); 1578 dprintk("svc_recv: found XPT_CLOSE\n");
1579 svc_delete_socket(svsk); 1579 svc_delete_xprt(&svsk->sk_xprt);
1580 } else if (test_bit(XPT_LISTENER, &svsk->sk_xprt.xpt_flags)) { 1580 } else if (test_bit(XPT_LISTENER, &svsk->sk_xprt.xpt_flags)) {
1581 struct svc_xprt *newxpt; 1581 struct svc_xprt *newxpt;
1582 newxpt = svsk->sk_xprt.xpt_ops->xpo_accept(&svsk->sk_xprt); 1582 newxpt = svsk->sk_xprt.xpt_ops->xpo_accept(&svsk->sk_xprt);
@@ -1685,7 +1685,7 @@ svc_age_temp_sockets(unsigned long closure)
1685 } 1685 }
1686 1686
1687 list_for_each_safe(le, next, &serv->sv_tempsocks) { 1687 list_for_each_safe(le, next, &serv->sv_tempsocks) {
1688 svsk = list_entry(le, struct svc_sock, sk_list); 1688 svsk = list_entry(le, struct svc_sock, sk_xprt.xpt_list);
1689 1689
1690 if (!test_and_set_bit(XPT_OLD, &svsk->sk_xprt.xpt_flags)) 1690 if (!test_and_set_bit(XPT_OLD, &svsk->sk_xprt.xpt_flags))
1691 continue; 1691 continue;
@@ -1701,9 +1701,9 @@ svc_age_temp_sockets(unsigned long closure)
1701 1701
1702 while (!list_empty(&to_be_aged)) { 1702 while (!list_empty(&to_be_aged)) {
1703 le = to_be_aged.next; 1703 le = to_be_aged.next;
1704 /* fiddling the sk_list node is safe 'cos we're XPT_DETACHED */ 1704 /* fiddling the sk_xprt.xpt_list node is safe 'cos we're XPT_DETACHED */
1705 list_del_init(le); 1705 list_del_init(le);
1706 svsk = list_entry(le, struct svc_sock, sk_list); 1706 svsk = list_entry(le, struct svc_sock, sk_xprt.xpt_list);
1707 1707
1708 dprintk("queuing svsk %p for closing, %lu seconds old\n", 1708 dprintk("queuing svsk %p for closing, %lu seconds old\n",
1709 svsk, get_seconds() - svsk->sk_lastrecv); 1709 svsk, get_seconds() - svsk->sk_lastrecv);
@@ -1757,7 +1757,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
1757 svsk->sk_lastrecv = get_seconds(); 1757 svsk->sk_lastrecv = get_seconds();
1758 spin_lock_init(&svsk->sk_lock); 1758 spin_lock_init(&svsk->sk_lock);
1759 INIT_LIST_HEAD(&svsk->sk_deferred); 1759 INIT_LIST_HEAD(&svsk->sk_deferred);
1760 INIT_LIST_HEAD(&svsk->sk_ready);
1761 mutex_init(&svsk->sk_mutex); 1760 mutex_init(&svsk->sk_mutex);
1762 1761
1763 /* Initialize the socket */ 1762 /* Initialize the socket */
@@ -1769,7 +1768,7 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
1769 spin_lock_bh(&serv->sv_lock); 1768 spin_lock_bh(&serv->sv_lock);
1770 if (is_temporary) { 1769 if (is_temporary) {
1771 set_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags); 1770 set_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags);
1772 list_add(&svsk->sk_list, &serv->sv_tempsocks); 1771 list_add(&svsk->sk_xprt.xpt_list, &serv->sv_tempsocks);
1773 serv->sv_tmpcnt++; 1772 serv->sv_tmpcnt++;
1774 if (serv->sv_temptimer.function == NULL) { 1773 if (serv->sv_temptimer.function == NULL) {
1775 /* setup timer to age temp sockets */ 1774 /* setup timer to age temp sockets */
@@ -1780,7 +1779,7 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
1780 } 1779 }
1781 } else { 1780 } else {
1782 clear_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags); 1781 clear_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags);
1783 list_add(&svsk->sk_list, &serv->sv_permsocks); 1782 list_add(&svsk->sk_xprt.xpt_list, &serv->sv_permsocks);
1784 } 1783 }
1785 spin_unlock_bh(&serv->sv_lock); 1784 spin_unlock_bh(&serv->sv_lock);
1786 1785
@@ -1912,66 +1911,63 @@ static void svc_sock_free(struct svc_xprt *xprt)
1912} 1911}
1913 1912
1914/* 1913/*
1915 * Remove a dead socket 1914 * Remove a dead transport
1916 */ 1915 */
1917static void 1916static void svc_delete_xprt(struct svc_xprt *xprt)
1918svc_delete_socket(struct svc_sock *svsk)
1919{ 1917{
1920 struct svc_serv *serv; 1918 struct svc_serv *serv = xprt->xpt_server;
1921 struct sock *sk;
1922
1923 dprintk("svc: svc_delete_socket(%p)\n", svsk);
1924
1925 serv = svsk->sk_xprt.xpt_server;
1926 sk = svsk->sk_sk;
1927 1919
1928 svsk->sk_xprt.xpt_ops->xpo_detach(&svsk->sk_xprt); 1920 dprintk("svc: svc_delete_xprt(%p)\n", xprt);
1921 xprt->xpt_ops->xpo_detach(xprt);
1929 1922
1930 spin_lock_bh(&serv->sv_lock); 1923 spin_lock_bh(&serv->sv_lock);
1931 1924 if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags))
1932 if (!test_and_set_bit(XPT_DETACHED, &svsk->sk_xprt.xpt_flags)) 1925 list_del_init(&xprt->xpt_list);
1933 list_del_init(&svsk->sk_list);
1934 /* 1926 /*
1935 * We used to delete the svc_sock from whichever list 1927 * We used to delete the transport from whichever list
1936 * it's sk_ready node was on, but we don't actually 1928 * it's sk_xprt.xpt_ready node was on, but we don't actually
1937 * need to. This is because the only time we're called 1929 * need to. This is because the only time we're called
1938 * while still attached to a queue, the queue itself 1930 * while still attached to a queue, the queue itself
1939 * is about to be destroyed (in svc_destroy). 1931 * is about to be destroyed (in svc_destroy).
1940 */ 1932 */
1941 if (!test_and_set_bit(XPT_DEAD, &svsk->sk_xprt.xpt_flags)) { 1933 if (!test_and_set_bit(XPT_DEAD, &xprt->xpt_flags)) {
1942 BUG_ON(atomic_read(&svsk->sk_xprt.xpt_ref.refcount) < 2); 1934 BUG_ON(atomic_read(&xprt->xpt_ref.refcount) < 2);
1943 if (test_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags)) 1935 if (test_bit(XPT_TEMP, &xprt->xpt_flags))
1944 serv->sv_tmpcnt--; 1936 serv->sv_tmpcnt--;
1945 svc_xprt_put(&svsk->sk_xprt); 1937 svc_xprt_put(xprt);
1946 } 1938 }
1947
1948 spin_unlock_bh(&serv->sv_lock); 1939 spin_unlock_bh(&serv->sv_lock);
1949} 1940}
1950 1941
1951static void svc_close_socket(struct svc_sock *svsk) 1942static void svc_close_xprt(struct svc_xprt *xprt)
1952{ 1943{
1953 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); 1944 set_bit(XPT_CLOSE, &xprt->xpt_flags);
1954 if (test_and_set_bit(XPT_BUSY, &svsk->sk_xprt.xpt_flags)) 1945 if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags))
1955 /* someone else will have to effect the close */ 1946 /* someone else will have to effect the close */
1956 return; 1947 return;
1957 1948
1958 svc_xprt_get(&svsk->sk_xprt); 1949 svc_xprt_get(xprt);
1959 svc_delete_socket(svsk); 1950 svc_delete_xprt(xprt);
1960 clear_bit(XPT_BUSY, &svsk->sk_xprt.xpt_flags); 1951 clear_bit(XPT_BUSY, &xprt->xpt_flags);
1961 svc_xprt_put(&svsk->sk_xprt); 1952 svc_xprt_put(xprt);
1962} 1953}
1963 1954
1964void svc_force_close_socket(struct svc_sock *svsk) 1955void svc_close_all(struct list_head *xprt_list)
1965{ 1956{
1966 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); 1957 struct svc_xprt *xprt;
1967 if (test_bit(XPT_BUSY, &svsk->sk_xprt.xpt_flags)) { 1958 struct svc_xprt *tmp;
1968 /* Waiting to be processed, but no threads left, 1959
1969 * So just remove it from the waiting list 1960 list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) {
1970 */ 1961 set_bit(XPT_CLOSE, &xprt->xpt_flags);
1971 list_del_init(&svsk->sk_ready); 1962 if (test_bit(XPT_BUSY, &xprt->xpt_flags)) {
1972 clear_bit(XPT_BUSY, &svsk->sk_xprt.xpt_flags); 1963 /* Waiting to be processed, but no threads left,
1964 * So just remove it from the waiting list
1965 */
1966 list_del_init(&xprt->xpt_ready);
1967 clear_bit(XPT_BUSY, &xprt->xpt_flags);
1968 }
1969 svc_close_xprt(xprt);
1973 } 1970 }
1974 svc_close_socket(svsk);
1975} 1971}
1976 1972
1977/* 1973/*