[Midnightbsd-cvs] src [9920] trunk/sys/nlm: sync

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Fri May 25 09:02:31 EDT 2018


Revision: 9920
          http://svnweb.midnightbsd.org/src/?rev=9920
Author:   laffer1
Date:     2018-05-25 09:02:30 -0400 (Fri, 25 May 2018)
Log Message:
-----------
sync

Modified Paths:
--------------
    trunk/sys/nlm/nlm_advlock.c
    trunk/sys/nlm/nlm_prot_clnt.c
    trunk/sys/nlm/nlm_prot_impl.c

Modified: trunk/sys/nlm/nlm_advlock.c
===================================================================
--- trunk/sys/nlm/nlm_advlock.c	2018-05-25 13:01:20 UTC (rev 9919)
+++ trunk/sys/nlm/nlm_advlock.c	2018-05-25 13:02:30 UTC (rev 9920)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2008 Isilon Inc http://www.isilon.com/
  * Authors: Doug Rabson <dfr at rabson.org>
@@ -26,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nlm/nlm_advlock.c 302209 2016-06-26 13:18:03Z kib $");
 
 #include <sys/param.h>
 #include <sys/fcntl.h>
@@ -210,7 +211,7 @@
 	struct rpc_callextra ext;
 	struct nlm_feedback_arg nf;
 	AUTH *auth;
-	struct ucred *cred;
+	struct ucred *cred, *cred1;
 	struct nlm_file_svid *ns;
 	int svid;
 	int error;
@@ -240,15 +241,17 @@
 	else
 		retries = INT_MAX;
 
-	if (unlock_vp)
-		VOP_UNLOCK(vp, 0);
-
 	/*
 	 * We need to switch to mount-point creds so that we can send
-	 * packets from a privileged port.
+	 * packets from a privileged port.  Reference mnt_cred and
+	 * switch to them before unlocking the vnode, since mount
+	 * point could be unmounted right after unlock.
 	 */
 	cred = td->td_ucred;
 	td->td_ucred = vp->v_mount->mnt_cred;
+	crhold(td->td_ucred);
+	if (unlock_vp)
+		VOP_UNLOCK(vp, 0);
 
 	host = nlm_find_host_by_name(servername, sa, vers);
 	auth = authunix_create(cred);
@@ -373,7 +376,9 @@
 	if (ns)
 		nlm_free_svid(ns);
 
+	cred1 = td->td_ucred;
 	td->td_ucred = cred;
+	crfree(cred1);
 	AUTH_DESTROY(auth);
 
 	nlm_host_release(host);
@@ -709,7 +714,37 @@
 	newfl.l_pid = svid;
 	newfl.l_sysid = NLM_SYSID_CLIENT | sysid;
 
-	error = lf_advlockasync(&a, &vp->v_lockf, size);
+	for (;;) {
+		error = lf_advlockasync(&a, &vp->v_lockf, size);
+		if (error == EDEADLK) {
+			/*
+			 * Locks are associated with the processes and
+			 * not with threads.  Suppose we have two
+			 * threads A1 A2 in one process, A1 locked
+			 * file f1, A2 is locking file f2, and A1 is
+			 * unlocking f1. Then remote server may
+			 * already unlocked f1, while local still not
+			 * yet scheduled A1 to make the call to local
+			 * advlock manager. The process B owns lock on
+			 * f2 and issued the lock on f1.  Remote would
+			 * grant B the request on f1, but local would
+			 * return EDEADLK.
+			*/
+			pause("nlmdlk", 1);
+			/* XXXKIB allow suspend */
+		} else if (error == EINTR) {
+			/*
+			 * lf_purgelocks() might wake up the lock
+			 * waiter and removed our lock graph edges.
+			 * There is no sense in re-trying recording
+			 * the lock to the local manager after
+			 * reclaim.
+			 */
+			error = 0;
+			break;
+		} else
+			break;
+	}
 	KASSERT(error == 0 || error == ENOENT,
 	    ("Failed to register NFS lock locally - error=%d", error));
 }

Modified: trunk/sys/nlm/nlm_prot_clnt.c
===================================================================
--- trunk/sys/nlm/nlm_prot_clnt.c	2018-05-25 13:01:20 UTC (rev 9919)
+++ trunk/sys/nlm/nlm_prot_clnt.c	2018-05-25 13:02:30 UTC (rev 9920)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Please do not edit this file.
  * It was generated using rpcgen.
@@ -15,7 +16,7 @@
 /*static char sccsid[] = "from: * @(#)nlm_prot.x	2.1 88/08/01 4.0 RPCSRC";*/
 __RCSID("$NetBSD: nlm_prot.x,v 1.6 2000/06/07 14:30:15 bouyer Exp $");
 #endif /* not lint */
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nlm/nlm_prot_clnt.c 180025 2008-06-26 10:21:54Z dfr $");
 
 enum clnt_stat 
 nlm_sm_notify_0(struct nlm_sm_status *argp, void *clnt_res, CLIENT *clnt, struct rpc_callextra *ext, struct timeval timo)

Modified: trunk/sys/nlm/nlm_prot_impl.c
===================================================================
--- trunk/sys/nlm/nlm_prot_impl.c	2018-05-25 13:01:20 UTC (rev 9919)
+++ trunk/sys/nlm/nlm_prot_impl.c	2018-05-25 13:02:30 UTC (rev 9920)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2008 Isilon Inc http://www.isilon.com/
  * Authors: Doug Rabson <dfr at rabson.org>
@@ -28,7 +29,7 @@
 #include "opt_inet6.h"
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nlm/nlm_prot_impl.c 303173 2016-07-22 03:09:47Z sbruno $");
 
 #include <sys/param.h>
 #include <sys/fail.h>
@@ -133,6 +134,11 @@
 static time_t nlm_next_idle_check;
 
 /*
+ * A flag to indicate the server is already running.
+ */
+static int nlm_is_running;
+
+/*
  * A socket to use for RPC - shared by all IPv4 RPC clients.
  */
 static struct socket *nlm_socket;
@@ -1067,7 +1073,7 @@
 		break;
 #endif
 	default:
-		strcmp(tmp, "<unknown>");
+		strlcpy(tmp, "<unknown>", sizeof(tmp));
 	}
 
 
@@ -1434,6 +1440,12 @@
 		return (EINVAL);
 	}
 
