Index: mountd.c
===================================================================
RCS file: /space2/ncvs/src/usr.sbin/mountd/mountd.c,v
retrieving revision 1.70
diff -u -p -r1.70 mountd.c
--- mountd.c	16 Oct 2002 16:04:50 -0000	1.70
+++ mountd.c	28 Nov 2002 18:03:48 -0000
@@ -211,6 +211,11 @@ int	xdr_fhs(XDR *, caddr_t);
 int	xdr_mlist(XDR *, caddr_t);
 void	terminate(int);
 
+static char *nmount_fs[] = {
+	"ext2fs",
+	NULL
+};
+
 struct exportlist *exphead;
 struct mountlist *mlhead;
 struct grouplist *grphead;
@@ -919,7 +924,9 @@ get_exportlist()
 	struct dirlist *dirhead;
 	struct statfs fsb, *fsp;
 	struct xucred anon;
-	char *cp, *endcp, *dirp, *hst, *usr, *dom, savedc;
+	struct iovec iov[6];
+	struct export_args ea;
+	char **fs, *cp, *endcp, *dirp, *hst, *usr, *dom, savedc;
 	int len, has_host, exflags, got_nondir, dirplen, num, i, netgrp;
 
 	dirp = NULL;
@@ -958,6 +965,31 @@ get_exportlist()
 			struct msdosfs_args da;
 			struct ntfs_args na;
 		} targs;
+		for (fs = nmount_fs; *fs != NULL; fs++) {
+			if (strcmp(*fs, fsp->f_fstypename) == 0) {
+				ea.ex_flags = MNT_DELEXPORT;
+				iov[0].iov_base = "fstype";
+				iov[0].iov_len = strlen(iov[0].iov_base) + 1;
+				iov[1].iov_base = fsp->f_fstypename;
+				iov[1].iov_len = strlen(iov[1].iov_base) + 1;
+				iov[2].iov_base = "fspath";
+				iov[2].iov_len = strlen(iov[2].iov_base) + 1;
+				iov[3].iov_base = fsp->f_mntonname;
+				iov[3].iov_len = strlen(iov[3].iov_base) + 1;
+				iov[4].iov_base = "export";
+				iov[4].iov_len = strlen(iov[4].iov_base) + 1;
+				iov[5].iov_base = &ea;
+				iov[5].iov_len = sizeof(ea);
+				if ((nmount(iov, 6,
+				    fsp->f_flags | MNT_UPDATE) < 0) &&
+				    errno != ENOENT)
+					syslog(LOG_ERR,
+					    "can't delete exports for %s: %m",
+					    fsp->f_mntonname);
+				fsp++;
+				continue;
+			}
+		}
 
 		if (!strcmp(fsp->f_fstypename, "ufs") ||
 		    !strcmp(fsp->f_fstypename, "msdosfs") ||
@@ -1745,9 +1777,10 @@ do_mount(ep, grp, exflags, anoncrp, dirp
 {
 	struct statfs fsb1;
 	struct addrinfo *ai;
-	struct export_args *eap;
-	char *cp = NULL;
-	int done;
+	struct export_args *eap, ea;
+	struct iovec iov[6];
+	char **fs, *cp = NULL;
+	int done, do_nmount, error;
 	char savedc = '\0';
 	union {
 		struct ufs_args ua;
@@ -1760,6 +1793,15 @@ do_mount(ep, grp, exflags, anoncrp, dirp
 	/* XXX, we assume that all xx_args look like ufs_args. */
 	args.ua.fspec = 0;
 	eap = &args.ua.export;
+	do_nmount = 0;
+
+	for (fs = nmount_fs; *fs != NULL; fs++) {
+		if (strcmp(*fs, fsb->f_fstypename) == 0) {
+			bzero(&ea, sizeof(ea));
+			eap = &ea;
+			do_nmount = 1;
+		}
+	}
 
 	eap->ex_flags = exflags;
 	eap->ex_anon = *anoncrp;
@@ -1784,10 +1826,10 @@ do_mount(ep, grp, exflags, anoncrp, dirp
 				goto skip;
 			eap->ex_addr =
 			    (struct sockaddr *)&grp->gr_ptr.gt_net.nt_net;
-			eap->ex_addrlen = args.ua.export.ex_addr->sa_len;
+			eap->ex_addrlen = eap->ex_addr->sa_len;
 			eap->ex_mask =
 			    (struct sockaddr *)&grp->gr_ptr.gt_net.nt_mask;
-			eap->ex_masklen = args.ua.export.ex_mask->sa_len;
+			eap->ex_masklen = eap->ex_mask->sa_len;
 			break;
 		case GT_DEFAULT:
 			eap->ex_addr = NULL;
@@ -1812,8 +1854,26 @@ do_mount(ep, grp, exflags, anoncrp, dirp
 		 * Also, needs to know how to export all types of local
 		 * exportable filesystems and not just "ufs".
 		 */
-		while (mount(fsb->f_fstypename, dirp,
-		    fsb->f_flags | MNT_UPDATE, (caddr_t)&args) < 0) {
+retry:
+		if (do_nmount) {
+			iov[0].iov_base = "fstype";
+			iov[0].iov_len = strlen(iov[0].iov_base) + 1;
+			iov[1].iov_base = fsb->f_fstypename;
+			iov[1].iov_len = strlen(iov[1].iov_base) + 1;
+			iov[2].iov_base = "fspath";
+			iov[2].iov_len = strlen(iov[2].iov_base) + 1;
+			iov[3].iov_base = dirp;
+			iov[3].iov_len = strlen(iov[3].iov_base) + 1;
+			iov[4].iov_base = "export";
+			iov[4].iov_len = strlen(iov[4].iov_base) + 1;
+			iov[5].iov_base = eap;
+			iov[5].iov_len = sizeof(*eap);
+			error = nmount(iov, 6, fsb->f_flags | MNT_UPDATE);
+		} else {
+			error = mount(fsb->f_fstypename, dirp,
+				    fsb->f_flags | MNT_UPDATE, &args);
+		}
+		if (error) {
 			if (cp)
 				*cp-- = savedc;
 			else
@@ -1859,6 +1919,7 @@ do_mount(ep, grp, exflags, anoncrp, dirp
 				syslog(LOG_ERR, "can't export %s", dirp);
 				return (1);
 			}
+			goto retry;
 		}
 skip:
 		if (ai != NULL)
