NFS client with non-reserved ports. This allows to mount more than 800 volumes quickly, without waiting for TIME_WAIT sockets to dissipate. diff -ur -X dontdiff linux-2.4.19-pre7/fs/lockd/clntproc.c linux-2.4.19-pre7-p3/fs/lockd/clntproc.c --- linux-2.4.19-pre7/fs/lockd/clntproc.c Thu Oct 11 07:52:18 2001 +++ linux-2.4.19-pre7-p3/fs/lockd/clntproc.c Wed Apr 24 16:51:08 2002 @@ -109,6 +109,7 @@ sigset_t oldset; unsigned long flags; int status, proto, vers; + int resport; vers = (NFS_PROTO(inode)->version == 3) ? 4 : 1; if (NFS_PROTO(inode)->version > 3) { @@ -118,6 +119,7 @@ /* Retrieve transport protocol from NFS client */ proto = NFS_CLIENT(inode)->cl_xprt->prot; + resport = NFS_CLIENT(inode)->cl_xprt->resport; if (!(host = nlmclnt_lookup_host(NFS_ADDR(inode), proto, vers))) return -ENOLCK; @@ -129,7 +131,7 @@ /* Bind an rpc client to this host handle (does not * perform a portmapper lookup) */ - if (!(clnt = nlm_bind_host(host))) { + if (!(clnt = nlm_bind_host(host, resport))) { status = -ENOLCK; goto done; } @@ -164,6 +166,7 @@ locks_init_lock(&call->a_res.lock.fl); } call->a_host = host; + call->a_resport = resport; /* Set up the argument struct */ nlmclnt_setlockargs(call, fl); @@ -262,7 +265,7 @@ } /* If we have no RPC client yet, create one. */ - if ((clnt = nlm_bind_host(host)) == NULL) + if ((clnt = nlm_bind_host(host, req->a_resport)) == NULL) return -ENOLCK; /* Perform the RPC call. If an error occurs, try again */ @@ -330,7 +333,7 @@ nlm_procname(proc), host->h_name); /* If we have no RPC client yet, create one. */ - if ((clnt = nlm_bind_host(host)) == NULL) + if ((clnt = nlm_bind_host(host, req->a_resport)) == NULL) return -ENOLCK; /* bootstrap and kick off the async RPC call */ @@ -358,7 +361,7 @@ nlm_procname(proc), host->h_name); /* If we have no RPC client yet, create one. */ - if ((clnt = nlm_bind_host(host)) == NULL) + if ((clnt = nlm_bind_host(host, req->a_resport)) == NULL) return -ENOLCK; /* bootstrap and kick off the async RPC call */ diff -ur -X dontdiff linux-2.4.19-pre7/fs/lockd/host.c linux-2.4.19-pre7-p3/fs/lockd/host.c --- linux-2.4.19-pre7/fs/lockd/host.c Mon Oct 1 13:45:47 2001 +++ linux-2.4.19-pre7-p3/fs/lockd/host.c Wed Apr 24 16:51:08 2002 @@ -163,7 +163,7 @@ * Create the NLM RPC client for an NLM peer */ struct rpc_clnt * -nlm_bind_host(struct nlm_host *host) +nlm_bind_host(struct nlm_host *host, int resport) { struct rpc_clnt *clnt; struct rpc_xprt *xprt; @@ -187,15 +187,19 @@ host->h_nextrebind - jiffies); } } else { - uid_t saved_fsuid = current->fsuid; - kernel_cap_t saved_cap = current->cap_effective; + if (resport) { + uid_t saved_fsuid = current->fsuid; + kernel_cap_t saved_cap = current->cap_effective; - /* Create RPC socket as root user so we get a priv port */ - current->fsuid = 0; - cap_raise (current->cap_effective, CAP_NET_BIND_SERVICE); - xprt = xprt_create_proto(host->h_proto, &host->h_addr, NULL); - current->fsuid = saved_fsuid; - current->cap_effective = saved_cap; + /* Create RPC socket as root user so we get a priv port */ + current->fsuid = 0; + cap_raise (current->cap_effective, CAP_NET_BIND_SERVICE); + xprt = xprt_create_proto(host->h_proto, &host->h_addr, NULL, 1); + current->fsuid = saved_fsuid; + current->cap_effective = saved_cap; + } else { + xprt = xprt_create_proto(host->h_proto, &host->h_addr, NULL, 0); + } if (xprt == NULL) goto forgetit; diff -ur -X dontdiff linux-2.4.19-pre7/fs/lockd/mon.c linux-2.4.19-pre7-p3/fs/lockd/mon.c --- linux-2.4.19-pre7/fs/lockd/mon.c Mon Oct 1 13:45:47 2001 +++ linux-2.4.19-pre7-p3/fs/lockd/mon.c Wed Apr 24 16:51:08 2002 @@ -110,7 +110,7 @@ sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); sin.sin_port = 0; - xprt = xprt_create_proto(IPPROTO_UDP, &sin, NULL); + xprt = xprt_create_proto(IPPROTO_UDP, &sin, NULL, 1); if (!xprt) goto out; diff -ur -X dontdiff linux-2.4.19-pre7/fs/nfs/inode.c linux-2.4.19-pre7-p3/fs/nfs/inode.c --- linux-2.4.19-pre7/fs/nfs/inode.c Tue Apr 23 17:08:47 2002 +++ linux-2.4.19-pre7-p3/fs/nfs/inode.c Wed Apr 24 16:51:08 2002 @@ -361,7 +361,7 @@ /* Now create transport and client */ xprt = xprt_create_proto(tcp? IPPROTO_TCP : IPPROTO_UDP, - &srvaddr, &timeparms); + &srvaddr, &timeparms, (data->flags & NFS_MOUNT_NORES) == 0); if (xprt == NULL) goto out_no_xprt; diff -ur -X dontdiff linux-2.4.19-pre7/fs/nfs/mount_clnt.c linux-2.4.19-pre7-p3/fs/nfs/mount_clnt.c --- linux-2.4.19-pre7/fs/nfs/mount_clnt.c Thu Apr 13 07:54:19 2000 +++ linux-2.4.19-pre7-p3/fs/nfs/mount_clnt.c Wed Apr 24 16:51:08 2002 @@ -82,7 +82,7 @@ struct rpc_xprt *xprt; struct rpc_clnt *clnt; - if (!(xprt = xprt_create_proto(IPPROTO_UDP, srvaddr, NULL))) + if (!(xprt = xprt_create_proto(IPPROTO_UDP, srvaddr, NULL, 1))) return NULL; clnt = rpc_create_client(xprt, hostname, diff -ur -X dontdiff linux-2.4.19-pre7/include/linux/lockd/lockd.h linux-2.4.19-pre7-p3/include/linux/lockd/lockd.h --- linux-2.4.19-pre7/include/linux/lockd/lockd.h Thu Nov 22 11:47:20 2001 +++ linux-2.4.19-pre7-p3/include/linux/lockd/lockd.h Wed Apr 24 17:29:55 2002 @@ -64,6 +64,7 @@ #define NLMCLNT_OHSIZE (sizeof(system_utsname.nodename)+10) struct nlm_rqst { unsigned int a_flags; /* initial RPC task flags */ + int a_resport; struct nlm_host * a_host; /* host handle */ struct nlm_args a_args; /* arguments */ struct nlm_res a_res; /* result */ @@ -145,7 +146,7 @@ struct nlm_host * nlmsvc_lookup_host(struct svc_rqst *); struct nlm_host * nlm_lookup_host(struct svc_client *, struct sockaddr_in *, int, int); -struct rpc_clnt * nlm_bind_host(struct nlm_host *); +struct rpc_clnt * nlm_bind_host(struct nlm_host *, int); void nlm_rebind_host(struct nlm_host *); struct nlm_host * nlm_get_host(struct nlm_host *); void nlm_release_host(struct nlm_host *); Only in linux-2.4.19-pre7-p3/include/linux: modules diff -ur -X dontdiff linux-2.4.19-pre7/include/linux/nfs_mount.h linux-2.4.19-pre7-p3/include/linux/nfs_mount.h --- linux-2.4.19-pre7/include/linux/nfs_mount.h Thu Nov 22 11:47:41 2001 +++ linux-2.4.19-pre7-p3/include/linux/nfs_mount.h Wed Apr 24 17:28:03 2002 @@ -53,6 +53,7 @@ #define NFS_MOUNT_KERBEROS 0x0100 /* 3 */ #define NFS_MOUNT_NONLM 0x0200 /* 3 */ #define NFS_MOUNT_BROKEN_SUID 0x0400 /* 4 */ +#define NFS_MOUNT_NORES 0x0800 /* ? XXX */ #define NFS_MOUNT_FLAGMASK 0xFFFF #endif diff -ur -X dontdiff linux-2.4.19-pre7/include/linux/sunrpc/xprt.h linux-2.4.19-pre7-p3/include/linux/sunrpc/xprt.h --- linux-2.4.19-pre7/include/linux/sunrpc/xprt.h Thu Nov 22 11:47:20 2001 +++ linux-2.4.19-pre7-p3/include/linux/sunrpc/xprt.h Wed Apr 24 16:57:27 2002 @@ -141,7 +141,8 @@ unsigned char shutdown : 1, /* being shut down */ nocong : 1, /* no congestion control */ stream : 1, /* TCP */ - tcp_more : 1; /* more record fragments */ + tcp_more : 1, /* more record fragments */ + resport : 1; /* use reserved port */ /* * State of TCP reply receive stuff @@ -171,7 +172,8 @@ #ifdef __KERNEL__ struct rpc_xprt * xprt_create_proto(int proto, struct sockaddr_in *addr, - struct rpc_timeout *toparms); + struct rpc_timeout *toparms, + int use_res_port); int xprt_destroy(struct rpc_xprt *); void xprt_shutdown(struct rpc_xprt *); void xprt_default_timeout(struct rpc_timeout *, int); diff -ur -X dontdiff linux-2.4.19-pre7/net/sunrpc/pmap_clnt.c linux-2.4.19-pre7-p3/net/sunrpc/pmap_clnt.c --- linux-2.4.19-pre7/net/sunrpc/pmap_clnt.c Fri Sep 21 11:24:50 2001 +++ linux-2.4.19-pre7-p3/net/sunrpc/pmap_clnt.c Wed Apr 24 16:51:08 2002 @@ -28,7 +28,7 @@ #define PMAP_UNSET 2 #define PMAP_GETPORT 3 -static struct rpc_clnt * pmap_create(char *, struct sockaddr_in *, int); +static struct rpc_clnt *pmap_create(char *, struct sockaddr_in *, int, int); static void pmap_getport_done(struct rpc_task *); extern struct rpc_program pmap_program; static spinlock_t pmap_lock = SPIN_LOCK_UNLOCKED; @@ -60,7 +60,7 @@ spin_unlock(&pmap_lock); task->tk_status = -EACCES; /* why set this? returns -EIO below */ - if (!(pmap_clnt = pmap_create(clnt->cl_server, sap, map->pm_prot))) + if (!(pmap_clnt = pmap_create(clnt->cl_server, sap, map->pm_prot, 0))) goto bailout; task->tk_status = 0; @@ -101,7 +101,7 @@ NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot); strcpy(hostname, in_ntoa(sin->sin_addr.s_addr)); - if (!(pmap_clnt = pmap_create(hostname, sin, prot))) + if (!(pmap_clnt = pmap_create(hostname, sin, prot, 0))) return -EACCES; /* Setup the call info struct */ @@ -158,7 +158,8 @@ sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - if (!(pmap_clnt = pmap_create("localhost", &sin, IPPROTO_UDP))) { + /* Use a privileged port or else portmapper rejects out request. */ + if (!(pmap_clnt = pmap_create("localhost", &sin, IPPROTO_UDP, 1))) { dprintk("RPC: couldn't create pmap client\n"); return -EACCES; } @@ -183,13 +184,13 @@ } static struct rpc_clnt * -pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto) +pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto, int resport) { struct rpc_xprt *xprt; struct rpc_clnt *clnt; /* printk("pmap: create xprt\n"); */ - if (!(xprt = xprt_create_proto(proto, srvaddr, NULL))) + if (!(xprt = xprt_create_proto(proto, srvaddr, NULL, resport))) return NULL; xprt->addr.sin_port = htons(RPC_PMAP_PORT); diff -ur -X dontdiff linux-2.4.19-pre7/net/sunrpc/xprt.c linux-2.4.19-pre7-p3/net/sunrpc/xprt.c --- linux-2.4.19-pre7/net/sunrpc/xprt.c Tue Apr 23 17:09:01 2002 +++ linux-2.4.19-pre7-p3/net/sunrpc/xprt.c Wed Apr 24 16:51:08 2002 @@ -85,7 +85,7 @@ static void xprt_reserve_status(struct rpc_task *task); static void xprt_disconnect(struct rpc_xprt *); static void xprt_reconn_status(struct rpc_task *task); -static struct socket *xprt_create_socket(int, struct rpc_timeout *); +static struct socket *xprt_create_socket(int, struct rpc_timeout *, int); static int xprt_bind_socket(struct rpc_xprt *, struct socket *); static void xprt_remove_pending(struct rpc_xprt *); @@ -460,7 +460,8 @@ status = -ENOTCONN; if (!inet) { /* Create an unconnected socket */ - if (!(sock = xprt_create_socket(xprt->prot, &xprt->timeout))) + if (!(sock = xprt_create_socket(xprt->prot, &xprt->timeout, + xprt->resport))) goto defer; xprt_bind_socket(xprt, sock); inet = sock->sk; @@ -1448,7 +1449,7 @@ */ static struct rpc_xprt * xprt_setup(struct socket *sock, int proto, - struct sockaddr_in *ap, struct rpc_timeout *to) + struct sockaddr_in *ap, struct rpc_timeout *to, int use_resport) { struct rpc_xprt *xprt; struct rpc_rqst *req; @@ -1494,6 +1495,8 @@ INIT_LIST_HEAD(&xprt->rx_pending); + xprt->resport = use_resport; + dprintk("RPC: created transport %p\n", xprt); xprt_bind_socket(xprt, sock); @@ -1564,7 +1567,7 @@ * Create a client socket given the protocol and peer address. */ static struct socket * -xprt_create_socket(int proto, struct rpc_timeout *to) +xprt_create_socket(int proto, struct rpc_timeout *to, int resport) { struct socket *sock; int type, err; @@ -1580,7 +1583,8 @@ } /* If the caller has the capability, bind to a reserved port */ - if (capable(CAP_NET_BIND_SERVICE) && xprt_bindresvport(sock) < 0) + if (resport && + capable(CAP_NET_BIND_SERVICE) && xprt_bindresvport(sock) < 0) goto failed; return sock; @@ -1594,17 +1598,18 @@ * Create an RPC client transport given the protocol and peer address. */ struct rpc_xprt * -xprt_create_proto(int proto, struct sockaddr_in *sap, struct rpc_timeout *to) +xprt_create_proto(int proto, struct sockaddr_in *sap, struct rpc_timeout *to, + int use_resport) { struct socket *sock; struct rpc_xprt *xprt; dprintk("RPC: xprt_create_proto called\n"); - if (!(sock = xprt_create_socket(proto, to))) + if (!(sock = xprt_create_socket(proto, to, use_resport))) return NULL; - if (!(xprt = xprt_setup(sock, proto, sap, to))) + if (!(xprt = xprt_setup(sock, proto, sap, to, use_resport))) sock_release(sock); return xprt;