+	if (addr_count < 0 || addr_count > 256 ) {
+		NLM_ERR("NLM:  too many service addresses (%d) given, "
+		    "max 256 - can't start server\n", addr_count);
+		return (EINVAL);
+	}
+
 	xprts = malloc(addr_count * sizeof(SVCXPRT *), M_NLM, M_WAITOK|M_ZERO);
 	for (i = 0; i < version_count; i++) {
 		for (j = 0; j < addr_count; j++) {
@@ -1526,51 +1538,51 @@
 	struct nlm_waiting_lock *nw;
 	vop_advlock_t *old_nfs_advlock;
 	vop_reclaim_t *old_nfs_reclaim;
-	int v4_used;
-#ifdef INET6
-	int v6_used;
-#endif
 
-	if (nlm_socket) {
+	if (nlm_is_running != 0) {
 		NLM_ERR("NLM: can't start server - "
 		    "it appears to be running already\n");
 		return (EPERM);
 	}
 
-	memset(&opt, 0, sizeof(opt));
+	if (nlm_socket == NULL) {
+		memset(&opt, 0, sizeof(opt));
 
-	nlm_socket = NULL;
-	error = socreate(AF_INET, &nlm_socket, SOCK_DGRAM, 0,
-	    td->td_ucred, td);
-	if (error) {
-		NLM_ERR("NLM: can't create IPv4 socket - error %d\n", error);
-		return (error);
-	}
-	opt.sopt_dir = SOPT_SET;
-	opt.sopt_level = IPPROTO_IP;
-	opt.sopt_name = IP_PORTRANGE;
-	portlow = IP_PORTRANGE_LOW;
-	opt.sopt_val = &portlow;
-	opt.sopt_valsize = sizeof(portlow);
-	sosetopt(nlm_socket, &opt);
+		error = socreate(AF_INET, &nlm_socket, SOCK_DGRAM, 0,
+		    td->td_ucred, td);
+		if (error) {
+			NLM_ERR("NLM: can't create IPv4 socket - error %d\n",
+			    error);
+			return (error);
+		}
+		opt.sopt_dir = SOPT_SET;
+		opt.sopt_level = IPPROTO_IP;
+		opt.sopt_name = IP_PORTRANGE;
+		portlow = IP_PORTRANGE_LOW;
+		opt.sopt_val = &portlow;
+		opt.sopt_valsize = sizeof(portlow);
+		sosetopt(nlm_socket, &opt);
 
 #ifdef INET6
-	nlm_socket6 = NULL;
-	error = socreate(AF_INET6, &nlm_socket6, SOCK_DGRAM, 0,
-	    td->td_ucred, td);
-	if (error) {
-		NLM_ERR("NLM: can't create IPv6 socket - error %d\n", error);
-		goto out;
-		return (error);
+		nlm_socket6 = NULL;
+		error = socreate(AF_INET6, &nlm_socket6, SOCK_DGRAM, 0,
+		    td->td_ucred, td);
+		if (error) {
+			NLM_ERR("NLM: can't create IPv6 socket - error %d\n",
+			    error);
+			soclose(nlm_socket);
+			nlm_socket = NULL;
+			return (error);
+		}
+		opt.sopt_dir = SOPT_SET;
+		opt.sopt_level = IPPROTO_IPV6;
+		opt.sopt_name = IPV6_PORTRANGE;
+		portlow = IPV6_PORTRANGE_LOW;
+		opt.sopt_val = &portlow;
+		opt.sopt_valsize = sizeof(portlow);
+		sosetopt(nlm_socket6, &opt);
+#endif
 	}
-	opt.sopt_dir = SOPT_SET;
-	opt.sopt_level = IPPROTO_IPV6;
-	opt.sopt_name = IPV6_PORTRANGE;
-	portlow = IPV6_PORTRANGE_LOW;
-	opt.sopt_val = &portlow;
-	opt.sopt_valsize = sizeof(portlow);
-	sosetopt(nlm_socket6, &opt);
-#endif
 
 	nlm_auth = authunix_create(curthread->td_ucred);
 
@@ -1622,6 +1634,7 @@
 		error = EINVAL;
 		goto out;
 	}
+	nlm_is_running = 1;
 
 	NLM_DEBUG(1, "NLM: local NSM state is %d\n", smstat.state);
 	nlm_nsm_state = smstat.state;
@@ -1638,6 +1651,7 @@
 	nfs_reclaim_p = old_nfs_reclaim;
 
 out:
+	nlm_is_running = 0;
 	if (pool)
 		svcpool_destroy(pool);
 
@@ -1661,13 +1675,8 @@
 	 * nlm_hosts to the host (which may remove it from the list
 	 * and free it). After this phase, the only entries in the
 	 * nlm_host list should be from other threads performing
-	 * client lock requests. We arrange to defer closing the
-	 * sockets until the last RPC client handle is released.
+	 * client lock requests.
 	 */
-	v4_used = 0;
-#ifdef INET6
-	v6_used = 0;
-#endif
 	mtx_lock(&nlm_global_lock);
 	TAILQ_FOREACH(nw, &nlm_waiting_locks, nw_link) {
 		wakeup(nw);
@@ -1678,43 +1687,10 @@
 		nlm_host_release(host);
 		mtx_lock(&nlm_global_lock);
 	}
-	TAILQ_FOREACH_SAFE(host, &nlm_hosts, nh_link, nhost) {
-		mtx_lock(&host->nh_lock);
-		if (host->nh_srvrpc.nr_client
-		    || host->nh_clntrpc.nr_client) {
-			if (host->nh_addr.ss_family == AF_INET)
-				v4_used++;
-#ifdef INET6
-			if (host->nh_addr.ss_family == AF_INET6)
-				v6_used++;
-#endif
-			/*
-			 * Note that the rpc over udp code copes
-			 * correctly with the fact that a socket may
-			 * be used by many rpc handles.
-			 */
-			if (host->nh_srvrpc.nr_client)
-				CLNT_CONTROL(host->nh_srvrpc.nr_client,
-				    CLSET_FD_CLOSE, 0);
-			if (host->nh_clntrpc.nr_client)
-				CLNT_CONTROL(host->nh_clntrpc.nr_client,
-				    CLSET_FD_CLOSE, 0);
-		}
-		mtx_unlock(&host->nh_lock);
-	}
 	mtx_unlock(&nlm_global_lock);
 
 	AUTH_DESTROY(nlm_auth);
 
-	if (!v4_used)
-		soclose(nlm_socket);
-	nlm_socket = NULL;
-#ifdef INET6
-	if (!v6_used)
-		soclose(nlm_socket6);
-	nlm_socket6 = NULL;
-#endif
-
 	return (error);
 }
 
@@ -1769,7 +1745,6 @@
 struct vfs_state {
 	struct mount	*vs_mp;
 	struct vnode	*vs_vp;
-	int		vs_vfslocked;
 	int		vs_vnlocked;
 };
 
@@ -1786,7 +1761,6 @@
 	if (!vs->vs_mp) {
 		return (ESTALE);
 	}
-	vs->vs_vfslocked = VFS_LOCK_GIANT(vs->vs_mp);
 
 	/* accmode == 0 means don't check, since it is an unlock. */
 	if (accmode != 0) {
@@ -1862,7 +1836,6 @@
 	}
 	if (vs->vs_mp)
 		vfs_rel(vs->vs_mp);
-	VFS_UNLOCK_GIANT(vs->vs_vfslocked);
 }
 
 static nlm4_stats
@@ -2438,7 +2411,15 @@
 nfslockd_modevent(module_t mod, int type, void *data)
 {
 
-	return (0);
+	switch (type) {
+	case MOD_LOAD:
+		return (0);
+	case MOD_UNLOAD:
+		/* The NLM module cannot be safely unloaded. */
+		/* FALLTHROUGH */
+	default:
+		return (EOPNOTSUPP);
+	}
 }
 static moduledata_t nfslockd_mod = {
 	"nfslockd",



More information about the Midnightbsd-cvs mailing list