aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svc_xprt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/svc_xprt.c')
-rw-r--r--net/sunrpc/svc_xprt.c59
1 files changed, 38 insertions, 21 deletions
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index cbc084939dd8..c82fe739fbdc 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -100,16 +100,14 @@ EXPORT_SYMBOL_GPL(svc_unreg_xprt_class);
100 */ 100 */
101int svc_print_xprts(char *buf, int maxlen) 101int svc_print_xprts(char *buf, int maxlen)
102{ 102{
103 struct list_head *le; 103 struct svc_xprt_class *xcl;
104 char tmpstr[80]; 104 char tmpstr[80];
105 int len = 0; 105 int len = 0;
106 buf[0] = '\0'; 106 buf[0] = '\0';
107 107
108 spin_lock(&svc_xprt_class_lock); 108 spin_lock(&svc_xprt_class_lock);
109 list_for_each(le, &svc_xprt_class_list) { 109 list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) {
110 int slen; 110 int slen;
111 struct svc_xprt_class *xcl =
112 list_entry(le, struct svc_xprt_class, xcl_list);
113 111
114 sprintf(tmpstr, "%s %d\n", xcl->xcl_name, xcl->xcl_max_payload); 112 sprintf(tmpstr, "%s %d\n", xcl->xcl_name, xcl->xcl_max_payload);
115 slen = strlen(tmpstr); 113 slen = strlen(tmpstr);
@@ -128,9 +126,9 @@ static void svc_xprt_free(struct kref *kref)
128 struct svc_xprt *xprt = 126 struct svc_xprt *xprt =
129 container_of(kref, struct svc_xprt, xpt_ref); 127 container_of(kref, struct svc_xprt, xpt_ref);
130 struct module *owner = xprt->xpt_class->xcl_owner; 128 struct module *owner = xprt->xpt_class->xcl_owner;
131 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags) && 129 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags))
132 xprt->xpt_auth_cache != NULL) 130 svcauth_unix_info_release(xprt);
133 svcauth_unix_info_release(xprt->xpt_auth_cache); 131 put_net(xprt->xpt_net);
134 xprt->xpt_ops->xpo_free(xprt); 132 xprt->xpt_ops->xpo_free(xprt);
135 module_put(owner); 133 module_put(owner);
136} 134}
@@ -156,15 +154,18 @@ void svc_xprt_init(struct svc_xprt_class *xcl, struct svc_xprt *xprt,
156 INIT_LIST_HEAD(&xprt->xpt_list); 154 INIT_LIST_HEAD(&xprt->xpt_list);
157 INIT_LIST_HEAD(&xprt->xpt_ready); 155 INIT_LIST_HEAD(&xprt->xpt_ready);
158 INIT_LIST_HEAD(&xprt->xpt_deferred); 156 INIT_LIST_HEAD(&xprt->xpt_deferred);
157 INIT_LIST_HEAD(&xprt->xpt_users);
159 mutex_init(&xprt->xpt_mutex); 158 mutex_init(&xprt->xpt_mutex);
160 spin_lock_init(&xprt->xpt_lock); 159 spin_lock_init(&xprt->xpt_lock);
161 set_bit(XPT_BUSY, &xprt->xpt_flags); 160 set_bit(XPT_BUSY, &xprt->xpt_flags);
162 rpc_init_wait_queue(&xprt->xpt_bc_pending, "xpt_bc_pending"); 161 rpc_init_wait_queue(&xprt->xpt_bc_pending, "xpt_bc_pending");
162 xprt->xpt_net = get_net(&init_net);
163} 163}
164EXPORT_SYMBOL_GPL(svc_xprt_init); 164EXPORT_SYMBOL_GPL(svc_xprt_init);
165 165
166static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl, 166static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
167 struct svc_serv *serv, 167 struct svc_serv *serv,
168 struct net *net,
168 const int family, 169 const int family,
169 const unsigned short port, 170 const unsigned short port,
170 int flags) 171 int flags)
@@ -199,12 +200,12 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
199 return ERR_PTR(-EAFNOSUPPORT); 200 return ERR_PTR(-EAFNOSUPPORT);
200 } 201 }
201 202
202 return xcl->xcl_ops->xpo_create(serv, sap, len, flags); 203 return xcl->xcl_ops->xpo_create(serv, net, sap, len, flags);
203} 204}
204 205
205int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, 206int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
206 const int family, const unsigned short port, 207 struct net *net, const int family,
207 int flags) 208 const unsigned short port, int flags)
208{ 209{
209 struct svc_xprt_class *xcl; 210 struct svc_xprt_class *xcl;
210 211
@@ -220,7 +221,7 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
220 goto err; 221 goto err;
221 222
222 spin_unlock(&svc_xprt_class_lock); 223 spin_unlock(&svc_xprt_class_lock);
223 newxprt = __svc_xpo_create(xcl, serv, family, port, flags); 224 newxprt = __svc_xpo_create(xcl, serv, net, family, port, flags);
224 if (IS_ERR(newxprt)) { 225 if (IS_ERR(newxprt)) {
225 module_put(xcl->xcl_owner); 226 module_put(xcl->xcl_owner);
226 return PTR_ERR(newxprt); 227 return PTR_ERR(newxprt);
@@ -329,12 +330,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
329 "svc_xprt_enqueue: " 330 "svc_xprt_enqueue: "
330 "threads and transports both waiting??\n"); 331 "threads and transports both waiting??\n");
331 332
332 if (test_bit(XPT_DEAD, &xprt->xpt_flags)) {
333 /* Don't enqueue dead transports */
334 dprintk("svc: transport %p is dead, not enqueued\n", xprt);
335 goto out_unlock;
336 }
337
338 pool->sp_stats.packets++; 333 pool->sp_stats.packets++;
339 334
340 /* Mark transport as busy. It will remain in this state until 335 /* Mark transport as busy. It will remain in this state until
@@ -651,6 +646,11 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
651 if (signalled() || kthread_should_stop()) 646 if (signalled() || kthread_should_stop())
652 return -EINTR; 647 return -EINTR;
653 648
649 /* Normally we will wait up to 5 seconds for any required
650 * cache information to be provided.
651 */
652 rqstp->rq_chandle.thread_wait = 5*HZ;
653
654 spin_lock_bh(&pool->sp_lock); 654 spin_lock_bh(&pool->sp_lock);
655 xprt = svc_xprt_dequeue(pool); 655 xprt = svc_xprt_dequeue(pool);
656 if (xprt) { 656 if (xprt) {
@@ -658,6 +658,12 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
658 svc_xprt_get(xprt); 658 svc_xprt_get(xprt);
659 rqstp->rq_reserved = serv->sv_max_mesg; 659 rqstp->rq_reserved = serv->sv_max_mesg;
660 atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); 660 atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
661
662 /* As there is a shortage of threads and this request
663 * had to be queued, don't allow the thread to wait so
664 * long for cache updates.
665 */
666 rqstp->rq_chandle.thread_wait = 1*HZ;
661 } else { 667 } else {
662 /* No data pending. Go to sleep */ 668 /* No data pending. Go to sleep */
663 svc_thread_enqueue(pool, rqstp); 669 svc_thread_enqueue(pool, rqstp);
@@ -868,6 +874,19 @@ static void svc_age_temp_xprts(unsigned long closure)
868 mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ); 874 mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ);
869} 875}
870 876
877static void call_xpt_users(struct svc_xprt *xprt)
878{
879 struct svc_xpt_user *u;
880
881 spin_lock(&xprt->xpt_lock);
882 while (!list_empty(&xprt->xpt_users)) {
883 u = list_first_entry(&xprt->xpt_users, struct svc_xpt_user, list);
884 list_del(&u->list);
885 u->callback(u);
886 }
887 spin_unlock(&xprt->xpt_lock);
888}
889
871/* 890/*
872 * Remove a dead transport 891 * Remove a dead transport
873 */ 892 */
@@ -878,7 +897,7 @@ void svc_delete_xprt(struct svc_xprt *xprt)
878 897
879 /* Only do this once */ 898 /* Only do this once */
880 if (test_and_set_bit(XPT_DEAD, &xprt->xpt_flags)) 899 if (test_and_set_bit(XPT_DEAD, &xprt->xpt_flags))
881 return; 900 BUG();
882 901
883 dprintk("svc: svc_delete_xprt(%p)\n", xprt); 902 dprintk("svc: svc_delete_xprt(%p)\n", xprt);
884 xprt->xpt_ops->xpo_detach(xprt); 903 xprt->xpt_ops->xpo_detach(xprt);
@@ -900,6 +919,7 @@ void svc_delete_xprt(struct svc_xprt *xprt)
900 while ((dr = svc_deferred_dequeue(xprt)) != NULL) 919 while ((dr = svc_deferred_dequeue(xprt)) != NULL)
901 kfree(dr); 920 kfree(dr);
902 921
922 call_xpt_users(xprt);
903 svc_xprt_put(xprt); 923 svc_xprt_put(xprt);
904} 924}
905 925
@@ -910,10 +930,7 @@ void svc_close_xprt(struct svc_xprt *xprt)
910 /* someone else will have to effect the close */ 930 /* someone else will have to effect the close */
911 return; 931 return;
912 932
913 svc_xprt_get(xprt);
914 svc_delete_xprt(xprt); 933 svc_delete_xprt(xprt);
915 clear_bit(XPT_BUSY, &xprt->xpt_flags);
916 svc_xprt_put(xprt);
917} 934}
918EXPORT_SYMBOL_GPL(svc_close_xprt); 935EXPORT_SYMBOL_GPL(svc_close_xprt);
919 936