diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2007-02-12 03:53:29 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-12 12:48:35 -0500 |
commit | 482fb94e1b0c2efe8258334aa2a68d4f4a91de9c (patch) | |
tree | 84353b34bb5ea02df98b598fff037cf1da20d6b0 | |
parent | 6b174337e5126de834a971d3edc3681bbfa45e2c (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.c | 26 | ||||
-rw-r--r-- | fs/nfs/callback.c | 20 | ||||
-rw-r--r-- | fs/nfsd/nfssvc.c | 6 | ||||
-rw-r--r-- | include/linux/sunrpc/svcsock.h | 2 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 6 |
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 | */ | ||
226 | static int make_socks(struct svc_serv *serv, int proto) | 231 | static 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) | |||
106 | int nfs_callback_up(void) | 106 | int 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; |
142 | out_destroy: | 138 | out_destroy: |
139 | dprintk("Couldn't create callback socket or server thread; err = %d\n", | ||
140 | ret); | ||
143 | svc_destroy(serv); | 141 | svc_destroy(serv); |
144 | out_err: | 142 | out_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 | */ |
65 | int svc_makesock(struct svc_serv *, int, unsigned short); | 65 | int svc_makesock(struct svc_serv *, int, unsigned short, int flags); |
66 | void svc_close_socket(struct svc_sock *); | 66 | void svc_close_socket(struct svc_sock *); |
67 | int svc_recv(struct svc_rqst *, long); | 67 | int svc_recv(struct svc_rqst *, long); |
68 | int svc_send(struct svc_rqst *); | 68 | int 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 | */ |
1694 | int svc_makesock(struct svc_serv *serv, int protocol, unsigned short port) | 1695 | int 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 | /* |