xref: /netbsd-src/sys/compat/netbsd32/netbsd32_compat_20.c (revision 41aa5859b647891f23013f613e0858c4b789a7bf)
1*41aa5859Sriastradh /*	$NetBSD: netbsd32_compat_20.c,v 1.42 2021/09/07 11:43:05 riastradh Exp $	*/
24b2667d3Scube 
34b2667d3Scube /*
44b2667d3Scube  * Copyright (c) 1998, 2001 Matthew R. Green
54b2667d3Scube  * All rights reserved.
64b2667d3Scube  *
74b2667d3Scube  * Redistribution and use in source and binary forms, with or without
84b2667d3Scube  * modification, are permitted provided that the following conditions
94b2667d3Scube  * are met:
104b2667d3Scube  * 1. Redistributions of source code must retain the above copyright
114b2667d3Scube  *    notice, this list of conditions and the following disclaimer.
124b2667d3Scube  * 2. Redistributions in binary form must reproduce the above copyright
134b2667d3Scube  *    notice, this list of conditions and the following disclaimer in the
144b2667d3Scube  *    documentation and/or other materials provided with the distribution.
154b2667d3Scube  *
164b2667d3Scube  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
174b2667d3Scube  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
184b2667d3Scube  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
194b2667d3Scube  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
204b2667d3Scube  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
214b2667d3Scube  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
224b2667d3Scube  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
234b2667d3Scube  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
244b2667d3Scube  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
254b2667d3Scube  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
264b2667d3Scube  * SUCH DAMAGE.
274b2667d3Scube  */
284b2667d3Scube 
294b2667d3Scube #include <sys/cdefs.h>
30*41aa5859Sriastradh __KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_20.c,v 1.42 2021/09/07 11:43:05 riastradh Exp $");
314b2667d3Scube 
324b2667d3Scube #include <sys/param.h>
334b2667d3Scube #include <sys/systm.h>
34d91f98a8Spgoyette #include <sys/module.h>
354b2667d3Scube #include <sys/mount.h>
364b2667d3Scube #include <sys/stat.h>
374b2667d3Scube #include <sys/time.h>
384b2667d3Scube #include <sys/ktrace.h>
394b2667d3Scube #include <sys/vnode.h>
40255beb6cSchristos #include <sys/socket.h>
414b2667d3Scube #include <sys/file.h>
424b2667d3Scube #include <sys/filedesc.h>
434b2667d3Scube #include <sys/namei.h>
444b2667d3Scube #include <sys/syscallargs.h>
45d91f98a8Spgoyette #include <sys/syscallvar.h>
464b2667d3Scube #include <sys/proc.h>
47b041fac9Schristos #include <sys/dirent.h>
484b2667d3Scube 
494b2667d3Scube #include <compat/netbsd32/netbsd32.h>
50d91f98a8Spgoyette #include <compat/netbsd32/netbsd32_syscall.h>
514b2667d3Scube #include <compat/netbsd32/netbsd32_syscallargs.h>
524b2667d3Scube #include <compat/netbsd32/netbsd32_conv.h>
534b2667d3Scube 
540f0296d8Sperry static inline void compat_20_netbsd32_from_statvfs(struct statvfs *,
554b2667d3Scube     struct netbsd32_statfs *);
564b2667d3Scube 
570f0296d8Sperry static inline void
compat_20_netbsd32_from_statvfs(struct statvfs * sbp,struct netbsd32_statfs * sb32p)5828bae79bSdsl compat_20_netbsd32_from_statvfs(struct statvfs *sbp, struct netbsd32_statfs *sb32p)
594b2667d3Scube {
60*41aa5859Sriastradh 
61*41aa5859Sriastradh 	memset(sb32p, 0, sizeof(*sb32p));
628822fe6dSmaxv 	sb32p->f_type = 0; /* XXX Put an actual value? */
634b2667d3Scube 	sb32p->f_flags = sbp->f_flag;
644b2667d3Scube 	sb32p->f_bsize = (netbsd32_long)sbp->f_bsize;
654b2667d3Scube 	sb32p->f_iosize = (netbsd32_long)sbp->f_iosize;
664b2667d3Scube 	sb32p->f_blocks = (netbsd32_long)sbp->f_blocks;
674b2667d3Scube 	sb32p->f_bfree = (netbsd32_long)sbp->f_bfree;
684b2667d3Scube 	sb32p->f_bavail = (netbsd32_long)sbp->f_bavail;
694b2667d3Scube 	sb32p->f_files = (netbsd32_long)sbp->f_files;
704b2667d3Scube 	sb32p->f_ffree = (netbsd32_long)sbp->f_ffree;
714b2667d3Scube 	sb32p->f_fsid = sbp->f_fsidx;
724b2667d3Scube 	sb32p->f_owner = sbp->f_owner;
734b2667d3Scube 	sb32p->f_spare[0] = 0;
744b2667d3Scube 	sb32p->f_spare[1] = 0;
754b2667d3Scube 	sb32p->f_spare[2] = 0;
764b2667d3Scube 	sb32p->f_spare[3] = 0;
7718754a76Schristos 	(void)memcpy(sb32p->f_fstypename, sbp->f_fstypename,
7818754a76Schristos 	    sizeof(sb32p->f_fstypename));
7918754a76Schristos 	(void)memcpy(sb32p->f_mntonname, sbp->f_mntonname,
8018754a76Schristos 	    sizeof(sb32p->f_mntonname));
8118754a76Schristos 	(void)memcpy(sb32p->f_mntfromname, sbp->f_mntfromname,
8218754a76Schristos 	    sizeof(sb32p->f_mntfromname));
834b2667d3Scube }
844b2667d3Scube 
854b2667d3Scube int
compat_20_netbsd32_getfsstat(struct lwp * l,const struct compat_20_netbsd32_getfsstat_args * uap,register_t * retval)867e2790cfSdsl compat_20_netbsd32_getfsstat(struct lwp *l, const struct compat_20_netbsd32_getfsstat_args *uap, register_t *retval)
874b2667d3Scube {
887e2790cfSdsl 	/* {
894b2667d3Scube 		syscallarg(netbsd32_statfsp_t) buf;
904b2667d3Scube 		syscallarg(netbsd32_long) bufsize;
914b2667d3Scube 		syscallarg(int) flags;
927e2790cfSdsl 	} */
9376f776f1Schristos 	int root = 0;
9476f776f1Schristos 	struct proc *p = l->l_proc;
95d177c6cdShannken 	mount_iterator_t *iter;
96d177c6cdShannken 	struct mount *mp;
9776f776f1Schristos 	struct statvfs *sb;
984b2667d3Scube 	struct netbsd32_statfs sb32;
9953524e44Schristos 	void *sfsp;
10076f776f1Schristos 	size_t count, maxcount;
10176f776f1Schristos 	int error = 0;
1024b2667d3Scube 
10376f776f1Schristos 	sb = STATVFSBUF_GET();
1044b2667d3Scube 	maxcount = SCARG(uap, bufsize) / sizeof(struct netbsd32_statfs);
105d364d308Sdsl 	sfsp = SCARG_P32(uap, buf);
106d177c6cdShannken 	mountlist_iterator_init(&iter);
1074b2667d3Scube 	count = 0;
108d177c6cdShannken 	while ((mp = mountlist_iterator_next(iter)) != NULL) {
1094b2667d3Scube 		if (sfsp && count < maxcount) {
11076f776f1Schristos 			error = dostatvfs(mp, sb, l, SCARG(uap, flags), 0);
11176f776f1Schristos 			if (error) {
11276f776f1Schristos 				error = 0;
1134b2667d3Scube 				continue;
1144b2667d3Scube 			}
11576f776f1Schristos 			compat_20_netbsd32_from_statvfs(sb, &sb32);
1164b2667d3Scube 			error = copyout(&sb32, sfsp, sizeof(sb32));
117d177c6cdShannken 			if (error)
11876f776f1Schristos 				goto out;
119fffc9c66Schristos 			sfsp = (char *)sfsp + sizeof(sb32);
12076f776f1Schristos 			root |= strcmp(sb->f_mntonname, "/") == 0;
1214b2667d3Scube 		}
1224b2667d3Scube 		count++;
1234b2667d3Scube 	}
12476f776f1Schristos 
12576f776f1Schristos 	if (root == 0 && p->p_cwdi->cwdi_rdir) {
12676f776f1Schristos 		/*
12776f776f1Schristos 		 * fake a root entry
12876f776f1Schristos 		 */
12976f776f1Schristos 		error = dostatvfs(p->p_cwdi->cwdi_rdir->v_mount,
13076f776f1Schristos 		    sb, l, SCARG(uap, flags), 1);
13176f776f1Schristos 		if (error != 0)
13276f776f1Schristos 			goto out;
13376f776f1Schristos 		if (sfsp) {
13476f776f1Schristos 			compat_20_netbsd32_from_statvfs(sb, &sb32);
13576f776f1Schristos 			error = copyout(&sb32, sfsp, sizeof(sb32));
13676f776f1Schristos 			if (error != 0)
13776f776f1Schristos 				goto out;
13876f776f1Schristos 		}
13976f776f1Schristos 		count++;
14076f776f1Schristos 	}
14176f776f1Schristos 
1424b2667d3Scube 	if (sfsp && count > maxcount)
1434b2667d3Scube 		*retval = maxcount;
1444b2667d3Scube 	else
1454b2667d3Scube 		*retval = count;
14676f776f1Schristos out:
147d177c6cdShannken 	mountlist_iterator_destroy(iter);
14876f776f1Schristos 	STATVFSBUF_PUT(sb);
14976f776f1Schristos 	return error;
1504b2667d3Scube }
1514b2667d3Scube 
1524b2667d3Scube int
compat_20_netbsd32_statfs(struct lwp * l,const struct compat_20_netbsd32_statfs_args * uap,register_t * retval)1537e2790cfSdsl compat_20_netbsd32_statfs(struct lwp *l, const struct compat_20_netbsd32_statfs_args *uap, register_t *retval)
1544b2667d3Scube {
1557e2790cfSdsl 	/* {
1564b2667d3Scube 		syscallarg(const netbsd32_charp) path;
1574b2667d3Scube 		syscallarg(netbsd32_statfsp_t) buf;
1587e2790cfSdsl 	} */
1594b2667d3Scube 	struct mount *mp;
16076f776f1Schristos 	struct statvfs *sb;
1614b2667d3Scube 	struct netbsd32_statfs s32;
1624b2667d3Scube 	int error;
163effcf1afSdholland 	struct vnode *vp;
1644b2667d3Scube 
165effcf1afSdholland 	error = namei_simple_user(SCARG_P32(uap, path),
166effcf1afSdholland 				NSM_FOLLOW_TRYEMULROOT, &vp);
167effcf1afSdholland 	if (error != 0)
168650cb29cSsimonb 		return error;
169effcf1afSdholland 	mp = vp->v_mount;
170effcf1afSdholland 	vrele(vp);
171b3f822cfSchs 	sb = STATVFSBUF_GET();
17276f776f1Schristos 	if ((error = dostatvfs(mp, sb, l, 0, 0)) != 0)
173b3f822cfSchs 		goto out;
17476f776f1Schristos 	compat_20_netbsd32_from_statvfs(sb, &s32);
175b3f822cfSchs 	error = copyout(&s32, SCARG_P32(uap, buf), sizeof(s32));
176b3f822cfSchs out:
177b3f822cfSchs 	STATVFSBUF_PUT(sb);
178b3f822cfSchs 	return error;
1794b2667d3Scube }
1804b2667d3Scube 
1814b2667d3Scube int
compat_20_netbsd32_fstatfs(struct lwp * l,const struct compat_20_netbsd32_fstatfs_args * uap,register_t * retval)1827e2790cfSdsl compat_20_netbsd32_fstatfs(struct lwp *l, const struct compat_20_netbsd32_fstatfs_args *uap, register_t *retval)
1834b2667d3Scube {
1847e2790cfSdsl 	/* {
1854b2667d3Scube 		syscallarg(int) fd;
1864b2667d3Scube 		syscallarg(netbsd32_statfsp_t) buf;
1877e2790cfSdsl 	} */
188a9ca7a37Sad 	file_t *fp;
1894b2667d3Scube 	struct mount *mp;
19076f776f1Schristos 	struct statvfs *sb;
1914b2667d3Scube 	struct netbsd32_statfs s32;
1924b2667d3Scube 	int error;
1934b2667d3Scube 
194a00bd89dSad 	/* fd_getvnode() will use the descriptor for us */
195a9ca7a37Sad 	if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
196650cb29cSsimonb 		return error;
19745b1ec74Smatt 	mp = fp->f_vnode->v_mount;
198b3f822cfSchs 	sb = STATVFSBUF_GET();
19976f776f1Schristos 	if ((error = dostatvfs(mp, sb, l, 0, 0)) != 0)
2004b2667d3Scube 		goto out;
20176f776f1Schristos 	compat_20_netbsd32_from_statvfs(sb, &s32);
202d364d308Sdsl 	error = copyout(&s32, SCARG_P32(uap, buf), sizeof(s32));
2034b2667d3Scube  out:
204b3f822cfSchs 	STATVFSBUF_PUT(sb);
205a9ca7a37Sad 	fd_putfile(SCARG(uap, fd));
206833b5e5eSwiz 	return error;
2074b2667d3Scube }
2084b2667d3Scube 
2094b2667d3Scube int
compat_20_netbsd32_fhstatfs(struct lwp * l,const struct compat_20_netbsd32_fhstatfs_args * uap,register_t * retval)2107e2790cfSdsl compat_20_netbsd32_fhstatfs(struct lwp *l, const struct compat_20_netbsd32_fhstatfs_args *uap, register_t *retval)
2114b2667d3Scube {
2127e2790cfSdsl 	/* {
2134b2667d3Scube 		syscallarg(const netbsd32_fhandlep_t) fhp;
2144b2667d3Scube 		syscallarg(struct statvfs *) buf;
2157e2790cfSdsl 	} */
216b4cb63a6Smartin 	struct compat_30_sys_fhstatvfs1_args ua;
2174b2667d3Scube 
218b4cb63a6Smartin 	NETBSD32TOP_UAP(fhp, const struct compat_30_fhandle);
2194b2667d3Scube 	NETBSD32TOP_UAP(buf, struct statvfs);
2204b2667d3Scube #ifdef notyet
2214b2667d3Scube 	NETBSD32TOP_UAP(flags, int);
2224b2667d3Scube #endif
223650cb29cSsimonb 	return compat_30_sys_fhstatvfs1(l, &ua, retval);
2244b2667d3Scube }
225d91f98a8Spgoyette 
226d91f98a8Spgoyette static struct syscall_package compat_netbsd32_20_syscalls[] = {
227d91f98a8Spgoyette 	{ NETBSD32_SYS_compat_20_netbsd32_statfs, 0,
228d91f98a8Spgoyette 	    (sy_call_t *)compat_20_netbsd32_statfs },
229d91f98a8Spgoyette 	{ NETBSD32_SYS_compat_20_netbsd32_fstatfs, 0,
230d91f98a8Spgoyette 	    (sy_call_t *)compat_20_netbsd32_fstatfs },
231d91f98a8Spgoyette 	{ NETBSD32_SYS_compat_20_netbsd32_fhstatfs, 0,
232d91f98a8Spgoyette 	    (sy_call_t *)compat_20_netbsd32_fhstatfs },
233d91f98a8Spgoyette 	{ NETBSD32_SYS_compat_20_netbsd32_getfsstat, 0,
234d91f98a8Spgoyette 	    (sy_call_t *)compat_20_netbsd32_getfsstat },
235d91f98a8Spgoyette 	{ 0, 0, NULL }
236d91f98a8Spgoyette };
237d91f98a8Spgoyette 
238d91f98a8Spgoyette MODULE(MODULE_CLASS_EXEC, compat_netbsd32_20, "compat_netbsd32_30,compat_20");
239d91f98a8Spgoyette 
240d91f98a8Spgoyette static int
compat_netbsd32_20_modcmd(modcmd_t cmd,void * arg)241d91f98a8Spgoyette compat_netbsd32_20_modcmd(modcmd_t cmd, void *arg)
242d91f98a8Spgoyette {
243d91f98a8Spgoyette 
244d91f98a8Spgoyette 	switch (cmd) {
245d91f98a8Spgoyette 	case MODULE_CMD_INIT:
246d91f98a8Spgoyette 		return syscall_establish(&emul_netbsd32,
247d91f98a8Spgoyette 		    compat_netbsd32_20_syscalls);
248d91f98a8Spgoyette 
249d91f98a8Spgoyette 	case MODULE_CMD_FINI:
250d91f98a8Spgoyette 		return syscall_disestablish(&emul_netbsd32,
251d91f98a8Spgoyette 		    compat_netbsd32_20_syscalls);
252d91f98a8Spgoyette 
253d91f98a8Spgoyette 	default:
254d91f98a8Spgoyette 		return ENOTTY;
255d91f98a8Spgoyette 	}
256d91f98a8Spgoyette }
257