aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/svc_xprt.c43
-rw-r--r--net/sunrpc/svcsock.c39
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}
109EXPORT_SYMBOL_GPL(svc_xprt_init); 110EXPORT_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}
146EXPORT_SYMBOL_GPL(svc_create_xprt); 153EXPORT_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);
94static struct cache_deferred_req *svc_defer(struct cache_req *req); 94static struct cache_deferred_req *svc_defer(struct cache_req *req);
95static struct svc_xprt *svc_create_socket(struct svc_serv *, int, 95static struct svc_xprt *svc_create_socket(struct svc_serv *, int,
96 struct sockaddr *, int, int); 96 struct sockaddr *, int, int);
97static 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