Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 15 May 2011 00:43:51 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r221935 - stable/8/sys/fs/nfsclient
Message-ID:  <201105150043.p4F0hpVv020894@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Sun May 15 00:43:51 2011
New Revision: 221935
URL: http://svn.freebsd.org/changeset/base/221935

Log:
  MFC: r221190,r221205
  Fix the new NFS client so that it handles the "nfs_args" value
  in mnt_optnew. This is needed so that the old mount(2) syscall
  works and that is needed so that amd(8) works. The code was
  basically just cribbed from sys/nfsclient/nfs_vfsops.c with minor
  changes. This patch is mainly to fix the new NFS client so that
  amd(8) works with it. Thanks go to Craig Rodrigues for helping with
  this.

Modified:
  stable/8/sys/fs/nfsclient/nfs_clvfsops.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/fs/nfsclient/nfs_clvfsops.c
==============================================================================
--- stable/8/sys/fs/nfsclient/nfs_clvfsops.c	Sun May 15 00:25:19 2011	(r221934)
+++ stable/8/sys/fs/nfsclient/nfs_clvfsops.c	Sun May 15 00:43:51 2011	(r221935)
@@ -702,7 +702,7 @@ nfs_decode_args(struct mount *mp, struct
 	}
 }
 
-static const char *nfs_opts[] = { "from",
+static const char *nfs_opts[] = { "from", "nfs_args",
     "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
     "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
     "async", "noconn", "nolockd", "conn", "lockd", "intr", "rdirplus",
@@ -756,8 +756,10 @@ nfs_mount(struct mount *mp)
 	u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100];
 	char *opt, *name, *secname;
 	int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;
-	int dirlen, krbnamelen, srvkrbnamelen;
+	int dirlen, has_nfs_args_opt, krbnamelen, srvkrbnamelen;
+	size_t hstlen;
 
+	has_nfs_args_opt = 0;
 	if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
 		error = EINVAL;
 		goto out;
@@ -771,6 +773,25 @@ nfs_mount(struct mount *mp)
 
 	nfscl_init();
 
+	/*
+	 * The old mount_nfs program passed the struct nfs_args
+	 * from userspace to kernel.  The new mount_nfs program
+	 * passes string options via nmount() from userspace to kernel
+	 * and we populate the struct nfs_args in the kernel.
+	 */
+	if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
+		error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
+		    sizeof(args));
+		if (error != 0)
+			goto out;
+
+		if (args.version != NFS_ARGSVERSION) {
+			error = EPROGMISMATCH;
+			goto out;
+		}
+		has_nfs_args_opt = 1;
+	}
+
 	/* Handle the new style options. */
 	if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
 		args.flags |= NFSMNT_NOCONN;
@@ -989,27 +1010,52 @@ nfs_mount(struct mount *mp)
 	if (nfs_ip_paranoia == 0)
 		args.flags |= NFSMNT_NOCONN;
 
-	if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
-	    &args.fhsize) == 0) {
-		if (args.fhsize < 0 || args.fhsize > NFSX_FHMAX) {
+	if (has_nfs_args_opt != 0) {
+		/*
+		 * In the 'nfs_args' case, the pointers in the args
+		 * structure are in userland - we copy them in here.
+		 */
+		if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) {
 			vfs_mount_error(mp, "Bad file handle");
 			error = EINVAL;
 			goto out;
 		}
-		bcopy(args.fh, nfh, args.fhsize);
+		error = copyin((caddr_t)args.fh, (caddr_t)nfh,
+		    args.fhsize);
+		if (error != 0)
+			goto out;
+		error = copyinstr(args.hostname, hst, MNAMELEN - 1, &hstlen);
+		if (error != 0)
+			goto out;
+		bzero(&hst[hstlen], MNAMELEN - hstlen);
+		args.hostname = hst;
+		/* sockargs() call must be after above copyin() calls */
+		error = getsockaddr(&nam, (caddr_t)args.addr,
+		    args.addrlen);
+		if (error != 0)
+			goto out;
 	} else {
-		args.fhsize = 0;
-	}
-
-	(void) vfs_getopt(mp->mnt_optnew, "hostname", (void **)&args.hostname,
-	    &len);
-	if (args.hostname == NULL) {
-		vfs_mount_error(mp, "Invalid hostname");
-		error = EINVAL;
-		goto out;
+		if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
+		    &args.fhsize) == 0) {
+			if (args.fhsize < 0 || args.fhsize > NFSX_FHMAX) {
+				vfs_mount_error(mp, "Bad file handle");
+				error = EINVAL;
+				goto out;
+			}
+			bcopy(args.fh, nfh, args.fhsize);
+		} else {
+			args.fhsize = 0;
+		}
+		(void) vfs_getopt(mp->mnt_optnew, "hostname",
+		    (void **)&args.hostname, &len);
+		if (args.hostname == NULL) {
+			vfs_mount_error(mp, "Invalid hostname");
+			error = EINVAL;
+			goto out;
+		}
+		bcopy(args.hostname, hst, MNAMELEN);
+		hst[MNAMELEN - 1] = '\0';
 	}
-	bcopy(args.hostname, hst, MNAMELEN);
-	hst[MNAMELEN - 1] = '\0';
 
 	if (vfs_getopt(mp->mnt_optnew, "principal", (void **)&name, NULL) == 0)
 		strlcpy(srvkrbname, name, sizeof (srvkrbname));
@@ -1029,8 +1075,8 @@ nfs_mount(struct mount *mp)
 		dirpath[0] = '\0';
 	dirlen = strlen(dirpath);
 
-	if (vfs_getopt(mp->mnt_optnew, "addr", (void **)&args.addr,
-	    &args.addrlen) == 0) {
+	if (has_nfs_args_opt == 0 && vfs_getopt(mp->mnt_optnew, "addr",
+	    (void **)&args.addr, &args.addrlen) == 0) {
 		if (args.addrlen > SOCK_MAXADDRLEN) {
 			error = ENAMETOOLONG;
 			goto out;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105150043.p4F0hpVv020894>