[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-nfs
Subject:    Re: [NFS] [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more.
From:       Steve Dickson <SteveD () redhat ! com>
Date:       2005-03-23 11:56:58
Message-ID: 4241598A.20504 () RedHat ! com
[Download RAW message or body]

Steve Dickson wrote:
> The following patches fix the '-p port' command line
> argument to rpc.nfsd as well as adds following
> flags that control the NFS versions and transports that
> rpc.nfsd will use.
Just for the sake of completion on this proposal, I've updated
the patches to introduce the -V flag and changed the name of the file
rpc.nfsd uses from threads, to config (i.e. /proc/fs/nfsd/config),
which does more accurately describes what is happening....

steved.


["nfs-utils-1.0.7-nfsd-ctlbits2.patch" (text/x-patch)]

--- nfs-utils-1.0.7/support/include/nfs/nfs.h.orig	2003-07-02 22:09:31.000000000 -0400
+++ nfs-utils-1.0.7/support/include/nfs/nfs.h	2005-03-22 08:48:55.055423216 -0500
@@ -40,7 +40,14 @@ struct nfs_fh_old {
 #define NFSCTL_LOCKD		0x10000
 #define LOCKDCTL_SVC		NFSCTL_LOCKD
 
-
+#define NFSCTL_VERSET(_cltbits, _v)   ((_cltbits) |= (1 << ((_v) - 1)))
+#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << ((_v) - 1))) 
+#define NFSCTL_UDPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (17 - 1))) 
+#define NFSCTL_TCPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (18 - 1))) 
+
+#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << ((_v) - 1))) 
+#define NFSCTL_UDPISSET(_cltbits)     ((_cltbits) & (1 << (17 - 1))) 
+#define NFSCTL_TCPISSET(_cltbits)     ((_cltbits) & (1 << (18 - 1))) 
 
 /* SVC */
 struct nfsctl_svc {
--- nfs-utils-1.0.7/support/include/nfslib.h.orig	2004-09-14 21:58:40.000000000 -0400
+++ nfs-utils-1.0.7/support/include/nfslib.h	2005-03-17 09:02:15.000000000 -0500
@@ -118,7 +118,7 @@ int			wildmat(char *text, char *pattern)
  * nfsd library functions.
  */
 int			nfsctl(int, struct nfsctl_arg *, union nfsctl_res *);
-int			nfssvc(int port, int nrservs);
+int			nfssvc(int port, int nrservs, unsigned int ctlbits);
 int			nfsaddclient(struct nfsctl_client *clp);
 int			nfsdelclient(struct nfsctl_client *clp);
 int			nfsexport(struct nfsctl_export *exp);
--- nfs-utils-1.0.7/support/nfs/nfssvc.c.orig	2005-03-17 09:44:28.000000000 -0500
+++ nfs-utils-1.0.7/support/nfs/nfssvc.c	2005-03-22 09:29:34.956501872 -0500
@@ -14,27 +14,32 @@
 #include "nfslib.h"
 
 int
-nfssvc(int port, int nrservs)
+nfssvc(int port, int nrservs, unsigned ctlbits)
 {
 	struct nfsctl_arg	arg;
 	int fd;
 
-	fd = open("/proc/fs/nfsd/threads", O_WRONLY);
+	fd = open("/proc/fs/nfsd/config", O_WRONLY);
 	if (fd < 0)
 		fd = open("/proc/fs/nfs/threads", O_WRONLY);
 	if (fd >= 0) {
 		/* 2.5+ kernel with nfsd filesystem mounted.
 		 * Just write the number in.
-		 * Cannot handle port number yet, but does anyone care?
 		 */
-		char buf[20];
+		char buf[40];
 		int n;
-		snprintf(buf, 20,"%d\n", nrservs);
+		snprintf(buf, 40,"%d %d %d\n", nrservs, port, ctlbits);
 		n = write(fd, buf, strlen(buf));
 		close(fd);
-		if (n != strlen(buf))
-			return -1;
-		else
+		if (n != strlen(buf)) {
+			/*
+			 * See if this an older kernel that does not
+			 * have the ctlbits support
+			 */
+			snprintf(buf, 40, "%d\n", nrservs);
+			if (n != strlen(buf))
+				return -1;
+		} else
 			return 0;
 	}
 
--- nfs-utils-1.0.7/utils/mountd/mountd.c.orig	2005-03-17 07:30:36.000000000 -0500
+++ nfs-utils-1.0.7/utils/mountd/mountd.c	2005-03-19 11:57:38.000000000 -0500
@@ -255,6 +255,9 @@ mount_mnt_3_svc(struct svc_req *rqstp, d
 			= sizeof(flavors)/sizeof(flavors[0]);
 		ok->auth_flavors.auth_flavors_val = flavors;
 	}
+	if (fh == NULL || res->fhs_status)
+		xlog(D_CALL, "MNT3(%s) failed: status %d\n", res->fhs_status);
+
 	return 1;
 }
 
--- nfs-utils-1.0.7/utils/nfsd/nfsd.c.orig	2005-03-17 07:30:36.000000000 -0500
+++ nfs-utils-1.0.7/utils/nfsd/nfsd.c	2005-03-22 09:22:43.600037560 -0500
@@ -23,12 +23,25 @@
 
 static void	usage(const char *);
 
+static struct option longopts[] =
+{
+	{ "help", 0, 0, 'h' },
+	{ "nfs-version", 1, 0, 'V' },
+	{ "no-nfs-version", 1, 0, 'N' },
+	{ "no-tcp", 0, 0, 'T' },
+	{ "no-udp", 0, 0, 'U' },
+	{ "port", 1, 0, 'P' },
+	{ "port", 1, 0, 'p' },
+	{ NULL, 0, 0, 0 }
+};
+
 int
 main(int argc, char **argv)
 {
-	int	count = 1, c, error, port, fd;
+	int	count = 1, c, error, port, fd, found_one;
 	struct servent *ent;
 	DIR *dir;
+	unsigned int ctlbits = ~0;
 
 	ent = getservbyname ("nfs", "udp");
 	if (ent != NULL)
@@ -36,7 +49,7 @@ main(int argc, char **argv)
 	else
 		port = 2049;
 
-	while ((c = getopt(argc, argv, "hp:P:")) != EOF) {
+	while ((c = getopt_long(argc, argv, "hN:p:P:TUV:", longopts, NULL)) != EOF) {
 		switch(c) {
 		case 'P':	/* XXX for nfs-server compatibility */
 		case 'p':
@@ -47,12 +60,70 @@ main(int argc, char **argv)
 				usage(argv [0]);
 			}
 			break;
+		case 'N':
+			switch((c = atoi(optarg))) {
+			case 2:
+			case 3:
+			case 4:
+				NFSCTL_VERUNSET(ctlbits, c);
+				break;
+			default:
+				fprintf(stderr, "%c: Unsupported version\n", c);
+				exit(1);
+			}
+			break;
+		case 'T':
+			NFSCTL_TCPUNSET(ctlbits);
+			break;
+		case 'U':
+			NFSCTL_UDPUNSET(ctlbits);
+			break;
+		case 'V':
+			switch((c = atoi(optarg))) {
+			case 2:
+				NFSCTL_VERUNSET(ctlbits, 3);
+				NFSCTL_VERUNSET(ctlbits, 4);
+				break;
+			case 3:
+				NFSCTL_VERUNSET(ctlbits, 2);
+				NFSCTL_VERUNSET(ctlbits, 4);
+				break;
+			case 4:
+				NFSCTL_VERUNSET(ctlbits, 2);
+				NFSCTL_VERUNSET(ctlbits, 3);
+				break;
+			default:
+				fprintf(stderr, "%c: Unsupported version\n", c);
+				exit(1);
+			}
+			NFSCTL_VERSET(ctlbits, c);
 			break;
-		case 'h':
 		default:
+			fprintf(stderr, "Invalid argument: '%c'\n", c);
+		case 'h':
 			usage(argv[0]);
 		}
 	}
+	/*
+	 * Do some sanity checking, if the ctlbits are set
+	 */
+	if (!NFSCTL_UDPISSET(ctlbits) && !NFSCTL_TCPISSET(ctlbits)) {
+		fprintf(stderr, "invalid protocol specified\n");
+		exit(1);
+	}
+	found_one = 0;
+	for (c = 2; c <= 4; c++) {
+		if (NFSCTL_VERISSET(ctlbits, c))
+			found_one = 1;
+	}
+	if (!found_one) {
+		fprintf(stderr, "no version specified\n");
+		exit(1);
+	}			
+	if (NFSCTL_VERISSET(ctlbits, 4) && !NFSCTL_TCPISSET(ctlbits)) {
+		fprintf(stderr, "version 4 requires the TCP protocol\n");
+		exit(1);
+	}
 
 	if (chdir(NFS_STATEDIR)) {
 		fprintf(stderr, "%s: chdir(%s) failed: %s\n",
@@ -99,7 +170,7 @@ main(int argc, char **argv)
 			(void) close(fd);
 	}
 
-	if ((error = nfssvc(port, count)) < 0) {
+	if ((error = nfssvc(port, count, ctlbits)) < 0) {
 		int e = errno;
 		openlog("nfsd", LOG_PID, LOG_DAEMON);
 		syslog(LOG_ERR, "nfssvc: %s", strerror(e));
@@ -112,7 +183,8 @@ main(int argc, char **argv)
 static void
 usage(const char *prog)
 {
-	fprintf(stderr, "usage:\n"
-			"%s nrservs\n", prog);
+	fprintf(stderr, "Usage:\n"
+		"%s [-p|-P|--port] [-N|no-nfs-version] [-T|--no-tcp] [-U|--no-udp] nrservs\n", 
+		prog);
 	exit(2);
 }
--- nfs-utils-1.0.7/utils/nfsd/nfsd.man.orig	2002-08-26 12:57:59.000000000 -0400
+++ nfs-utils-1.0.7/utils/nfsd/nfsd.man	2005-03-22 09:37:24.414133464 -0500
@@ -6,7 +6,7 @@
 .SH NAME
 rpc.nfsd \- NFS server process
 .SH SYNOPSIS
-.BI "/usr/sbin/rpc.nfsd [-p " port "] " nproc
+.BI "/usr/sbin/rpc.nfsd [" options "]" " "nproc
 .SH DESCRIPTION
 The
 .B rpc.nfsd
@@ -22,11 +22,35 @@ server provides an ancillary service nee
 by NFS clients.
 .SH OPTIONS
 .TP
-.BI \-p " port"
+.B \-p " or " \-\-port  port
 specify a diferent port to listen on for NFS requests. By default,
 .B rpc.nfsd
 will listen on port 2049.
 .TP
+.B \-N " or " \-\-no-nfs-version vers
+This option can be used to request that 
+.B rpc.nfsd
+do not offer certain versions of NFS. The current version of
+.B rpc.nfsd
+can support both NFS version 2,3 and the newer version 4.
+.TP
+.B \-T " or " \-\-no-tcp
+Disable 
+.B rpc.nfsd 
+from accepting TCP connections from clients.
+.TP
+.B \-U " or " \-\-no-udp
+Disable
+.B rpc.nfsd
+from accepting UDP connections from clients.
+.TP
+.B \-V " or " \-\-nfs-version
+This option can be used to request that
+.B rpc.nfsd
+offer certain versions of NFS. The current version of
+.B rpc.nfsd
+can support NFS version 2,3 and the newer version 4.
+.TP
 .I nproc
 specify the number of NFS server threads. By default, just one
 thread is started. However, for optimum performance several threads


["linux-2.6.11-nfsd-ctlbits2.patch" (text/x-patch)]

--- linux-2.6.11/fs/nfsd/nfs4state.c.orig	2005-03-02 02:38:13.000000000 -0500
+++ linux-2.6.11/fs/nfsd/nfs4state.c	2005-03-18 06:59:15.000000000 -0500
@@ -3250,6 +3250,8 @@ __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.11/fs/nfsd/nfssvc.c.orig	2005-03-02 02:38:10.000000000 -0500
+++ linux-2.6.11/fs/nfsd/nfssvc.c	2005-03-18 08:39:53.000000000 -0500
@@ -30,6 +30,7 @@
 #include <linux/nfsd/nfsd.h>
 #include <linux/nfsd/stats.h>
 #include <linux/nfsd/cache.h>
+#include <linux/nfsd/syscall.h>
 #include <linux/lockd/bind.h>
 
 #define NFSDDBG_FACILITY	NFSDDBG_SVC
@@ -62,6 +63,29 @@ struct nfsd_list {
 };
 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)
+	[3] = &nfsd_version3,
+#endif
+#if defined(CONFIG_NFSD_V4)
+	[4] = &nfsd_version4,
+#endif
+};
+
+#define NFSD_MINVERS    2
+#define NFSD_NRVERS		(sizeof(nfsd_version)/sizeof(nfsd_version[0]))
+struct svc_program		nfsd_program = {
+	.pg_prog		= NFS_PROGRAM,		/* program number */
+	.pg_nvers		= NFSD_NRVERS,		/* nr of entries in nfsd_version */
+	.pg_vers		= nfsd_version,	/* version table */
+	.pg_name		= "nfsd",		/* program name */
+	.pg_class		= "nfsd",		/* authentication class */
+	.pg_stats		= &nfsd_svcstats,	/* version table */
+};
+
 /*
  * Maximum number of nfsd processes
  */
@@ -76,23 +100,47 @@ int nfsd_nrthreads(void)
 }
 
 int
-nfsd_svc(unsigned short port, int nrservs)
+nfsd_svc(unsigned short port, int nrservs, unsigned int ctlbits)
 {
 	int	error;
-	int	none_left;	
+	int	none_left, found_one, i;
 	struct list_head *victim;
 	
+	dprintk("nfsd: creating service (port %d nserver %d ctlbits 0x%x)\n",
+		port, nrservs, ctlbits);
+
 	lock_kernel();
-	dprintk("nfsd: creating service\n");
 	error = -EINVAL;
 	if (nrservs <= 0)
 		nrservs = 0;
 	if (nrservs > NFSD_MAXSERVS)
 		nrservs = NFSD_MAXSERVS;
-	
+	/*
+	 * If set, use the ctlbits to define the
+	 * services that will be advertised
+	 */
+	if (ctlbits) {
+		found_one = 0;
+		for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
+			if (NFSCTL_VERISSET(ctlbits, i)) {
+				nfsd_program.pg_vers[i] = nfsd_version[i]; 
+				found_one = 1;
+			} else
+				nfsd_program.pg_vers[i] = NULL;
+		}
+		if (!found_one) {
+			printk(KERN_ERR "nfsd: no version set (cltbits 0x%x)\n", ctlbits);
+			goto out;
+		}			
+	} else { /* otherwise, turn everthing on */
+		ctlbits = ~0;
+		nfsd_program.pg_vers = nfsd_version;
+	}
+
 	/* Readahead param cache - will no-op if it already exists */
 	error =	nfsd_racache_init(2*nrservs);
-	nfs4_state_init();
+	if (NFSCTL_VERISSET(ctlbits, 4))
+		nfs4_state_init();
 	if (error<0)
 		goto out;
 	if (!nfsd_serv) {
@@ -101,14 +149,17 @@ nfsd_svc(unsigned short port, int nrserv
 		nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
 		if (nfsd_serv == NULL)
 			goto out;
-		error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
-		if (error < 0)
-			goto failure;
-
+		if (NFSCTL_UDPISSET(ctlbits)) {
+			error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
+			if (error < 0)
+				goto failure;
+		}
 #ifdef CONFIG_NFSD_TCP
-		error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
-		if (error < 0)
-			goto failure;
+		if (NFSCTL_TCPISSET(ctlbits)) {
+			error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
+			if (error < 0)
+				goto failure;
+		}
 #endif
 		do_gettimeofday(&nfssvc_boot);		/* record boot time */
 	} else
@@ -358,24 +409,3 @@ nfsd_dispatch(struct svc_rqst *rqstp, u3
 	return 1;
 }
 
-extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
-
-static struct svc_version *	nfsd_version[] = {
-	[2] = &nfsd_version2,
-#if defined(CONFIG_NFSD_V3)
-	[3] = &nfsd_version3,
-#endif
-#if defined(CONFIG_NFSD_V4)
-	[4] = &nfsd_version4,
-#endif
-};
-
-#define NFSD_NRVERS		(sizeof(nfsd_version)/sizeof(nfsd_version[0]))
-struct svc_program		nfsd_program = {
-	.pg_prog		= NFS_PROGRAM,		/* program number */
-	.pg_nvers		= NFSD_NRVERS,		/* nr of entries in nfsd_version */
-	.pg_vers		= nfsd_version,		/* version table */
-	.pg_name		= "nfsd",		/* program name */
-	.pg_class		= "nfsd",		/* authentication class */
-	.pg_stats		= &nfsd_svcstats,	/* version table */
-};
--- linux-2.6.11/fs/nfsd/nfsctl.c.orig	2005-03-18 07:21:19.000000000 -0500
+++ linux-2.6.11/fs/nfsd/nfsctl.c	2005-03-22 07:41:34.000000000 -0500
@@ -49,7 +49,7 @@ enum {
 	NFSD_Getfs,
 	NFSD_List,
 	NFSD_Fh,
-	NFSD_Threads,
+	NFSD_Config,
 	NFSD_Leasetime,
 };
 
@@ -64,7 +64,7 @@ static ssize_t write_unexport(struct fil
 static ssize_t write_getfd(struct file *file, char *buf, size_t size);
 static ssize_t write_getfs(struct file *file, char *buf, size_t size);
 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_config(struct file *file, char *buf, size_t size);
 static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
 
 static ssize_t (*write_op[])(struct file *, char *, size_t) = {
@@ -76,7 +76,7 @@ static ssize_t (*write_op[])(struct file
 	[NFSD_Getfd] = write_getfd,
 	[NFSD_Getfs] = write_getfs,
 	[NFSD_Fh] = write_filehandle,
-	[NFSD_Threads] = write_threads,
+	[NFSD_Config] = write_config,
 	[NFSD_Leasetime] = write_leasetime,
 };
 
@@ -133,7 +133,7 @@ static ssize_t write_svc(struct file *fi
 	if (size < sizeof(*data))
 		return -EINVAL;
 	data = (struct nfsctl_svc*) buf;
-	return nfsd_svc(data->svc_port, data->svc_nthreads);
+	return nfsd_svc(data->svc_port, data->svc_nthreads, 0);
 }
 
 static ssize_t write_add(struct file *file, char *buf, size_t size)
@@ -304,13 +304,16 @@ static ssize_t write_filehandle(struct f
 
 extern int nfsd_nrthreads(void);
 
-static ssize_t write_threads(struct file *file, char *buf, size_t size)
+static ssize_t write_config(struct file *file, char *buf, size_t size)
 {
 	/* if size > 0, look for a number of threads and call nfsd_svc
 	 * then write out number of threads as reply
 	 */
 	char *mesg = buf;
 	int rv;
+	unsigned int ctlbits = 0;
+	unsigned int port = 0;
+
 	if (size > 0) {
 		int newthreads;
 		rv = get_int(&mesg, &newthreads);
@@ -318,11 +321,30 @@ static ssize_t write_threads(struct file
 			return rv;
 		if (newthreads <0)
 			return -EINVAL;
-		rv = nfsd_svc(2049, newthreads);
+		rv = get_int(&mesg, &port);
+		if (rv) {
+			/*
+			 * its possible the rpc.nfsd does not 
+			 * have the ctlbits support, so just 
+			 * fill in with default values 
+			 */
+			port = 2049;
+			ctlbits = ~0;
+			sprintf(buf, "%d\n", newthreads);
+		} else {
+			rv = get_int(&mesg, &ctlbits);
+			if (rv) {
+				ctlbits = ~0;
+				sprintf(buf, "%d %d\n", nfsd_nrthreads(), port);
+			} else
+				sprintf(buf, "%d %d %d\n", nfsd_nrthreads(), port, ctlbits);
+		}
+		rv = nfsd_svc((unsigned short)port, newthreads, ctlbits);
 		if (rv)
 			return rv;
-	}
-	sprintf(buf, "%d\n", nfsd_nrthreads());
+	} else 
+		sprintf(buf, "%d\n", nfsd_nrthreads());
+
 	return strlen(buf);
 }
 
@@ -366,7 +388,7 @@ static int nfsd_fill_super(struct super_
 		[NFSD_Getfs] = {".getfs", &transaction_ops, S_IWUSR|S_IRUSR},
 		[NFSD_List] = {"exports", &exports_operations, S_IRUGO},
 		[NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
-		[NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
+		[NFSD_Config] = {"config", &transaction_ops, S_IWUSR|S_IRUSR},
 #ifdef CONFIG_NFSD_V4
 		[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
 #endif
--- linux-2.6.11/include/linux/nfsd/syscall.h.orig	2005-03-02 02:38:38.000000000 -0500
+++ linux-2.6.11/include/linux/nfsd/syscall.h	2005-03-18 07:30:26.000000000 -0500
@@ -39,6 +39,14 @@
 #define NFSCTL_GETFD		7	/* get an fh by path (used by mountd) */
 #define	NFSCTL_GETFS		8	/* get an fh by path with max FH len */
 
+#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << ((_v) - 1)))
+#define NFSCTL_UDPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (17 - 1)))
+#define NFSCTL_TCPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (18 - 1)))
+
+#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << ((_v) - 1)))
+#define NFSCTL_UDPISSET(_cltbits)     ((_cltbits) & (1 << (17 - 1)))
+#define NFSCTL_TCPISSET(_cltbits)     ((_cltbits) & (1 << (18 - 1)))
+
 /* SVC */
 struct nfsctl_svc {
 	unsigned short		svc_port;
--- linux-2.6.11/include/linux/nfsd/nfsd.h.orig	2005-03-02 02:38:32.000000000 -0500
+++ linux-2.6.11/include/linux/nfsd/nfsd.h	2005-03-18 05:08:55.000000000 -0500
@@ -63,7 +63,7 @@ extern struct svc_version	nfsd_version2,
 /*
  * Function prototypes.
  */
-int		nfsd_svc(unsigned short port, int nrservs);
+int		nfsd_svc(unsigned short port, int nrservs, unsigned int ctlbits);
 int		nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp);
 
 /* nfsd/vfs.c */


-------------------------------------------------------
This SF.net email is sponsored by: 2005 Windows Mobile Application Contest
Submit applications for Windows Mobile(tm)-based Pocket PCs or Smartphones
for the chance to win $25,000 and application distribution. Enter today at
http://ads.osdn.com/?ad_id=6882&alloc_id=15148&op=click
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic