From owner-svn-src-head@FreeBSD.ORG Thu Apr 28 23:21:51 2011 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2914B106578E; Thu, 28 Apr 2011 23:21:51 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 15E648FC12; Thu, 28 Apr 2011 23:21:51 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p3SNLo2A072893; Thu, 28 Apr 2011 23:21:50 GMT (envelope-from rmacklem@svn.freebsd.org) Received: (from rmacklem@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p3SNLopx072891; Thu, 28 Apr 2011 23:21:50 GMT (envelope-from rmacklem@svn.freebsd.org) Message-Id: <201104282321.p3SNLopx072891@svn.freebsd.org> From: Rick Macklem Date: Thu, 28 Apr 2011 23:21:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r221190 - head/sys/fs/nfsclient X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Apr 2011 23:21:51 -0000 Author: rmacklem Date: Thu Apr 28 23:21:50 2011 New Revision: 221190 URL: http://svn.freebsd.org/changeset/base/221190 Log: 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. Tested by: Craig Rodrigues (for amd) MFC after: 2 weeks Modified: head/sys/fs/nfsclient/nfs_clvfsops.c Modified: head/sys/fs/nfsclient/nfs_clvfsops.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clvfsops.c Thu Apr 28 23:21:40 2011 (r221189) +++ head/sys/fs/nfsclient/nfs_clvfsops.c Thu Apr 28 23:21:50 2011 (r221190) @@ -708,7 +708,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", @@ -762,8 +762,9 @@ 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; + has_nfs_args_opt = 0; if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) { error = EINVAL; goto out; @@ -777,6 +778,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; @@ -993,27 +1013,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, &len); + if (error != 0) + goto out; + bzero(&hst[len], MNAMELEN - len); + 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)); @@ -1033,8 +1078,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;