svn commit: r278523 - in head: sys/kern usr.sbin/mountd

Konstantin Belousov kib at FreeBSD.org
Tue Feb 10 18:00:33 UTC 2015


Author: kib
Date: Tue Feb 10 18:00:32 2015
New Revision: 278523
URL: https://svnweb.freebsd.org/changeset/base/278523

Log:
  Mountd iterating over the mount points may race with the parallel
  unmount, which causes error from nmount(2) call when performing
  MNT_DELEXPORT over the directory which ceased to be a mount point.
  
  The race is legitimate and innocent, but results in the chatty mountd.
  Silence it by providing an distinguished error code for the situation,
  and ignoring the error in mountd loop.
  
  Based on the patch by:	Andreas Longwitz <longwitz at incore.de>
  Prodded and tested by:	bdrewery
  Sponsored by:	The FreeBSD Foundation
  MFC after:	2 weeks

Modified:
  head/sys/kern/vfs_mount.c
  head/usr.sbin/mountd/mountd.c

Modified: head/sys/kern/vfs_mount.c
==============================================================================
--- head/sys/kern/vfs_mount.c	Tue Feb 10 16:34:42 2015	(r278522)
+++ head/sys/kern/vfs_mount.c	Tue Feb 10 18:00:32 2015	(r278523)
@@ -888,12 +888,18 @@ vfs_domount_update(
 
 	ASSERT_VOP_ELOCKED(vp, __func__);
 	KASSERT((fsflags & MNT_UPDATE) != 0, ("MNT_UPDATE should be here"));
+	mp = vp->v_mount;
 
 	if ((vp->v_vflag & VV_ROOT) == 0) {
+		if (vfs_copyopt(*optlist, "export", &export, sizeof(export))
+		    == 0)
+			error = EXDEV;
+		else
+			error = EINVAL;
 		vput(vp);
-		return (EINVAL);
+		return (error);
 	}
-	mp = vp->v_mount;
+
 	/*
 	 * We only allow the filesystem to be reloaded if it
 	 * is currently mounted read-only.

Modified: head/usr.sbin/mountd/mountd.c
==============================================================================
--- head/usr.sbin/mountd/mountd.c	Tue Feb 10 16:34:42 2015	(r278522)
+++ head/usr.sbin/mountd/mountd.c	Tue Feb 10 18:00:32 2015	(r278523)
@@ -1747,8 +1747,12 @@ get_exportlist(void)
 		iov[5].iov_len = strlen(fsp->f_mntfromname) + 1;
 		errmsg[0] = '\0';
 
+		/*
+		 * EXDEV is returned when path exists but is not a
+		 * mount point.  May happens if raced with unmount.
+		 */
 		if (nmount(iov, iovlen, fsp->f_flags) < 0 &&
-		    errno != ENOENT && errno != ENOTSUP) {
+		    errno != ENOENT && errno != ENOTSUP && errno != EXDEV) {
 			syslog(LOG_ERR,
 			    "can't delete exports for %s: %m %s",
 			    fsp->f_mntonname, errmsg);


More information about the svn-src-all mailing list