--- linux-2.6.14/fs/nfsd/nfsctl.c.aa1 2005-11-08 09:31:44.000000000 +0000 +++ linux-2.6.14/fs/nfsd/nfsctl.c 2005-11-08 09:32:14.000000000 +0000 @@ -36,7 +36,9 @@ #include <asm/uaccess.h> +int nfsd_port = 2049; +unsigned int nfsd_portbits = 0; unsigned int nfsd_versbits = ~0; /* * We have a single directory with 9 nodes in it. @@ -53,6 +55,7 @@ enum { NFSD_Fh, NFSD_Threads, NFSD_Versions, + NFSD_Ports, /* * The below MUST come last. Otherwise we leave a hole in nfsd_files[] * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops @@ -76,6 +73,7 @@ static ssize_t write_getfd(struct file * static ssize_t write_filehandle(struct file *file, char *buf, size_t size); static ssize_t write_threads(struct file *file, char *buf, size_t size); static ssize_t write_versions(struct file *file, char *buf, size_t size); +static ssize_t write_ports(struct file *file, char *buf, size_t size); #ifdef CONFIG_NFSD_V4 static ssize_t write_leasetime(struct file *file, char *buf, size_t size); static ssize_t write_recoverydir(struct file *file, char *buf, size_t size); @@ -92,7 +88,8 @@ static ssize_t (*write_op[])(struct file [NFSD_Getfs] = write_getfs, [NFSD_Fh] = write_filehandle, [NFSD_Threads] = write_threads, [NFSD_Versions] = write_versions, + [NFSD_Ports] = write_ports, #ifdef CONFIG_NFSD_V4 [NFSD_Leasetime] = write_leasetime, [NFSD_RecoveryDir] = write_recoverydir, @@ -358,7 +351,60 @@ static ssize_t write_threads(struct file sprintf(buf, "%d\n", nfsd_nrthreads()); return strlen(buf); } +static ssize_t write_ports(struct file *file, char *buf, size_t size) +{ + /* + * Format: + * family proto proto address port + */ + char *mesg = buf; + char *family, *udp, *tcp, *addr; + int len, port = 0; + ssize_t tlen = 0; + + if (buf[size-1] != '\n') + return -EINVAL; + buf[size-1] = 0; + family = mesg; + len = qword_get(&mesg, family, size); + if (len <= 0) return -EINVAL; + + tlen += len; + udp = family+len+1; + len = qword_get(&mesg, udp, size); + if (len <= 0) return -EINVAL; + + tlen += len; + tcp = udp+len+1; + len = qword_get(&mesg, tcp, size); + if (len <= 0) return -EINVAL; + + tlen += len; + addr = tcp+len+1; + len = qword_get(&mesg, addr, size); + if (len <= 0) return -EINVAL; + + len = get_int(&mesg, &port); + if (len) + return len; + + tlen += sizeof(port); + if (port) + nfsd_port = port; + + if (strcmp(tcp, "tcp") == 0 || strcmp(tcp, "TCP") == 0) + NFSCTL_TCPSET(nfsd_portbits); + else + NFSCTL_TCPUNSET(nfsd_portbits); + + if (strcmp(udp, "udp") == 0 || strcmp(udp, "UDP") == 0) + NFSCTL_UDPSET(nfsd_portbits); + else + NFSCTL_UDPUNSET(nfsd_portbits); + + return tlen; +} static ssize_t write_versions(struct file *file, char *buf, size_t size) { /* @@ -484,6 +508,7 @@ static int nfsd_fill_super(struct super_ [NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, + [NFSD_Ports] = {"ports", &transaction_ops, S_IWUSR|S_IRUSR}, #ifdef CONFIG_NFSD_V4 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR}, --- linux-2.6.14/fs/nfsd/nfs4state.c.aa1 2005-11-08 09:31:51.000000000 +0000 +++ linux-2.6.14/fs/nfsd/nfs4state.c 2005-11-08 09:32:14.000000000 +0000 @@ -3319,6 +3319,9 @@ __nfs4_state_shutdown(void) void nfs4_state_shutdown(void) { + if (!nfs4_init) + return; + nfs4_lock_state(); nfs4_release_reclaim(); __nfs4_state_shutdown(); --- linux-2.6.14/fs/nfsd/nfssvc.c.aa1 2005-11-08 09:31:44.000000000 +0000 +++ linux-2.6.14/fs/nfsd/nfssvc.c 2005-11-08 09:32:14.000000000 +0000 @@ -64,6 +64,8 @@ struct nfsd_list { }; static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list); +extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4; + static struct svc_version * nfsd_version[] = { [2] = &nfsd_version2, #if defined(CONFIG_NFSD_V3) @@ -110,8 +112,8 @@ nfsd_svc(unsigned short port, int nrserv struct list_head *victim; lock_kernel(); - dprintk("nfsd: creating service: vers 0x%x\n", - nfsd_versbits); + dprintk("nfsd: creating service: port %d vers 0x%x proto 0x%x\n", + nfsd_port, nfsd_versbits, nfsd_portbits); error = -EINVAL; if (nrservs <= 0) nrservs = 0; @@ -126,11 +147,15 @@ nfsd_svc(unsigned short port, int nrserv nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE); if (nfsd_serv == NULL) goto out; + if (NFSCTL_UDPISSET(nfsd_portbits)) + port = nfsd_port; error = svc_makesock(nfsd_serv, IPPROTO_UDP, port); if (error < 0) goto failure; #ifdef CONFIG_NFSD_TCP + if (NFSCTL_TCPISSET(nfsd_portbits)) + port = nfsd_port; error = svc_makesock(nfsd_serv, IPPROTO_TCP, port); if (error < 0) goto failure; --- linux-2.6.14/include/linux/nfsd/syscall.h.aa1 2005-11-08 09:31:44.000000000 +0000 +++ linux-2.6.14/include/linux/nfsd/syscall.h 2005-11-08 09:32:14.000000000 +0000 @@ -40,19 +40,28 @@ #define NFSCTL_GETFS 8 /* get an fh by path with max FH len */ /* - * Macros used to set version + * Macros used to set version and protocol */ #define NFSCTL_VERSET(_cltbits, _v) ((_cltbits) |= (1 << (_v))) #define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << (_v))) #define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << (_v))) #if defined(CONFIG_NFSD_V4) #define NFSCTL_VERALL (0x1c /* 0b011100 */) #elif defined(CONFIG_NFSD_V3) #define NFSCTL_VERALL (0x0c /* 0b001100 */) #else #define NFSCTL_VERALL (0x04 /* 0b000100 */) #endif + +#define NFSCTL_UDPSET(_cltbits) ((_cltbits) |= (1 << (17 - 1))) +#define NFSCTL_UDPUNSET(_cltbits) ((_cltbits) &= ~(1 << (17 - 1))) +#define NFSCTL_UDPISSET(_cltbits) ((_cltbits) & (1 << (17 - 1))) + +#define NFSCTL_TCPSET(_cltbits) ((_cltbits) |= (1 << (18 - 1))) +#define NFSCTL_TCPUNSET(_cltbits) ((_cltbits) &= ~(1 << (18 - 1))) +#define NFSCTL_TCPISSET(_cltbits) ((_cltbits) & (1 << (18 - 1))) + /* SVC */ struct nfsctl_svc { @@ -135,7 +136,8 @@ extern int exp_delclient(struct nfsctl_ extern int exp_export(struct nfsctl_export *nxp); extern int exp_unexport(struct nfsctl_export *nxp); -extern unsigned int nfsd_versbits; +extern int nfsd_port; +extern unsigned int nfsd_versbits, nfsd_portbits; #endif /* __KERNEL__ */