Module Name:    src
Committed By:   mrg
Date:           Mon Jun 22 10:35:00 UTC 2015

Modified Files:
        src/sys/compat/netbsd32: files.netbsd32 netbsd32.h netbsd32_conv.h
            netbsd32_syscall.h netbsd32_syscallargs.h netbsd32_syscalls.c
            netbsd32_sysent.c netbsd32_systrace_args.c syscalls.master
        src/sys/nfs: nfs_syscalls.c nfs_var.h
Added Files:
        src/sys/compat/netbsd32: netbsd32_nfssvc.c

Log Message:
add netbsd32 support for nfssvc(2).  we do this by defining 5 copyin/out
functions that do all the ugly work, are just plain copyin/out for the
native system calls, and do the necessary translations for netbsd32.

with this i'm able to run 32 bit nfsd and mountd on 64 bit kernel and
mount the file systems remotely.


To generate a diff of this commit:
cvs rdiff -u -r1.35 -r1.36 src/sys/compat/netbsd32/files.netbsd32
cvs rdiff -u -r1.106 -r1.107 src/sys/compat/netbsd32/netbsd32.h
cvs rdiff -u -r1.29 -r1.30 src/sys/compat/netbsd32/netbsd32_conv.h
cvs rdiff -u -r0 -r1.1 src/sys/compat/netbsd32/netbsd32_nfssvc.c
cvs rdiff -u -r1.115 -r1.116 src/sys/compat/netbsd32/netbsd32_syscall.h \
    src/sys/compat/netbsd32/netbsd32_syscallargs.h
cvs rdiff -u -r1.114 -r1.115 src/sys/compat/netbsd32/netbsd32_syscalls.c \
    src/sys/compat/netbsd32/netbsd32_sysent.c
cvs rdiff -u -r1.5 -r1.6 src/sys/compat/netbsd32/netbsd32_systrace_args.c
cvs rdiff -u -r1.107 -r1.108 src/sys/compat/netbsd32/syscalls.master
cvs rdiff -u -r1.155 -r1.156 src/sys/nfs/nfs_syscalls.c
cvs rdiff -u -r1.92 -r1.93 src/sys/nfs/nfs_var.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/compat/netbsd32/files.netbsd32
diff -u src/sys/compat/netbsd32/files.netbsd32:1.35 src/sys/compat/netbsd32/files.netbsd32:1.36
--- src/sys/compat/netbsd32/files.netbsd32:1.35	Sat Jun 20 19:58:40 2015
+++ src/sys/compat/netbsd32/files.netbsd32	Mon Jun 22 10:35:00 2015
@@ -1,4 +1,4 @@
-#	$NetBSD: files.netbsd32,v 1.35 2015/06/20 19:58:40 martin Exp $
+#	$NetBSD: files.netbsd32,v 1.36 2015/06/22 10:35:00 mrg Exp $
 #
 # config file description for machine-independent netbsd32 compat code.
 # included by ports that need it.
@@ -20,6 +20,7 @@ file	compat/netbsd32/netbsd32_lwp.c		com
 file	compat/netbsd32/netbsd32_module.c	compat_netbsd32
 file	compat/netbsd32/netbsd32_mod.c		compat_netbsd32
 file	compat/netbsd32/netbsd32_mqueue.c	compat_netbsd32
+file	compat/netbsd32/netbsd32_nfssvc.c	compat_netbsd32 & nfsserver
 file	compat/netbsd32/netbsd32_select.c	compat_netbsd32
 file	compat/netbsd32/netbsd32_sem.c		compat_netbsd32
 file	compat/netbsd32/netbsd32_signal.c	compat_netbsd32

Index: src/sys/compat/netbsd32/netbsd32.h
diff -u src/sys/compat/netbsd32/netbsd32.h:1.106 src/sys/compat/netbsd32/netbsd32.h:1.107
--- src/sys/compat/netbsd32/netbsd32.h:1.106	Sun Jun 21 14:03:38 2015
+++ src/sys/compat/netbsd32/netbsd32.h	Mon Jun 22 10:35:00 2015
@@ -1,7 +1,7 @@
-/*	$NetBSD: netbsd32.h,v 1.106 2015/06/21 14:03:38 mrg Exp $	*/
+/*	$NetBSD: netbsd32.h,v 1.107 2015/06/22 10:35:00 mrg Exp $	*/
 
 /*
- * Copyright (c) 1998, 2001, 2008 Matthew R. Green
+ * Copyright (c) 1998, 2001, 2008, 2015 Matthew R. Green
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -50,6 +50,8 @@
 #include <compat/sys/mount.h>
 #include <compat/sys/signal.h>
 
+#include <nfs/rpcv2.h>
+
 /*
  * first, define the basic types we need.
  */
