aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2007-02-12 03:53:29 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-12 12:48:35 -0500
commit482fb94e1b0c2efe8258334aa2a68d4f4a91de9c (patch)
tree84353b34bb5ea02df98b598fff037cf1da20d6b0
parent6b174337e5126de834a971d3edc3681bbfa45e2c (diff)
[PATCH] knfsd: SUNRPC: allow creating an RPC service without registering with portmapper
Sometimes we need to create an RPC service but not register it with the local portmapper. NFSv4 delegation callback, for example. Change the svc_makesock() API to allow optionally creating temporary or permanent sockets, optionally registering with the local portmapper, and make it return the ephemeral port of the new socket. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net> Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/lockd/svc.c26
-rw-r--r--fs/nfs/callback.c20
-rw-r--r--fs/nfsd/nfssvc.c6
-rw-r--r--include/linux/sunrpc/svcsock.h2
-rw-r--r--net/sunrpc/svcsock.c6
5 files changed, 34 insertions, 26 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 8ca18085e68d..2c3d5ac4a3b6 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -223,23 +223,29 @@ static int find_socket(struct svc_serv *serv, int proto)
223 return found; 223 return found;
224} 224}
225 225
226/*
227 * Make any sockets that are needed but not present.
228 * If nlm_udpport or nlm_tcpport were set as module
229 * options, make those sockets unconditionally
230 */
226static int make_socks(struct svc_serv *serv, int proto) 231static int make_socks(struct svc_serv *serv, int proto)
227{ 232{
228 /* Make any sockets that are needed but not present. 233 static int warned;
229 * If nlm_udpport or nlm_tcpport were set as module
230 * options, make those sockets unconditionally
231 */
232 static int warned;
233 int err = 0; 234 int err = 0;
235
234 if (proto == IPPROTO_UDP || nlm_udpport) 236 if (proto == IPPROTO_UDP || nlm_udpport)
235 if (!find_socket(serv, IPPROTO_UDP)) 237 if (!find_socket(serv, IPPROTO_UDP))
236 err = svc_makesock(serv, IPPROTO_UDP, nlm_udpport); 238 err = svc_makesock(serv, IPPROTO_UDP, nlm_udpport,
237 if (err == 0 && (proto == IPPROTO_TCP || nlm_tcpport)) 239 SVC_SOCK_DEFAULTS);
240 if (err >= 0 && (proto == IPPROTO_TCP || nlm_tcpport))
238 if (!find_socket(serv, IPPROTO_TCP)) 241 if (!find_socket(serv, IPPROTO_TCP))
239 err= svc_makesock(serv, IPPROTO_TCP, nlm_tcpport); 242 err = svc_makesock(serv, IPPROTO_TCP, nlm_tcpport,
240 if (!err) 243 SVC_SOCK_DEFAULTS);
244
245 if (err >= 0) {
241 warned = 0; 246 warned = 0;
242 else if (warned++ == 0) 247 err = 0;
248 } else if (warned++ == 0)
243 printk(KERN_WARNING 249 printk(KERN_WARNING
244 "lockd_up: makesock failed, error=%d\n", err); 250 "lockd_up: makesock failed, error=%d\n", err);
245 return err; 251 return err;
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 7933e2e99dbc..a070109fa6c7 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -106,7 +106,6 @@ static void nfs_callback_svc(struct svc_rqst *rqstp)
106int nfs_callback_up(void) 106int nfs_callback_up(void)
107{ 107{
108 struct svc_serv *serv; 108 struct svc_serv *serv;
109 struct svc_sock *svsk;
110 int ret = 0; 109 int ret = 0;
111 110
112 lock_kernel(); 111 lock_kernel();
@@ -119,17 +118,14 @@ int nfs_callback_up(void)
119 ret = -ENOMEM; 118 ret = -ENOMEM;
120 if (!serv) 119 if (!serv)
121 goto out_err; 120 goto out_err;
122 /* FIXME: We don't want to register this socket with the portmapper */ 121
123 ret = svc_makesock(serv, IPPROTO_TCP, nfs_callback_set_tcpport); 122 ret = svc_makesock(serv, IPPROTO_TCP, nfs_callback_set_tcpport,
124 if (ret < 0) 123 SVC_SOCK_ANONYMOUS);
124 if (ret <= 0)
125 goto out_destroy; 125 goto out_destroy;
126 if (!list_empty(&serv->sv_permsocks)) { 126 nfs_callback_tcpport = ret;
127 svsk = list_entry(serv->sv_permsocks.next, 127 dprintk("Callback port = 0x%x\n", nfs_callback_tcpport);
128 struct svc_sock, sk_list); 128
129 nfs_callback_tcpport = ntohs(inet_sk(svsk->sk_sk)->sport);
130 dprintk ("Callback port = 0x%x\n", nfs_callback_tcpport);
131 } else
132 BUG();
133 ret = svc_create_thread(nfs_callback_svc, serv); 129 ret = svc_create_thread(nfs_callback_svc, serv);
134 if (ret < 0) 130 if (ret < 0)
135 goto out_destroy; 131 goto out_destroy;
@@ -140,6 +136,8 @@ out:
140 unlock_kernel(); 136 unlock_kernel();
141 return ret; 137 return ret;
142out_destroy: 138out_destroy:
139 dprintk("Couldn't create callback socket or server thread; err = %d\n",
140 ret);
143 svc_destroy(serv); 141 svc_destroy(serv);
144out_err: 142out_err:
145 nfs_callback_info.users--; 143 nfs_callback_info.users--;
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index fbf5d51947ea..d7759ce6ed94 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -235,7 +235,8 @@ static int nfsd_init_socks(int port)
235 235
236 error = lockd_up(IPPROTO_UDP); 236 error = lockd_up(IPPROTO_UDP);
237 if (error >= 0) { 237 if (error >= 0) {
238 error = svc_makesock(nfsd_serv, IPPROTO_UDP, port); 238 error = svc_makesock(nfsd_serv, IPPROTO_UDP, port,
239 SVC_SOCK_DEFAULTS);
239 if (error < 0) 240 if (error < 0)
240 lockd_down(); 241 lockd_down();
241 } 242 }
@@ -245,7 +246,8 @@ static int nfsd_init_socks(int port)
245#ifdef CONFIG_NFSD_TCP 246#ifdef CONFIG_NFSD_TCP
246 error = lockd_up(IPPROTO_TCP); 247 error = lockd_up(IPPROTO_TCP);
247 if (error >= 0) { 248 if (error >= 0) {
248 error = svc_makesock(nfsd_serv, IPPROTO_TCP, port); 249 error = svc_makesock(nfsd_serv, IPPROTO_TCP, port,
250 SVC_SOCK_DEFAULTS);
249 if (error < 0) 251 if (error < 0)
250 lockd_down(); 252 lockd_down();
251 } 253 }
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index cef11a6e81e9..f030409d2994 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -62,7 +62,7 @@ struct svc_sock {
62/* 62/*
63 * Function prototypes. 63 * Function prototypes.
64 */ 64 */
65int svc_makesock(struct svc_serv *, int, unsigned short); 65int svc_makesock(struct svc_serv *, int, unsigned short, int flags);
66void svc_close_socket(struct svc_sock *); 66void svc_close_socket(struct svc_sock *);
67int svc_recv(struct svc_rqst *, long); 67int svc_recv(struct svc_rqst *, long);
68int svc_send(struct svc_rqst *); 68int svc_send(struct svc_rqst *);
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 27ba34a152ec..d120fadeb1ae 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1689,9 +1689,11 @@ void svc_close_socket(struct svc_sock *svsk)
1689 * @serv: RPC server structure 1689 * @serv: RPC server structure
1690 * @protocol: transport protocol to use 1690 * @protocol: transport protocol to use
1691 * @port: port to use 1691 * @port: port to use
1692 * @flags: requested socket characteristics
1692 * 1693 *
1693 */ 1694 */
1694int svc_makesock(struct svc_serv *serv, int protocol, unsigned short port) 1695int svc_makesock(struct svc_serv *serv, int protocol, unsigned short port,
1696 int flags)
1695{ 1697{
1696 struct sockaddr_in sin = { 1698 struct sockaddr_in sin = {
1697 .sin_family = AF_INET, 1699 .sin_family = AF_INET,
@@ -1700,7 +1702,7 @@ int svc_makesock(struct svc_serv *serv, int protocol, unsigned short port)
1700 }; 1702 };
1701 1703
1702 dprintk("svc: creating socket proto = %d\n", protocol); 1704 dprintk("svc: creating socket proto = %d\n", protocol);
1703 return svc_create_socket(serv, protocol, &sin, SVC_SOCK_DEFAULTS); 1705 return svc_create_socket(serv, protocol, &sin, flags);
1704} 1706}
1705 1707
1706/* 1708/*