diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/svc_xprt.c | 43 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 39 |
2 files changed, 43 insertions, 39 deletions
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index eb650af50c49..271467c5138d 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -105,6 +105,7 @@ void svc_xprt_init(struct svc_xprt_class *xcl, struct svc_xprt *xprt, | |||
105 | INIT_LIST_HEAD(&xprt->xpt_deferred); | 105 | INIT_LIST_HEAD(&xprt->xpt_deferred); |
106 | mutex_init(&xprt->xpt_mutex); | 106 | mutex_init(&xprt->xpt_mutex); |
107 | spin_lock_init(&xprt->xpt_lock); | 107 | spin_lock_init(&xprt->xpt_lock); |
108 | set_bit(XPT_BUSY, &xprt->xpt_flags); | ||
108 | } | 109 | } |
109 | EXPORT_SYMBOL_GPL(svc_xprt_init); | 110 | EXPORT_SYMBOL_GPL(svc_xprt_init); |
110 | 111 | ||
@@ -112,7 +113,6 @@ int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port, | |||
112 | int flags) | 113 | int flags) |
113 | { | 114 | { |
114 | struct svc_xprt_class *xcl; | 115 | struct svc_xprt_class *xcl; |
115 | int ret = -ENOENT; | ||
116 | struct sockaddr_in sin = { | 116 | struct sockaddr_in sin = { |
117 | .sin_family = AF_INET, | 117 | .sin_family = AF_INET, |
118 | .sin_addr.s_addr = INADDR_ANY, | 118 | .sin_addr.s_addr = INADDR_ANY, |
@@ -121,27 +121,34 @@ int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port, | |||
121 | dprintk("svc: creating transport %s[%d]\n", xprt_name, port); | 121 | dprintk("svc: creating transport %s[%d]\n", xprt_name, port); |
122 | spin_lock(&svc_xprt_class_lock); | 122 | spin_lock(&svc_xprt_class_lock); |
123 | list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) { | 123 | list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) { |
124 | if (strcmp(xprt_name, xcl->xcl_name) == 0) { | 124 | struct svc_xprt *newxprt; |
125 | spin_unlock(&svc_xprt_class_lock); | 125 | |
126 | if (try_module_get(xcl->xcl_owner)) { | 126 | if (strcmp(xprt_name, xcl->xcl_name)) |
127 | struct svc_xprt *newxprt; | 127 | continue; |
128 | newxprt = xcl->xcl_ops->xpo_create | 128 | |
129 | (serv, | 129 | if (!try_module_get(xcl->xcl_owner)) |
130 | (struct sockaddr *)&sin, sizeof(sin), | 130 | goto err; |
131 | flags); | 131 | |
132 | if (IS_ERR(newxprt)) { | 132 | spin_unlock(&svc_xprt_class_lock); |
133 | module_put(xcl->xcl_owner); | 133 | newxprt = xcl->xcl_ops-> |
134 | ret = PTR_ERR(newxprt); | 134 | xpo_create(serv, (struct sockaddr *)&sin, sizeof(sin), |
135 | } else | 135 | flags); |
136 | ret = svc_xprt_local_port(newxprt); | 136 | if (IS_ERR(newxprt)) { |
137 | } | 137 | module_put(xcl->xcl_owner); |
138 | goto out; | 138 | return PTR_ERR(newxprt); |
139 | } | 139 | } |
140 | |||
141 | clear_bit(XPT_TEMP, &newxprt->xpt_flags); | ||
142 | spin_lock_bh(&serv->sv_lock); | ||
143 | list_add(&newxprt->xpt_list, &serv->sv_permsocks); | ||
144 | spin_unlock_bh(&serv->sv_lock); | ||
145 | clear_bit(XPT_BUSY, &newxprt->xpt_flags); | ||
146 | return svc_xprt_local_port(newxprt); | ||
140 | } | 147 | } |
148 | err: | ||
141 | spin_unlock(&svc_xprt_class_lock); | 149 | spin_unlock(&svc_xprt_class_lock); |
142 | dprintk("svc: transport %s not found\n", xprt_name); | 150 | dprintk("svc: transport %s not found\n", xprt_name); |
143 | out: | 151 | return -ENOENT; |
144 | return ret; | ||
145 | } | 152 | } |
146 | EXPORT_SYMBOL_GPL(svc_create_xprt); | 153 | EXPORT_SYMBOL_GPL(svc_create_xprt); |
147 | 154 | ||
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index e43412bb07ae..b1cb97bbbd34 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -94,6 +94,7 @@ static int svc_deferred_recv(struct svc_rqst *rqstp); | |||
94 | static struct cache_deferred_req *svc_defer(struct cache_req *req); | 94 | static struct cache_deferred_req *svc_defer(struct cache_req *req); |
95 | static struct svc_xprt *svc_create_socket(struct svc_serv *, int, | 95 | static struct svc_xprt *svc_create_socket(struct svc_serv *, int, |
96 | struct sockaddr *, int, int); | 96 | struct sockaddr *, int, int); |
97 | static void svc_age_temp_xprts(unsigned long closure); | ||
97 | 98 | ||
98 | /* apparently the "standard" is that clients close | 99 | /* apparently the "standard" is that clients close |
99 | * idle connections after 5 minutes, servers after | 100 | * idle connections after 5 minutes, servers after |
@@ -1573,6 +1574,19 @@ svc_recv(struct svc_rqst *rqstp, long timeout) | |||
1573 | */ | 1574 | */ |
1574 | __module_get(newxpt->xpt_class->xcl_owner); | 1575 | __module_get(newxpt->xpt_class->xcl_owner); |
1575 | svc_check_conn_limits(xprt->xpt_server); | 1576 | svc_check_conn_limits(xprt->xpt_server); |
1577 | spin_lock_bh(&serv->sv_lock); | ||
1578 | set_bit(XPT_TEMP, &newxpt->xpt_flags); | ||
1579 | list_add(&newxpt->xpt_list, &serv->sv_tempsocks); | ||
1580 | serv->sv_tmpcnt++; | ||
1581 | if (serv->sv_temptimer.function == NULL) { | ||
1582 | /* setup timer to age temp sockets */ | ||
1583 | setup_timer(&serv->sv_temptimer, | ||
1584 | svc_age_temp_xprts, | ||
1585 | (unsigned long)serv); | ||
1586 | mod_timer(&serv->sv_temptimer, | ||
1587 | jiffies + svc_conn_age_period * HZ); | ||
1588 | } | ||
1589 | spin_unlock_bh(&serv->sv_lock); | ||
1576 | svc_xprt_received(newxpt); | 1590 | svc_xprt_received(newxpt); |
1577 | } | 1591 | } |
1578 | svc_xprt_received(xprt); | 1592 | svc_xprt_received(xprt); |
@@ -1716,7 +1730,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, | |||
1716 | struct svc_sock *svsk; | 1730 | struct svc_sock *svsk; |
1717 | struct sock *inet; | 1731 | struct sock *inet; |
1718 | int pmap_register = !(flags & SVC_SOCK_ANONYMOUS); | 1732 | int pmap_register = !(flags & SVC_SOCK_ANONYMOUS); |
1719 | int is_temporary = flags & SVC_SOCK_TEMPORARY; | ||
1720 | 1733 | ||
1721 | dprintk("svc: svc_setup_socket %p\n", sock); | 1734 | dprintk("svc: svc_setup_socket %p\n", sock); |
1722 | if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) { | 1735 | if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) { |
@@ -1736,7 +1749,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, | |||
1736 | return NULL; | 1749 | return NULL; |
1737 | } | 1750 | } |
1738 | 1751 | ||
1739 | set_bit(XPT_BUSY, &svsk->sk_xprt.xpt_flags); | ||
1740 | inet->sk_user_data = svsk; | 1752 | inet->sk_user_data = svsk; |
1741 | svsk->sk_sock = sock; | 1753 | svsk->sk_sock = sock; |
1742 | svsk->sk_sk = inet; | 1754 | svsk->sk_sk = inet; |
@@ -1750,24 +1762,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, | |||
1750 | else | 1762 | else |
1751 | svc_tcp_init(svsk, serv); | 1763 | svc_tcp_init(svsk, serv); |
1752 | 1764 | ||
1753 | spin_lock_bh(&serv->sv_lock); | ||
1754 | if (is_temporary) { | ||
1755 | set_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags); | ||
1756 | list_add(&svsk->sk_xprt.xpt_list, &serv->sv_tempsocks); | ||
1757 | serv->sv_tmpcnt++; | ||
1758 | if (serv->sv_temptimer.function == NULL) { | ||
1759 | /* setup timer to age temp sockets */ | ||
1760 | setup_timer(&serv->sv_temptimer, svc_age_temp_xprts, | ||
1761 | (unsigned long)serv); | ||
1762 | mod_timer(&serv->sv_temptimer, | ||
1763 | jiffies + svc_conn_age_period * HZ); | ||
1764 | } | ||
1765 | } else { | ||
1766 | clear_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags); | ||
1767 | list_add(&svsk->sk_xprt.xpt_list, &serv->sv_permsocks); | ||
1768 | } | ||
1769 | spin_unlock_bh(&serv->sv_lock); | ||
1770 | |||
1771 | dprintk("svc: svc_setup_socket created %p (inet %p)\n", | 1765 | dprintk("svc: svc_setup_socket created %p (inet %p)\n", |
1772 | svsk, svsk->sk_sk); | 1766 | svsk, svsk->sk_sk); |
1773 | 1767 | ||
@@ -1800,6 +1794,10 @@ int svc_addsock(struct svc_serv *serv, | |||
1800 | int salen; | 1794 | int salen; |
1801 | if (kernel_getsockname(svsk->sk_sock, sin, &salen) == 0) | 1795 | if (kernel_getsockname(svsk->sk_sock, sin, &salen) == 0) |
1802 | svc_xprt_set_local(&svsk->sk_xprt, sin, salen); | 1796 | svc_xprt_set_local(&svsk->sk_xprt, sin, salen); |
1797 | clear_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags); | ||
1798 | spin_lock_bh(&serv->sv_lock); | ||
1799 | list_add(&svsk->sk_xprt.xpt_list, &serv->sv_permsocks); | ||
1800 | spin_unlock_bh(&serv->sv_lock); | ||
1803 | svc_xprt_received(&svsk->sk_xprt); | 1801 | svc_xprt_received(&svsk->sk_xprt); |
1804 | err = 0; | 1802 | err = 0; |
1805 | } | 1803 | } |
@@ -1865,7 +1863,6 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv, | |||
1865 | 1863 | ||
1866 | if ((svsk = svc_setup_socket(serv, sock, &error, flags)) != NULL) { | 1864 | if ((svsk = svc_setup_socket(serv, sock, &error, flags)) != NULL) { |
1867 | svc_xprt_set_local(&svsk->sk_xprt, newsin, newlen); | 1865 | svc_xprt_set_local(&svsk->sk_xprt, newsin, newlen); |
1868 | svc_xprt_received(&svsk->sk_xprt); | ||
1869 | return (struct svc_xprt *)svsk; | 1866 | return (struct svc_xprt *)svsk; |
1870 | } | 1867 | } |
1871 | 1868 | ||