@@ -945,6 +947,48 @@ struct netbsd32_mfs_args {
 	netbsd32_u_long		size;
 };
 
+/* from <nfs/nfs.h> */
+struct netbsd32_nfsd_args {
+	int		sock;
+	netbsd32_voidp	name;
+	int		namelen;
+};
+
+typedef netbsd32_pointer_t netbsd32_nfsdp;
+struct netbsd32_nfsd_srvargs {
+	netbsd32_nfsdp	nsd_nfsd;
+	uid_t		nsd_uid;
+	u_int32_t	nsd_haddr;
+	struct uucred	nsd_cr;
+	int		nsd_authlen;
+	netbsd32_u_charp nsd_authstr;
+	int		nsd_verflen;
+	netbsd32_u_charp nsd_verfstr;
+	struct netbsd32_timeval	nsd_timestamp;
+	u_int32_t	nsd_ttl;
+	NFSKERBKEY_T	nsd_key;
+};
+
+typedef netbsd32_pointer_t netbsd32_export_argsp;
+struct netbsd32_export_args {
+	int		ex_flags;
+	uid_t		ex_root;
+	struct uucred	ex_anon;
+	netbsd32_sockaddrp_t ex_addr;
+	int		ex_addrlen;
+	netbsd32_sockaddrp_t ex_mask;
+	int		ex_masklen;
+	netbsd32_charp	ex_indexfile;
+};
+
+struct netbsd32_mountd_exports_list {
+	const netbsd32_charp	mel_path;
+	netbsd32_size_t		mel_nexports;
+	netbsd32_export_argsp	mel_exports;
+};
+
+/* no struct export_args30 yet */
+
 /* from <nfs/nfsmount,h> */
 struct netbsd32_nfs_args {
 	int32_t		version;	/* args structure version number */
@@ -966,6 +1010,8 @@ struct netbsd32_nfs_args {
 	int32_t		deadthresh;	/* Retrans threshold */
 	netbsd32_charp	hostname;	/* server's name */
 };
+
+/* from <msdosfs/msdosfsmount.h> */
 struct netbsd32_msdosfs_args {
 	netbsd32_charp	fspec;		/* blocks special holding the fs to mount */
 	struct	netbsd32_export_args30 _pad1; /* compat with old userland tools */

Index: src/sys/compat/netbsd32/netbsd32_conv.h
diff -u src/sys/compat/netbsd32/netbsd32_conv.h:1.29 src/sys/compat/netbsd32/netbsd32_conv.h:1.30
--- src/sys/compat/netbsd32/netbsd32_conv.h:1.29	Sat Jun 20 19:58:40 2015
+++ src/sys/compat/netbsd32/netbsd32_conv.h	Mon Jun 22 10:35:00 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: netbsd32_conv.h,v 1.29 2015/06/20 19:58:40 martin Exp $	*/
+/*	$NetBSD: netbsd32_conv.h,v 1.30 2015/06/22 10:35:00 mrg Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Matthew R. Green
@@ -39,6 +39,7 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/dirent.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
 #define msg __msg /* Don't ask me! */

Index: src/sys/compat/netbsd32/netbsd32_syscall.h
diff -u src/sys/compat/netbsd32/netbsd32_syscall.h:1.115 src/sys/compat/netbsd32/netbsd32_syscall.h:1.116
--- src/sys/compat/netbsd32/netbsd32_syscall.h:1.115	Sun Jun 21 12:52:40 2015
+++ src/sys/compat/netbsd32/netbsd32_syscall.h	Mon Jun 22 10:35:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_syscall.h,v 1.115 2015/06/21 12:52:40 martin Exp $ */
+/* $NetBSD: netbsd32_syscall.h,v 1.116 2015/06/22 10:35:00 mrg Exp $ */
 
 /*
  * System call numbers.
@@ -441,6 +441,9 @@
 /* syscall: "compat_43_netbsd32_ogetsockname" ret: "int" args: "int" "netbsd32_voidp" "netbsd32_intp" */
 #define	NETBSD32_SYS_compat_43_netbsd32_ogetsockname	150
 
+/* syscall: "netbsd32_nfssvc" ret: "int" args: "int" "netbsd32_voidp" */
+#define	NETBSD32_SYS_netbsd32_nfssvc	155
+
 /* syscall: "compat_43_netbsd32_ogetdirentries" ret: "int" args: "int" "netbsd32_charp" "u_int" "netbsd32_longp" */
 #define	NETBSD32_SYS_compat_43_netbsd32_ogetdirentries	156
 
Index: src/sys/compat/netbsd32/netbsd32_syscallargs.h
diff -u src/sys/compat/netbsd32/netbsd32_syscallargs.h:1.115 src/sys/compat/netbsd32/netbsd32_syscallargs.h:1.116
--- src/sys/compat/netbsd32/netbsd32_syscallargs.h:1.115	Sun Jun 21 12:52:40 2015
+++ src/sys/compat/netbsd32/netbsd32_syscallargs.h	Mon Jun 22 10:35:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_syscallargs.h,v 1.115 2015/06/21 12:52:40 martin Exp $ */
+/* $NetBSD: netbsd32_syscallargs.h,v 1.116 2015/06/22 10:35:00 mrg Exp $ */
 
 /*
  * System call argument lists.
@@ -816,6 +816,12 @@ struct compat_43_netbsd32_ogetsockname_a
 };
 check_syscall_args(compat_43_netbsd32_ogetsockname)
 
+struct netbsd32_nfssvc_args {
+	syscallarg(int) flag;
+	syscallarg(netbsd32_voidp) argp;
+};
+check_syscall_args(netbsd32_nfssvc)
+
 struct compat_43_netbsd32_ogetdirentries_args {
 	syscallarg(int) fd;
 	syscallarg(netbsd32_charp) buf;
@@ -2892,6 +2898,8 @@ int	compat_43_sys_quota(struct lwp *, co
 
 int	compat_43_netbsd32_ogetsockname(struct lwp *, const struct compat_43_netbsd32_ogetsockname_args *, register_t *);
 
+int	netbsd32_nfssvc(struct lwp *, const struct netbsd32_nfssvc_args *, register_t *);
+
 int	compat_43_netbsd32_ogetdirentries(struct lwp *, const struct compat_43_netbsd32_ogetdirentries_args *, register_t *);
 
 int	compat_20_netbsd32_statfs(struct lwp *, const struct compat_20_netbsd32_statfs_args *, register_t *);

Index: src/sys/compat/netbsd32/netbsd32_syscalls.c
diff -u src/sys/compat/netbsd32/netbsd32_syscalls.c:1.114 src/sys/compat/netbsd32/netbsd32_syscalls.c:1.115
--- src/sys/compat/netbsd32/netbsd32_syscalls.c:1.114	Sun Jun 21 12:52:40 2015
+++ src/sys/compat/netbsd32/netbsd32_syscalls.c	Mon Jun 22 10:35:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_syscalls.c,v 1.114 2015/06/21 12:52:40 martin Exp $ */
+/* $NetBSD: netbsd32_syscalls.c,v 1.115 2015/06/22 10:35:00 mrg Exp $ */
 
 /*
  * System call names.
@@ -8,7 +8,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_syscalls.c,v 1.114 2015/06/21 12:52:40 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_syscalls.c,v 1.115 2015/06/22 10:35:00 mrg Exp $");
 
 #if defined(_KERNEL_OPT)
 #if defined(_KERNEL_OPT)
@@ -182,7 +182,7 @@ const char *const netbsd32_syscallnames[
 	/* 152 */	"#152 (unimplemented)",
 	/* 153 */	"#153 (unimplemented)",
 	/* 154 */	"#154 (unimplemented)",
-	/* 155 */	"#155 (unimplemented netbsd32_nfssvc)",
+	/* 155 */	"netbsd32_nfssvc",
 	/* 156 */	"compat_43_netbsd32_ogetdirentries",
 	/* 157 */	"compat_20_netbsd32_statfs",
 	/* 158 */	"compat_20_netbsd32_fstatfs",
Index: src/sys/compat/netbsd32/netbsd32_sysent.c
diff -u src/sys/compat/netbsd32/netbsd32_sysent.c:1.114 src/sys/compat/netbsd32/netbsd32_sysent.c:1.115
--- src/sys/compat/netbsd32/netbsd32_sysent.c:1.114	Sun Jun 21 12:52:40 2015
+++ src/sys/compat/netbsd32/netbsd32_sysent.c	Mon Jun 22 10:35:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_sysent.c,v 1.114 2015/06/21 12:52:40 martin Exp $ */
+/* $NetBSD: netbsd32_sysent.c,v 1.115 2015/06/22 10:35:00 mrg Exp $ */
 
 /*
  * System call switch table.
@@ -8,7 +8,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_sysent.c,v 1.114 2015/06/21 12:52:40 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_sysent.c,v 1.115 2015/06/22 10:35:00 mrg Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -708,8 +708,9 @@ struct sysent netbsd32_sysent[] = {
 		.sy_call = sys_nosys,
 	},		/* 154 = filler */
 	{
-		.sy_call = sys_nosys,
-	},		/* 155 = filler */
+		ns(struct netbsd32_nfssvc_args),
+		.sy_call = (sy_call_t *)netbsd32_nfssvc
+	},		/* 155 = netbsd32_nfssvc */
 	{
 		ns(struct compat_43_netbsd32_ogetdirentries_args),
 		.sy_call = (sy_call_t *)compat_43(netbsd32_ogetdirentries)

Index: src/sys/compat/netbsd32/netbsd32_systrace_args.c
diff -u src/sys/compat/netbsd32/netbsd32_systrace_args.c:1.5 src/sys/compat/netbsd32/netbsd32_systrace_args.c:1.6
--- src/sys/compat/netbsd32/netbsd32_systrace_args.c:1.5	Sun Jun 21 12:52:40 2015
+++ src/sys/compat/netbsd32/netbsd32_systrace_args.c	Mon Jun 22 10:35:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_systrace_args.c,v 1.5 2015/06/21 12:52:40 martin Exp $ */
+/* $NetBSD: netbsd32_systrace_args.c,v 1.6 2015/06/22 10:35:00 mrg Exp $ */
 
 /*
  * System call argument to DTrace register array converstion.
@@ -1132,6 +1132,14 @@ systrace_args(register_t sysnum, const v
 		*n_args = 3;
 		break;
 	}
+	/* netbsd32_nfssvc */
+	case 155: {
+		struct netbsd32_nfssvc_args *p = params;
+		iarg[0] = SCARG(p, flag); /* int */
+		uarg[1] = (intptr_t) SCARG(p, argp).i32; /* netbsd32_voidp */
+		*n_args = 2;
+		break;
+	}
 	/* netbsd32_ogetdirentries */
 	case 156: {
 		struct compat_43_netbsd32_ogetdirentries_args *p = params;
@@ -5283,6 +5291,19 @@ systrace_entry_setargdesc(int sysnum, in
 			break;
 		};
 		break;
+	/* netbsd32_nfssvc */
+	case 155:
+		switch(ndx) {
+		case 0:
+			p = "int";
+			break;
+		case 1:
+			p = "netbsd32_voidp";
+			break;
+		default:
+			break;
+		};
+		break;
 	/* netbsd32_ogetdirentries */
 	case 156:
 		switch(ndx) {
@@ -9988,6 +10009,11 @@ systrace_return_setargdesc(int sysnum, i
 		if (ndx == 0 || ndx == 1)
 			p = "int";
 		break;
+	/* netbsd32_nfssvc */
+	case 155:
+		if (ndx == 0 || ndx == 1)
+			p = "int";
+		break;
 	/* netbsd32_ogetdirentries */
 	case 156:
 		if (ndx == 0 || ndx == 1)

Index: src/sys/compat/netbsd32/syscalls.master
diff -u src/sys/compat/netbsd32/syscalls.master:1.107 src/sys/compat/netbsd32/syscalls.master:1.108
--- src/sys/compat/netbsd32/syscalls.master:1.107	Sun Jun 21 12:51:33 2015
+++ src/sys/compat/netbsd32/syscalls.master	Mon Jun 22 10:35:00 2015
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.107 2015/06/21 12:51:33 martin Exp $
+	$NetBSD: syscalls.master,v 1.108 2015/06/22 10:35:00 mrg Exp $
 
 ;	from: NetBSD: syscalls.master,v 1.81 1998/07/05 08:49:50 jonathan Exp
 ;	@(#)syscalls.master	8.2 (Berkeley) 1/13/94
@@ -317,7 +317,7 @@
 152	UNIMPL
 153	UNIMPL
 154	UNIMPL
-155	UNIMPL		netbsd32_nfssvc
+155	STD		{ int|netbsd32||nfssvc(int flag, netbsd32_voidp argp); }
 156	COMPAT_43	{ int|netbsd32||ogetdirentries(int fd, \
 			    netbsd32_charp buf, u_int count, \
 			    netbsd32_longp basep); }

Index: src/sys/nfs/nfs_syscalls.c
diff -u src/sys/nfs/nfs_syscalls.c:1.155 src/sys/nfs/nfs_syscalls.c:1.156
--- src/sys/nfs/nfs_syscalls.c:1.155	Fri Sep  5 09:22:30 2014
+++ src/sys/nfs/nfs_syscalls.c	Mon Jun 22 10:35:00 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: nfs_syscalls.c,v 1.155 2014/09/05 09:22:30 matt Exp $	*/
+/*	$NetBSD: nfs_syscalls.c,v 1.156 2015/06/22 10:35:00 mrg Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_syscalls.c,v 1.155 2014/09/05 09:22:30 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_syscalls.c,v 1.156 2015/06/22 10:35:00 mrg Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -99,11 +99,61 @@ struct nfssvc_sock *nfs_udp6sock;
 static struct nfssvc_sock *nfsrv_sockalloc(void);
 static void nfsrv_sockfree(struct nfssvc_sock *);
 static void nfsd_rt(int, struct nfsrv_descript *, int);
+static int nfssvc_nfsd(struct nfssvc_copy_ops *, struct nfsd_srvargs *, void *,
+		struct lwp *);
+
+static int nfssvc_addsock_in(struct nfsd_args *, const void *);
+static int nfssvc_setexports_in(struct mountd_exports_list *, const void *);
+static int nfssvc_nsd_in(struct nfsd_srvargs *, const void *);
+static int nfssvc_nsd_out(void *, const struct nfsd_srvargs *);
+static int nfssvc_exp_in(struct export_args *, const void *, size_t);
+
+static int
+nfssvc_addsock_in(struct nfsd_args *nfsdarg, const void *argp)
+{
+
+	return copyin(argp, nfsdarg, sizeof *nfsdarg);
+}
+
+static int
+nfssvc_setexports_in(struct mountd_exports_list *mel, const void *argp)
+{
+
+	return copyin(argp, mel, sizeof *mel);
+}
+
+static int
+nfssvc_nsd_in(struct nfsd_srvargs *nsd, const void *argp)
+{
+
+	return copyin(argp, nsd, sizeof *nsd);
+}
+
+static int
+nfssvc_nsd_out(void *argp, const struct nfsd_srvargs *nsd)
+{
+
+	return copyout(nsd, argp, sizeof *nsd);
+}
+
+static int
+nfssvc_exp_in(struct export_args *exp, const void *argp, size_t nexports)
+{
+
+	return copyin(argp, exp, sizeof(*exp) * nexports);
+}
 
 /*
  * NFS server system calls
  */
 
+static struct nfssvc_copy_ops native_ops = {
+	.addsock_in = nfssvc_addsock_in,
+	.setexports_in = nfssvc_setexports_in,
+	.nsd_in = nfssvc_nsd_in,
+	.nsd_out = nfssvc_nsd_out,
+	.exp_in = nfssvc_exp_in,
+};
 
 /*
  * Nfs server pseudo system call for the nfsd's
@@ -112,6 +162,7 @@ static void nfsd_rt(int, struct nfsrv_de
  * - remains in the kernel as an nfsd
  * - remains in the kernel as an nfsiod
  */
+
 int
 sys_nfssvc(struct lwp *l, const struct sys_nfssvc_args *uap, register_t *retval)
 {
@@ -119,6 +170,15 @@ sys_nfssvc(struct lwp *l, const struct s
 		syscallarg(int) flag;
 		syscallarg(void *) argp;
 	} */
+	int	flag = SCARG(uap, flag);
+	void	*argp = SCARG(uap, argp);
+
+	return do_nfssvc(&native_ops, l, flag, argp, retval);
+}
+
+int
+do_nfssvc(struct nfssvc_copy_ops *ops, struct lwp *l, int flag, void *argp, register_t *retval)
+{
 	int error;
 	file_t *fp;
 	struct mbuf *nam;
@@ -139,14 +199,13 @@ sys_nfssvc(struct lwp *l, const struct s
 	}
 	mutex_exit(&nfsd_lock);
 
-	if (SCARG(uap, flag) & NFSSVC_BIOD) {
+	if (flag & NFSSVC_BIOD) {
 		/* Dummy implementation of nfsios for 1.4 and earlier. */
 		error = kpause("nfsbiod", true, 0, NULL);
-	} else if (SCARG(uap, flag) & NFSSVC_MNTD) {
+	} else if (flag & NFSSVC_MNTD) {
 		error = ENOSYS;
-	} else if (SCARG(uap, flag) & NFSSVC_ADDSOCK) {
-		error = copyin(SCARG(uap, argp), (void *)&nfsdarg,
-		    sizeof(nfsdarg));
+	} else if (flag & NFSSVC_ADDSOCK) {
+		error = ops->addsock_in(&nfsdarg, argp);
 		if (error)
 			return (error);
 		/* getsock() will use the descriptor for us */
@@ -171,18 +230,17 @@ sys_nfssvc(struct lwp *l, const struct s
 		}
 		error = nfssvc_addsock(fp, nam);
 		fd_putfile(nfsdarg.sock);
-	} else if (SCARG(uap, flag) & NFSSVC_SETEXPORTSLIST) {
+	} else if (flag & NFSSVC_SETEXPORTSLIST) {
 		struct export_args *args;
 		struct mountd_exports_list mel;
 
-		error = copyin(SCARG(uap, argp), &mel, sizeof(mel));
+		error = ops->setexports_in(&mel, argp);
 		if (error != 0)
 			return error;
 
 		args = (struct export_args *)malloc(mel.mel_nexports *
 		    sizeof(struct export_args), M_TEMP, M_WAITOK);
-		error = copyin(mel.mel_exports, args, mel.mel_nexports *
-		    sizeof(struct export_args));
+		error = ops->exp_in(args, mel.mel_exports, mel.mel_nexports);
 		if (error != 0) {
 			free(args, M_TEMP);
 			return error;
@@ -193,10 +251,10 @@ sys_nfssvc(struct lwp *l, const struct s
 
 		free(args, M_TEMP);
 	} else {
-		error = copyin(SCARG(uap, argp), (void *)nsd, sizeof (*nsd));
+		error = ops->nsd_in(nsd, argp);
 		if (error)
 			return (error);
-		if ((SCARG(uap, flag) & NFSSVC_AUTHIN) &&
+		if ((flag & NFSSVC_AUTHIN) &&
 		    ((nfsd = nsd->nsd_nfsd)) != NULL &&
 		    (nfsd->nfsd_slp->ns_flags & SLP_VALID)) {
 			slp = nfsd->nfsd_slp;
@@ -280,10 +338,10 @@ sys_nfssvc(struct lwp *l, const struct s
 			    }
 			}
 		}
-		if ((SCARG(uap, flag) & NFSSVC_AUTHINFAIL) &&
+		if ((flag & NFSSVC_AUTHINFAIL) &&
 		    (nfsd = nsd->nsd_nfsd))
 			nfsd->nfsd_flag |= NFSD_AUTHFAIL;
-		error = nfssvc_nfsd(nsd, SCARG(uap, argp), l);
+		error = nfssvc_nfsd(ops, nsd, argp, l);
 	}
 	if (error == EINTR || error == ERESTART)
 		error = 0;
@@ -415,8 +473,9 @@ nfssvc_addsock(file_t *fp, struct mbuf *
  * Called by nfssvc() for nfsds. Just loops around servicing rpc requests
  * until it is killed by a signal.
  */
-int
-nfssvc_nfsd(struct nfsd_srvargs *nsd, void *argp, struct lwp *l)
+static int
+nfssvc_nfsd(struct nfssvc_copy_ops *ops, struct nfsd_srvargs *nsd,
+	    void *argp, struct lwp *l)
 {
 	struct timeval tv;
 	struct mbuf *m;
@@ -564,7 +623,7 @@ nfssvc_nfsd(struct nfsd_srvargs *nsd, vo
 				    nsd->nsd_authstr, nfsd->nfsd_authlen) &&
 				    !copyout(nfsd->nfsd_verfstr,
 				    nsd->nsd_verfstr, nfsd->nfsd_verflen) &&
-				    !copyout(nsd, argp, sizeof (*nsd))) {
+				    !ops->nsd_out(argp, nsd)) {
 					return (ENEEDAUTH);
 				}
 				cacherep = RC_DROPIT;

Index: src/sys/nfs/nfs_var.h
diff -u src/sys/nfs/nfs_var.h:1.92 src/sys/nfs/nfs_var.h:1.93
--- src/sys/nfs/nfs_var.h:1.92	Fri May 30 08:47:45 2014
+++ src/sys/nfs/nfs_var.h	Mon Jun 22 10:35:00 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: nfs_var.h,v 1.92 2014/05/30 08:47:45 hannken Exp $	*/
+/*	$NetBSD: nfs_var.h,v 1.93 2015/06/22 10:35:00 mrg Exp $	*/
 
 /*-
  * Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -323,7 +323,6 @@ struct sys_nfssvc_args;
 int sys_getfh(struct lwp *, const struct sys_getfh_args *, register_t *);
 int sys_nfssvc(struct lwp *, const struct sys_nfssvc_args *, register_t *);
 int nfssvc_addsock(struct file *, struct mbuf *);
-int nfssvc_nfsd(struct nfsd_srvargs *, void *, struct lwp *);
 void nfsrv_zapsock(struct nfssvc_sock *);
 void nfsrv_slpderef(struct nfssvc_sock *);
 void nfsrv_init(int);
@@ -337,6 +336,21 @@ int nfs_getnickauth(struct nfsmount *, k
 	int);
 int nfs_savenickauth(struct nfsmount *, kauth_cred_t, int, NFSKERBKEY_T,
 	struct mbuf **, char **, struct mbuf *);
+/*
+ * Backend copyin/out functions for nfssvc(2), so that netbsd32 can
+ * easily access NFS.  Each operation either must perform a copyin or
+ * copyout of the right data for the emulation.  exp_in() takes a count
+ * of the number of export_args to copyin, and order arguments for
+ * func(dst, src).
+ */
+struct nfssvc_copy_ops {
+	int (*addsock_in)(struct nfsd_args *, const void *);
+	int (*setexports_in)(struct mountd_exports_list *, const void *);
+	int (*nsd_in)(struct nfsd_srvargs *, const void *);
+	int (*nsd_out)(void *, const struct nfsd_srvargs *);
+	int (*exp_in)(struct export_args *, const void *, size_t);
+};
+int do_nfssvc(struct nfssvc_copy_ops *, struct lwp *, int, void *, register_t *);
 
 /* nfs_export.c */
 extern struct nfs_public nfs_pub;

Added files:

Index: src/sys/compat/netbsd32/netbsd32_nfssvc.c
diff -u /dev/null src/sys/compat/netbsd32/netbsd32_nfssvc.c:1.1
--- /dev/null	Mon Jun 22 10:35:00 2015
+++ src/sys/compat/netbsd32/netbsd32_nfssvc.c	Mon Jun 22 10:35:00 2015
@@ -0,0 +1,185 @@
+/*	$NetBSD: netbsd32_nfssvc.c,v 1.1 2015/06/22 10:35:00 mrg Exp $	*/
+
+/*
+ * Copyright (c) 2015 Matthew R. Green
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_nfssvc.c,v 1.1 2015/06/22 10:35:00 mrg Exp $");
+
+#if defined(_KERNEL_OPT)
+#include "opt_nfs.h"
+#include "opt_compat_netbsd.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/vnode.h>
+#include <sys/filedesc.h>
+
+#include <compat/netbsd32/netbsd32.h>
+#include <compat/netbsd32/netbsd32_syscall.h>
+#include <compat/netbsd32/netbsd32_syscallargs.h>
+#include <compat/netbsd32/netbsd32_conv.h>
+
+#include <nfs/rpcv2.h>
+#include <nfs/nfsproto.h>
+#include <nfs/nfs.h>
+#include <nfs/nfs_var.h>
+
+static int nfssvc32_addsock_in(struct nfsd_args *, const void *);
+static int nfssvc32_setexports_in(struct mountd_exports_list *, const void *);
+static int nfssvc32_nsd_in(struct nfsd_srvargs *, const void *);
+static int nfssvc32_nsd_out(void *, const struct nfsd_srvargs *);
+static int nfssvc32_exp_in(struct export_args *, const void *, size_t);
+
+static int
+nfssvc32_addsock_in(struct nfsd_args *nfsdarg, const void *argp)
+{
+	struct netbsd32_nfsd_args args32;
+	int error;
+
+	error = copyin(argp, &args32, sizeof args32);
+	if (!error) {
+		nfsdarg->sock = args32.sock;
+		nfsdarg->name = NETBSD32PTR64(args32.name);
+		nfsdarg->namelen = args32.namelen;
+	}
+
+	return error;
+}
+
+static int
+nfssvc32_setexports_in(struct mountd_exports_list *mel, const void *argp)
+{
+	struct netbsd32_mountd_exports_list args32;
+	int error;
+
+	error = copyin(argp, &args32, sizeof args32);
+	if (!error) {
+		mel->mel_path = NETBSD32PTR64(args32.mel_path);
+		mel->mel_nexports = args32.mel_nexports;
+		mel->mel_exports = NETBSD32PTR64(args32.mel_exports);
+	}
+
+	return error;
+}
+
+static int
+nfssvc32_nsd_in(struct nfsd_srvargs *nsd, const void *argp)
+{
+	struct netbsd32_nfsd_srvargs args32;
+	int error;
+
+	error = copyin(argp, &args32, sizeof args32);
+	if (!error) {
+		nsd->nsd_nfsd = NETBSD32PTR64(args32.nsd_nfsd);
+		nsd->nsd_uid = args32.nsd_uid;
+		nsd->nsd_haddr = args32.nsd_haddr;
+		nsd->nsd_cr = args32.nsd_cr;
+		nsd->nsd_authlen = args32.nsd_authlen;
+		nsd->nsd_authstr = NETBSD32PTR64(args32.nsd_authstr);
+		nsd->nsd_verflen = args32.nsd_verflen;
+		nsd->nsd_uid = args32.nsd_uid;
+		netbsd32_to_timeval(&args32.nsd_timestamp, &nsd->nsd_timestamp);
+		nsd->nsd_ttl = args32.nsd_ttl;
+		nsd->nsd_key[0] = args32.nsd_key[0];
+		nsd->nsd_key[1] = args32.nsd_key[1];
+	}
+
+	return error;
+}
+
+static int
+nfssvc32_nsd_out(void *argp, const struct nfsd_srvargs *nsd)
+{
+	struct netbsd32_nfsd_srvargs args32;
+
+	NETBSD32PTR32(args32.nsd_nfsd, nsd->nsd_nfsd);
+	args32.nsd_uid = nsd->nsd_uid;
+	args32.nsd_haddr = nsd->nsd_haddr;
+	args32.nsd_cr = nsd->nsd_cr;
+	args32.nsd_authlen = nsd->nsd_authlen;
+	NETBSD32PTR32(args32.nsd_authstr, nsd->nsd_authstr);
+	args32.nsd_verflen = nsd->nsd_verflen;
+	args32.nsd_uid = nsd->nsd_uid;
+	netbsd32_from_timeval(&nsd->nsd_timestamp, &args32.nsd_timestamp);
+	args32.nsd_ttl = nsd->nsd_ttl;
+	args32.nsd_key[0] = nsd->nsd_key[0];
+	args32.nsd_key[1] = nsd->nsd_key[1];
+
+	return copyout(nsd, argp, sizeof *nsd);
+}
+
+static int
+nfssvc32_exp_in(struct export_args *exp, const void *argp, size_t nexports)
+{
+	struct netbsd32_export_args args32;
+	int error = 0;
+
+	for (size_t i = 0; i < nexports; i++) {
+		error = copyin(argp, &args32, sizeof args32);
+		if (error)
+			break;
+		exp->ex_flags = args32.ex_flags;
+		exp->ex_root = args32.ex_root;
+		exp->ex_anon = args32.ex_anon;
+		exp->ex_addr = NETBSD32PTR64(args32.ex_addr);
+		exp->ex_addrlen = args32.ex_addrlen;
+		exp->ex_mask = NETBSD32PTR64(args32.ex_mask);
+		exp->ex_masklen = args32.ex_masklen;
+		exp->ex_indexfile = NETBSD32PTR64(args32.ex_indexfile);
+		exp++;
+	}
+
+	return error;
+}
+
+/*
+ * NFS server system calls
+ */
+
+static struct nfssvc_copy_ops netbsd32_ops = {
+	.addsock_in = nfssvc32_addsock_in,
+	.setexports_in = nfssvc32_setexports_in,
+	.nsd_in = nfssvc32_nsd_in,
+	.nsd_out = nfssvc32_nsd_out,
+	.exp_in = nfssvc32_exp_in,
+};
+
+int
+netbsd32_nfssvc(struct lwp *l, const struct netbsd32_nfssvc_args *uap,
+    register_t *retval)
+{
+	/* {
+		syscallarg(int) flag;
+		syscallarg(netbsd32_voidp *) argp;
+	} */
+	int	flag = SCARG(uap, flag);
+	void	*argp = SCARG_P32(uap, argp);
+
+	return do_nfssvc(&netbsd32_ops, l, flag, argp, retval);
+}

Reply via email to