aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-10-02 05:17:48 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-02 10:57:18 -0400
commitb41b66d63c730cc45a1024e1f1e67439e507e40f (patch)
tree85f623c087a90ccf08a8264c638df5504f972c0d /fs
parent80212d59e32a8a8e030c2ddc5861d8ff70542c56 (diff)
[PATCH] knfsd: allow sockets to be passed to nfsd via 'portlist'
Userspace should create and bind a socket (but not connectted) and write the 'fd' to portlist. This will cause the nfs server to listen on that socket. To close a socket, the name of the socket - as read from 'portlist' can be written to 'portlist' with a preceding '-'. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfsctl.c59
-rw-r--r--fs/nfsd/nfssvc.c4
2 files changed, 51 insertions, 12 deletions
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index d4041a05bc19..80e97a5ffc3f 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -24,9 +24,11 @@
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/string.h> 25#include <linux/string.h>
26#include <linux/smp_lock.h> 26#include <linux/smp_lock.h>
27#include <linux/ctype.h>
27 28
28#include <linux/nfs.h> 29#include <linux/nfs.h>
29#include <linux/nfsd_idmap.h> 30#include <linux/nfsd_idmap.h>
31#include <linux/lockd/bind.h>
30#include <linux/sunrpc/svc.h> 32#include <linux/sunrpc/svc.h>
31#include <linux/sunrpc/svcsock.h> 33#include <linux/sunrpc/svcsock.h>
32#include <linux/nfsd/nfsd.h> 34#include <linux/nfsd/nfsd.h>
@@ -426,16 +428,55 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
426 428
427static ssize_t write_ports(struct file *file, char *buf, size_t size) 429static ssize_t write_ports(struct file *file, char *buf, size_t size)
428{ 430{
429 /* for now, ignore what was written and just 431 if (size == 0) {
430 * return known ports 432 int len = 0;
431 * AF proto address port 433 lock_kernel();
434 if (nfsd_serv)
435 len = svc_sock_names(buf, nfsd_serv, NULL);
436 unlock_kernel();
437 return len;
438 }
439 /* Either a single 'fd' number is written, in which
440 * case it must be for a socket of a supported family/protocol,
441 * and we use it as an nfsd socket, or
442 * A '-' followed by the 'name' of a socket in which case
443 * we close the socket.
432 */ 444 */
433 int len = 0; 445 if (isdigit(buf[0])) {
434 lock_kernel(); 446 char *mesg = buf;
435 if (nfsd_serv) 447 int fd;
436 len = svc_sock_names(buf, nfsd_serv); 448 int err;
437 unlock_kernel(); 449 err = get_int(&mesg, &fd);
438 return len; 450 if (err)
451 return -EINVAL;
452 if (fd < 0)
453 return -EINVAL;
454 err = nfsd_create_serv();
455 if (!err) {
456 int proto = 0;
457 err = svc_addsock(nfsd_serv, fd, buf, &proto);
458 /* Decrease the count, but don't shutdown the
459 * the service
460 */
461 if (err >= 0)
462 lockd_up(proto);
463 nfsd_serv->sv_nrthreads--;
464 }
465 return err;
466 }
467 if (buf[0] == '-') {
468 char *toclose = kstrdup(buf+1, GFP_KERNEL);
469 int len = 0;
470 if (!toclose)
471 return -ENOMEM;
472 lock_kernel();
473 if (nfsd_serv)
474 len = svc_sock_names(buf, nfsd_serv, toclose);
475 unlock_kernel();
476 kfree(toclose);
477 return len;
478 }
479 return -EINVAL;
439} 480}
440 481
441#ifdef CONFIG_NFSD_V4 482#ifdef CONFIG_NFSD_V4
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 5d473d8f0630..784f94fbebf3 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -195,7 +195,7 @@ void nfsd_reset_versions(void)
195 } 195 }
196} 196}
197 197
198static int nfsd_create_serv(void) 198int nfsd_create_serv(void)
199{ 199{
200 int err = 0; 200 int err = 0;
201 lock_kernel(); 201 lock_kernel();
@@ -210,8 +210,6 @@ static int nfsd_create_serv(void)
210 nfsd_last_thread); 210 nfsd_last_thread);
211 if (nfsd_serv == NULL) 211 if (nfsd_serv == NULL)
212 err = -ENOMEM; 212 err = -ENOMEM;
213 else
214 nfsd_serv->sv_nrthreads++;
215 unlock_kernel(); 213 unlock_kernel();
216 do_gettimeofday(&nfssvc_boot); /* record boot time */ 214 do_gettimeofday(&nfssvc_boot); /* record boot time */
217 return err; 215 return err;