1 1.42 riastrad /* $NetBSD: netbsd32_compat_20.c,v 1.42 2021/09/07 11:43:05 riastradh Exp $ */ 2 1.1 cube 3 1.1 cube /* 4 1.1 cube * Copyright (c) 1998, 2001 Matthew R. Green 5 1.1 cube * All rights reserved. 6 1.1 cube * 7 1.1 cube * Redistribution and use in source and binary forms, with or without 8 1.1 cube * modification, are permitted provided that the following conditions 9 1.1 cube * are met: 10 1.1 cube * 1. Redistributions of source code must retain the above copyright 11 1.1 cube * notice, this list of conditions and the following disclaimer. 12 1.1 cube * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cube * notice, this list of conditions and the following disclaimer in the 14 1.1 cube * documentation and/or other materials provided with the distribution. 15 1.1 cube * 16 1.1 cube * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.1 cube * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 cube * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 cube * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.1 cube * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 1.1 cube * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 1.1 cube * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 1.1 cube * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 1.1 cube * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 1.1 cube * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 1.1 cube * SUCH DAMAGE. 27 1.1 cube */ 28 1.1 cube 29 1.1 cube #include <sys/cdefs.h> 30 1.42 riastrad __KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_20.c,v 1.42 2021/09/07 11:43:05 riastradh Exp $"); 31 1.1 cube 32 1.1 cube #include <sys/param.h> 33 1.1 cube #include <sys/systm.h> 34 1.38 pgoyette #include <sys/module.h> 35 1.1 cube #include <sys/mount.h> 36 1.1 cube #include <sys/stat.h> 37 1.1 cube #include <sys/time.h> 38 1.1 cube #include <sys/ktrace.h> 39 1.1 cube #include <sys/vnode.h> 40 1.37 christos #include <sys/socket.h> 41 1.1 cube #include <sys/file.h> 42 1.1 cube #include <sys/filedesc.h> 43 1.1 cube #include <sys/namei.h> 44 1.1 cube #include <sys/syscallargs.h> 45 1.38 pgoyette #include <sys/syscallvar.h> 46 1.1 cube #include <sys/proc.h> 47 1.2 christos #include <sys/dirent.h> 48 1.1 cube 49 1.1 cube #include <compat/netbsd32/netbsd32.h> 50 1.38 pgoyette #include <compat/netbsd32/netbsd32_syscall.h> 51 1.1 cube #include <compat/netbsd32/netbsd32_syscallargs.h> 52 1.1 cube #include <compat/netbsd32/netbsd32_conv.h> 53 1.1 cube 54 1.4 perry static inline void compat_20_netbsd32_from_statvfs(struct statvfs *, 55 1.1 cube struct netbsd32_statfs *); 56 1.1 cube 57 1.4 perry static inline void 58 1.17 dsl compat_20_netbsd32_from_statvfs(struct statvfs *sbp, struct netbsd32_statfs *sb32p) 59 1.1 cube { 60 1.42 riastrad 61 1.42 riastrad memset(sb32p, 0, sizeof(*sb32p)); 62 1.39 maxv sb32p->f_type = 0; /* XXX Put an actual value? */ 63 1.1 cube sb32p->f_flags = sbp->f_flag; 64 1.1 cube sb32p->f_bsize = (netbsd32_long)sbp->f_bsize; 65 1.1 cube sb32p->f_iosize = (netbsd32_long)sbp->f_iosize; 66 1.1 cube sb32p->f_blocks = (netbsd32_long)sbp->f_blocks; 67 1.1 cube sb32p->f_bfree = (netbsd32_long)sbp->f_bfree; 68 1.1 cube sb32p->f_bavail = (netbsd32_long)sbp->f_bavail; 69 1.1 cube sb32p->f_files = (netbsd32_long)sbp->f_files; 70 1.1 cube sb32p->f_ffree = (netbsd32_long)sbp->f_ffree; 71 1.1 cube sb32p->f_fsid = sbp->f_fsidx; 72 1.1 cube sb32p->f_owner = sbp->f_owner; 73 1.1 cube sb32p->f_spare[0] = 0; 74 1.1 cube sb32p->f_spare[1] = 0; 75 1.1 cube sb32p->f_spare[2] = 0; 76 1.1 cube sb32p->f_spare[3] = 0; 77 1.13 christos (void)memcpy(sb32p->f_fstypename, sbp->f_fstypename, 78 1.13 christos sizeof(sb32p->f_fstypename)); 79 1.13 christos (void)memcpy(sb32p->f_mntonname, sbp->f_mntonname, 80 1.13 christos sizeof(sb32p->f_mntonname)); 81 1.13 christos (void)memcpy(sb32p->f_mntfromname, sbp->f_mntfromname, 82 1.13 christos sizeof(sb32p->f_mntfromname)); 83 1.1 cube } 84 1.1 cube 85 1.1 cube int 86 1.19 dsl compat_20_netbsd32_getfsstat(struct lwp *l, const struct compat_20_netbsd32_getfsstat_args *uap, register_t *retval) 87 1.1 cube { 88 1.19 dsl /* { 89 1.1 cube syscallarg(netbsd32_statfsp_t) buf; 90 1.1 cube syscallarg(netbsd32_long) bufsize; 91 1.1 cube syscallarg(int) flags; 92 1.19 dsl } */ 93 1.32 christos int root = 0; 94 1.32 christos struct proc *p = l->l_proc; 95 1.36 hannken mount_iterator_t *iter; 96 1.36 hannken struct mount *mp; 97 1.32 christos struct statvfs *sb; 98 1.1 cube struct netbsd32_statfs sb32; 99 1.8 christos void *sfsp; 100 1.32 christos size_t count, maxcount; 101 1.32 christos int error = 0; 102 1.1 cube 103 1.32 christos sb = STATVFSBUF_GET(); 104 1.1 cube maxcount = SCARG(uap, bufsize) / sizeof(struct netbsd32_statfs); 105 1.10 dsl sfsp = SCARG_P32(uap, buf); 106 1.36 hannken mountlist_iterator_init(&iter); 107 1.1 cube count = 0; 108 1.36 hannken while ((mp = mountlist_iterator_next(iter)) != NULL) { 109 1.1 cube if (sfsp && count < maxcount) { 110 1.32 christos error = dostatvfs(mp, sb, l, SCARG(uap, flags), 0); 111 1.32 christos if (error) { 112 1.32 christos error = 0; 113 1.1 cube continue; 114 1.1 cube } 115 1.32 christos compat_20_netbsd32_from_statvfs(sb, &sb32); 116 1.1 cube error = copyout(&sb32, sfsp, sizeof(sb32)); 117 1.36 hannken if (error) 118 1.32 christos goto out; 119 1.9 christos sfsp = (char *)sfsp + sizeof(sb32); 120 1.32 christos root |= strcmp(sb->f_mntonname, "/") == 0; 121 1.1 cube } 122 1.1 cube count++; 123 1.1 cube } 124 1.32 christos 125 1.32 christos if (root == 0 && p->p_cwdi->cwdi_rdir) { 126 1.32 christos /* 127 1.32 christos * fake a root entry 128 1.32 christos */ 129 1.32 christos error = dostatvfs(p->p_cwdi->cwdi_rdir->v_mount, 130 1.32 christos sb, l, SCARG(uap, flags), 1); 131 1.32 christos if (error != 0) 132 1.32 christos goto out; 133 1.32 christos if (sfsp) { 134 1.32 christos compat_20_netbsd32_from_statvfs(sb, &sb32); 135 1.32 christos error = copyout(&sb32, sfsp, sizeof(sb32)); 136 1.32 christos if (error != 0) 137 1.32 christos goto out; 138 1.32 christos } 139 1.32 christos count++; 140 1.32 christos } 141 1.32 christos 142 1.1 cube if (sfsp && count > maxcount) 143 1.1 cube *retval = maxcount; 144 1.1 cube else 145 1.1 cube *retval = count; 146 1.32 christos out: 147 1.36 hannken mountlist_iterator_destroy(iter); 148 1.32 christos STATVFSBUF_PUT(sb); 149 1.32 christos return error; 150 1.1 cube } 151 1.1 cube 152 1.1 cube int 153 1.19 dsl compat_20_netbsd32_statfs(struct lwp *l, const struct compat_20_netbsd32_statfs_args *uap, register_t *retval) 154 1.1 cube { 155 1.19 dsl /* { 156 1.1 cube syscallarg(const netbsd32_charp) path; 157 1.1 cube syscallarg(netbsd32_statfsp_t) buf; 158 1.19 dsl } */ 159 1.1 cube struct mount *mp; 160 1.32 christos struct statvfs *sb; 161 1.1 cube struct netbsd32_statfs s32; 162 1.1 cube int error; 163 1.27 dholland struct vnode *vp; 164 1.1 cube 165 1.27 dholland error = namei_simple_user(SCARG_P32(uap, path), 166 1.27 dholland NSM_FOLLOW_TRYEMULROOT, &vp); 167 1.27 dholland if (error != 0) 168 1.40 simonb return error; 169 1.27 dholland mp = vp->v_mount; 170 1.27 dholland vrele(vp); 171 1.35 chs sb = STATVFSBUF_GET(); 172 1.32 christos if ((error = dostatvfs(mp, sb, l, 0, 0)) != 0) 173 1.35 chs goto out; 174 1.32 christos compat_20_netbsd32_from_statvfs(sb, &s32); 175 1.35 chs error = copyout(&s32, SCARG_P32(uap, buf), sizeof(s32)); 176 1.35 chs out: 177 1.35 chs STATVFSBUF_PUT(sb); 178 1.35 chs return error; 179 1.1 cube } 180 1.1 cube 181 1.1 cube int 182 1.19 dsl compat_20_netbsd32_fstatfs(struct lwp *l, const struct compat_20_netbsd32_fstatfs_args *uap, register_t *retval) 183 1.1 cube { 184 1.19 dsl /* { 185 1.1 cube syscallarg(int) fd; 186 1.1 cube syscallarg(netbsd32_statfsp_t) buf; 187 1.19 dsl } */ 188 1.21 ad file_t *fp; 189 1.1 cube struct mount *mp; 190 1.32 christos struct statvfs *sb; 191 1.1 cube struct netbsd32_statfs s32; 192 1.1 cube int error; 193 1.1 cube 194 1.26 ad /* fd_getvnode() will use the descriptor for us */ 195 1.21 ad if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) 196 1.40 simonb return error; 197 1.34 matt mp = fp->f_vnode->v_mount; 198 1.35 chs sb = STATVFSBUF_GET(); 199 1.32 christos if ((error = dostatvfs(mp, sb, l, 0, 0)) != 0) 200 1.1 cube goto out; 201 1.32 christos compat_20_netbsd32_from_statvfs(sb, &s32); 202 1.10 dsl error = copyout(&s32, SCARG_P32(uap, buf), sizeof(s32)); 203 1.1 cube out: 204 1.35 chs STATVFSBUF_PUT(sb); 205 1.21 ad fd_putfile(SCARG(uap, fd)); 206 1.41 wiz return error; 207 1.1 cube } 208 1.1 cube 209 1.1 cube int 210 1.19 dsl compat_20_netbsd32_fhstatfs(struct lwp *l, const struct compat_20_netbsd32_fhstatfs_args *uap, register_t *retval) 211 1.1 cube { 212 1.19 dsl /* { 213 1.1 cube syscallarg(const netbsd32_fhandlep_t) fhp; 214 1.1 cube syscallarg(struct statvfs *) buf; 215 1.19 dsl } */ 216 1.6 martin struct compat_30_sys_fhstatvfs1_args ua; 217 1.1 cube 218 1.6 martin NETBSD32TOP_UAP(fhp, const struct compat_30_fhandle); 219 1.1 cube NETBSD32TOP_UAP(buf, struct statvfs); 220 1.1 cube #ifdef notyet 221 1.1 cube NETBSD32TOP_UAP(flags, int); 222 1.1 cube #endif 223 1.40 simonb return compat_30_sys_fhstatvfs1(l, &ua, retval); 224 1.1 cube } 225 1.38 pgoyette 226 1.38 pgoyette static struct syscall_package compat_netbsd32_20_syscalls[] = { 227 1.38 pgoyette { NETBSD32_SYS_compat_20_netbsd32_statfs, 0, 228 1.38 pgoyette (sy_call_t *)compat_20_netbsd32_statfs }, 229 1.38 pgoyette { NETBSD32_SYS_compat_20_netbsd32_fstatfs, 0, 230 1.38 pgoyette (sy_call_t *)compat_20_netbsd32_fstatfs }, 231 1.38 pgoyette { NETBSD32_SYS_compat_20_netbsd32_fhstatfs, 0, 232 1.38 pgoyette (sy_call_t *)compat_20_netbsd32_fhstatfs }, 233 1.38 pgoyette { NETBSD32_SYS_compat_20_netbsd32_getfsstat, 0, 234 1.38 pgoyette (sy_call_t *)compat_20_netbsd32_getfsstat }, 235 1.38 pgoyette { 0, 0, NULL } 236 1.38 pgoyette }; 237 1.38 pgoyette 238 1.38 pgoyette MODULE(MODULE_CLASS_EXEC, compat_netbsd32_20, "compat_netbsd32_30,compat_20"); 239 1.38 pgoyette 240 1.38 pgoyette static int 241 1.38 pgoyette compat_netbsd32_20_modcmd(modcmd_t cmd, void *arg) 242 1.38 pgoyette { 243 1.38 pgoyette 244 1.38 pgoyette switch (cmd) { 245 1.38 pgoyette case MODULE_CMD_INIT: 246 1.38 pgoyette return syscall_establish(&emul_netbsd32, 247 1.38 pgoyette compat_netbsd32_20_syscalls); 248 1.38 pgoyette 249 1.38 pgoyette case MODULE_CMD_FINI: 250 1.38 pgoyette return syscall_disestablish(&emul_netbsd32, 251 1.38 pgoyette compat_netbsd32_20_syscalls); 252 1.38 pgoyette 253 1.38 pgoyette default: 254 1.38 pgoyette return ENOTTY; 255 1.38 pgoyette } 256 1.38 pgoyette } 257