diff options
Diffstat (limited to 'net/sunrpc/svc_xprt.c')
-rw-r--r-- | net/sunrpc/svc_xprt.c | 59 |
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 | */ |
101 | int svc_print_xprts(char *buf, int maxlen) | 101 | int 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 | } |
164 | EXPORT_SYMBOL_GPL(svc_xprt_init); | 164 | EXPORT_SYMBOL_GPL(svc_xprt_init); |
165 | 165 | ||
166 | static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl, | 166 | static 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 | ||
205 | int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, | 206 | int 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 | ||
877 | static 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 | } |
918 | EXPORT_SYMBOL_GPL(svc_close_xprt); | 935 | EXPORT_SYMBOL_GPL(svc_close_xprt); |
919 | 936 | ||