1 1.26 christos /* $NetBSD: vfs_syscalls_50.c,v 1.26 2021/08/15 07:57:46 christos Exp $ */ 2 1.2 christos 3 1.2 christos /*- 4 1.2 christos * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 1.2 christos * All rights reserved. 6 1.2 christos * 7 1.2 christos * This code is derived from software contributed to The NetBSD Foundation 8 1.2 christos * by Christos Zoulas. 9 1.2 christos * 10 1.2 christos * Redistribution and use in source and binary forms, with or without 11 1.2 christos * modification, are permitted provided that the following conditions 12 1.2 christos * are met: 13 1.2 christos * 1. Redistributions of source code must retain the above copyright 14 1.2 christos * notice, this list of conditions and the following disclaimer. 15 1.2 christos * 2. Redistributions in binary form must reproduce the above copyright 16 1.2 christos * notice, this list of conditions and the following disclaimer in the 17 1.2 christos * documentation and/or other materials provided with the distribution. 18 1.2 christos * 19 1.2 christos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.2 christos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.2 christos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.2 christos * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.2 christos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.2 christos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.2 christos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.2 christos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.2 christos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.2 christos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.2 christos * POSSIBILITY OF SUCH DAMAGE. 30 1.2 christos */ 31 1.2 christos #include <sys/cdefs.h> 32 1.26 christos __KERNEL_RCSID(0, "$NetBSD: vfs_syscalls_50.c,v 1.26 2021/08/15 07:57:46 christos Exp $"); 33 1.19 pgoyette 34 1.19 pgoyette #if defined(_KERNEL_OPT) 35 1.19 pgoyette #include "opt_compat_netbsd.h" 36 1.20 christos #include "opt_quota.h" 37 1.19 pgoyette #endif 38 1.2 christos 39 1.2 christos #include <sys/param.h> 40 1.2 christos #include <sys/systm.h> 41 1.2 christos #include <sys/namei.h> 42 1.2 christos #include <sys/filedesc.h> 43 1.2 christos #include <sys/kernel.h> 44 1.2 christos #include <sys/file.h> 45 1.2 christos #include <sys/stat.h> 46 1.2 christos #include <sys/socketvar.h> 47 1.2 christos #include <sys/vnode.h> 48 1.2 christos #include <sys/mount.h> 49 1.2 christos #include <sys/proc.h> 50 1.2 christos #include <sys/uio.h> 51 1.2 christos #include <sys/dirent.h> 52 1.2 christos #include <sys/kauth.h> 53 1.2 christos #include <sys/time.h> 54 1.19 pgoyette #include <sys/syscall.h> 55 1.19 pgoyette #include <sys/syscallvar.h> 56 1.19 pgoyette #include <sys/syscallargs.h> 57 1.2 christos #include <sys/vfs_syscalls.h> 58 1.2 christos #ifndef LFS 59 1.2 christos #define LFS 60 1.2 christos #endif 61 1.2 christos #include <sys/syscallargs.h> 62 1.2 christos 63 1.2 christos #include <ufs/lfs/lfs_extern.h> 64 1.2 christos 65 1.2 christos #include <compat/common/compat_util.h> 66 1.19 pgoyette #include <compat/common/compat_mod.h> 67 1.2 christos #include <compat/sys/time.h> 68 1.2 christos #include <compat/sys/stat.h> 69 1.2 christos #include <compat/sys/dirent.h> 70 1.2 christos #include <compat/sys/mount.h> 71 1.2 christos 72 1.19 pgoyette static const struct syscall_package vfs_syscalls_50_syscalls[] = { 73 1.19 pgoyette { SYS_compat_50___stat30, 0, (sy_call_t *)compat_50_sys___stat30 }, 74 1.21 pgoyette { SYS_compat_50___fstat30, 0, (sy_call_t *)compat_50_sys___fstat30 }, 75 1.21 pgoyette { SYS_compat_50___lstat30, 0, (sy_call_t *)compat_50_sys___lstat30 }, 76 1.21 pgoyette { SYS_compat_50___fhstat40, 0, (sy_call_t *)compat_50_sys___fhstat40 }, 77 1.19 pgoyette { SYS_compat_50_utimes, 0, (sy_call_t *)compat_50_sys_utimes }, 78 1.21 pgoyette { SYS_compat_50_lfs_segwait, 0, 79 1.19 pgoyette (sy_call_t *)compat_50_sys_lfs_segwait } , 80 1.21 pgoyette { SYS_compat_50_futimes, 0, (sy_call_t *)compat_50_sys_futimes }, 81 1.21 pgoyette { SYS_compat_50_lutimes, 0, (sy_call_t *)compat_50_sys_lutimes }, 82 1.19 pgoyette { SYS_compat_50_mknod, 0, (sy_call_t *)compat_50_sys_mknod }, 83 1.19 pgoyette { 0, 0, NULL } 84 1.19 pgoyette }; 85 1.19 pgoyette 86 1.2 christos /* 87 1.2 christos * Convert from a new to an old stat structure. 88 1.2 christos */ 89 1.2 christos static void 90 1.2 christos cvtstat(struct stat30 *ost, const struct stat *st) 91 1.2 christos { 92 1.2 christos 93 1.26 christos /* Handle any padding. */ 94 1.26 christos memset(ost, 0, sizeof(*ost)); 95 1.2 christos ost->st_dev = st->st_dev; 96 1.2 christos ost->st_ino = st->st_ino; 97 1.2 christos ost->st_mode = st->st_mode; 98 1.2 christos ost->st_nlink = st->st_nlink; 99 1.2 christos ost->st_uid = st->st_uid; 100 1.2 christos ost->st_gid = st->st_gid; 101 1.2 christos ost->st_rdev = st->st_rdev; 102 1.2 christos timespec_to_timespec50(&st->st_atimespec, &ost->st_atimespec); 103 1.2 christos timespec_to_timespec50(&st->st_mtimespec, &ost->st_mtimespec); 104 1.2 christos timespec_to_timespec50(&st->st_ctimespec, &ost->st_ctimespec); 105 1.2 christos timespec_to_timespec50(&st->st_birthtimespec, &ost->st_birthtimespec); 106 1.2 christos ost->st_size = st->st_size; 107 1.2 christos ost->st_blocks = st->st_blocks; 108 1.2 christos ost->st_blksize = st->st_blksize; 109 1.2 christos ost->st_flags = st->st_flags; 110 1.2 christos ost->st_gen = st->st_gen; 111 1.6 pooka memset(ost->st_spare, 0, sizeof(ost->st_spare)); 112 1.2 christos } 113 1.2 christos 114 1.2 christos /* 115 1.2 christos * Get file status; this version follows links. 116 1.2 christos */ 117 1.2 christos /* ARGSUSED */ 118 1.2 christos int 119 1.2 christos compat_50_sys___stat30(struct lwp *l, const struct compat_50_sys___stat30_args *uap, register_t *retval) 120 1.2 christos { 121 1.2 christos /* { 122 1.2 christos syscallarg(const char *) path; 123 1.2 christos syscallarg(struct stat30 *) ub; 124 1.2 christos } */ 125 1.2 christos struct stat sb; 126 1.2 christos struct stat30 osb; 127 1.2 christos int error; 128 1.2 christos 129 1.2 christos error = do_sys_stat(SCARG(uap, path), FOLLOW, &sb); 130 1.2 christos if (error) 131 1.2 christos return error; 132 1.2 christos cvtstat(&osb, &sb); 133 1.26 christos return copyout(&osb, SCARG(uap, ub), sizeof(osb)); 134 1.2 christos } 135 1.2 christos 136 1.2 christos 137 1.2 christos /* 138 1.2 christos * Get file status; this version does not follow links. 139 1.2 christos */ 140 1.2 christos /* ARGSUSED */ 141 1.2 christos int 142 1.2 christos compat_50_sys___lstat30(struct lwp *l, const struct compat_50_sys___lstat30_args *uap, register_t *retval) 143 1.2 christos { 144 1.2 christos /* { 145 1.2 christos syscallarg(const char *) path; 146 1.2 christos syscallarg(struct stat30 *) ub; 147 1.2 christos } */ 148 1.2 christos struct stat sb; 149 1.2 christos struct stat30 osb; 150 1.2 christos int error; 151 1.2 christos 152 1.2 christos error = do_sys_stat(SCARG(uap, path), NOFOLLOW, &sb); 153 1.2 christos if (error) 154 1.2 christos return error; 155 1.2 christos cvtstat(&osb, &sb); 156 1.26 christos return copyout(&osb, SCARG(uap, ub), sizeof(osb)); 157 1.2 christos } 158 1.2 christos 159 1.2 christos /* 160 1.2 christos * Return status information about a file descriptor. 161 1.2 christos */ 162 1.2 christos /* ARGSUSED */ 163 1.2 christos int 164 1.2 christos compat_50_sys___fstat30(struct lwp *l, const struct compat_50_sys___fstat30_args *uap, register_t *retval) 165 1.2 christos { 166 1.2 christos /* { 167 1.2 christos syscallarg(int) fd; 168 1.2 christos syscallarg(struct stat30 *) sb; 169 1.2 christos } */ 170 1.2 christos struct stat sb; 171 1.2 christos struct stat30 osb; 172 1.2 christos int error; 173 1.2 christos 174 1.4 njoly error = do_sys_fstat(SCARG(uap, fd), &sb); 175 1.2 christos if (error) 176 1.2 christos return error; 177 1.2 christos cvtstat(&osb, &sb); 178 1.26 christos return copyout(&osb, SCARG(uap, sb), sizeof(osb)); 179 1.2 christos } 180 1.2 christos 181 1.2 christos /* ARGSUSED */ 182 1.2 christos int 183 1.2 christos compat_50_sys___fhstat40(struct lwp *l, const struct compat_50_sys___fhstat40_args *uap, register_t *retval) 184 1.2 christos { 185 1.2 christos /* { 186 1.2 christos syscallarg(const void *) fhp; 187 1.2 christos syscallarg(size_t) fh_size; 188 1.2 christos syscallarg(struct stat30 *) sb; 189 1.2 christos } */ 190 1.2 christos struct stat sb; 191 1.2 christos struct stat30 osb; 192 1.2 christos int error; 193 1.2 christos 194 1.2 christos error = do_fhstat(l, SCARG(uap, fhp), SCARG(uap, fh_size), &sb); 195 1.2 christos if (error) 196 1.2 christos return error; 197 1.2 christos cvtstat(&osb, &sb); 198 1.26 christos return copyout(&osb, SCARG(uap, sb), sizeof(osb)); 199 1.2 christos } 200 1.2 christos 201 1.2 christos static int 202 1.2 christos compat_50_do_sys_utimes(struct lwp *l, struct vnode *vp, const char *path, 203 1.2 christos int flag, const struct timeval50 *tptr) 204 1.2 christos { 205 1.3 christos struct timeval tv[2], *tvp; 206 1.2 christos struct timeval50 tv50[2]; 207 1.3 christos if (tptr) { 208 1.3 christos int error = copyin(tptr, tv50, sizeof(tv50)); 209 1.3 christos if (error) 210 1.3 christos return error; 211 1.3 christos timeval50_to_timeval(&tv50[0], &tv[0]); 212 1.3 christos timeval50_to_timeval(&tv50[1], &tv[1]); 213 1.3 christos tvp = tv; 214 1.3 christos } else 215 1.3 christos tvp = NULL; 216 1.3 christos return do_sys_utimes(l, vp, path, flag, tvp, UIO_SYSSPACE); 217 1.2 christos } 218 1.2 christos 219 1.2 christos /* 220 1.2 christos * Set the access and modification times given a path name; this 221 1.2 christos * version follows links. 222 1.2 christos */ 223 1.2 christos /* ARGSUSED */ 224 1.2 christos int 225 1.2 christos compat_50_sys_utimes(struct lwp *l, const struct compat_50_sys_utimes_args *uap, 226 1.2 christos register_t *retval) 227 1.2 christos { 228 1.2 christos /* { 229 1.2 christos syscallarg(const char *) path; 230 1.2 christos syscallarg(const struct timeval50 *) tptr; 231 1.2 christos } */ 232 1.2 christos 233 1.2 christos return compat_50_do_sys_utimes(l, NULL, SCARG(uap, path), FOLLOW, 234 1.2 christos SCARG(uap, tptr)); 235 1.2 christos } 236 1.2 christos 237 1.2 christos /* 238 1.2 christos * Set the access and modification times given a file descriptor. 239 1.2 christos */ 240 1.2 christos /* ARGSUSED */ 241 1.2 christos int 242 1.2 christos compat_50_sys_futimes(struct lwp *l, 243 1.2 christos const struct compat_50_sys_futimes_args *uap, register_t *retval) 244 1.2 christos { 245 1.2 christos /* { 246 1.2 christos syscallarg(int) fd; 247 1.2 christos syscallarg(const struct timeval50 *) tptr; 248 1.2 christos } */ 249 1.2 christos int error; 250 1.2 christos struct file *fp; 251 1.2 christos 252 1.2 christos /* fd_getvnode() will use the descriptor for us */ 253 1.2 christos if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) 254 1.2 christos return error; 255 1.18 matt error = compat_50_do_sys_utimes(l, fp->f_vnode, NULL, 0, 256 1.2 christos SCARG(uap, tptr)); 257 1.2 christos fd_putfile(SCARG(uap, fd)); 258 1.2 christos return error; 259 1.2 christos } 260 1.2 christos 261 1.2 christos /* 262 1.2 christos * Set the access and modification times given a path name; this 263 1.2 christos * version does not follow links. 264 1.2 christos */ 265 1.2 christos int 266 1.2 christos compat_50_sys_lutimes(struct lwp *l, 267 1.2 christos const struct compat_50_sys_lutimes_args *uap, register_t *retval) 268 1.2 christos { 269 1.2 christos /* { 270 1.2 christos syscallarg(const char *) path; 271 1.2 christos syscallarg(const struct timeval50 *) tptr; 272 1.2 christos } */ 273 1.2 christos 274 1.2 christos return compat_50_do_sys_utimes(l, NULL, SCARG(uap, path), NOFOLLOW, 275 1.2 christos SCARG(uap, tptr)); 276 1.2 christos } 277 1.2 christos 278 1.2 christos int 279 1.2 christos compat_50_sys_lfs_segwait(struct lwp *l, 280 1.2 christos const struct compat_50_sys_lfs_segwait_args *uap, register_t *retval) 281 1.2 christos { 282 1.2 christos /* { 283 1.2 christos syscallarg(fsid_t *) fsidp; 284 1.2 christos syscallarg(struct timeval50 *) tv; 285 1.2 christos } */ 286 1.2 christos #ifdef notyet 287 1.19 pgoyette /* XXX need to check presence of LFS at run-time XXX */ 288 1.2 christos struct timeval atv; 289 1.2 christos struct timeval50 atv50; 290 1.2 christos fsid_t fsid; 291 1.2 christos int error; 292 1.2 christos 293 1.2 christos /* XXX need we be su to segwait? */ 294 1.17 elad error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_LFS, 295 1.17 elad KAUTH_REQ_SYSTEM_LFS_SEGWAIT, NULL, NULL, NULL); 296 1.17 elad if (error) 297 1.2 christos return (error); 298 1.2 christos if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0) 299 1.2 christos return (error); 300 1.2 christos 301 1.2 christos if (SCARG(uap, tv)) { 302 1.2 christos error = copyin(SCARG(uap, tv), &atv50, sizeof(atv50)); 303 1.2 christos if (error) 304 1.2 christos return (error); 305 1.2 christos timeval50_to_timeval(&atv50, &atv); 306 1.2 christos if (itimerfix(&atv)) 307 1.2 christos return (EINVAL); 308 1.2 christos } else /* NULL or invalid */ 309 1.2 christos atv.tv_sec = atv.tv_usec = 0; 310 1.2 christos return lfs_segwait(&fsid, &atv); 311 1.2 christos #else 312 1.2 christos return ENOSYS; 313 1.2 christos #endif 314 1.2 christos } 315 1.2 christos 316 1.2 christos int 317 1.2 christos compat_50_sys_mknod(struct lwp *l, 318 1.2 christos const struct compat_50_sys_mknod_args *uap, register_t *retval) 319 1.2 christos { 320 1.2 christos /* { 321 1.2 christos syscallarg(const char *) path; 322 1.2 christos syscallarg(mode_t) mode; 323 1.2 christos syscallarg(uint32_t) dev; 324 1.2 christos } */ 325 1.2 christos return do_sys_mknod(l, SCARG(uap, path), SCARG(uap, mode), 326 1.23 kamil SCARG(uap, dev), UIO_USERSPACE); 327 1.2 christos } 328 1.7 bouyer 329 1.19 pgoyette int 330 1.19 pgoyette vfs_syscalls_50_init(void) 331 1.19 pgoyette { 332 1.19 pgoyette 333 1.19 pgoyette return syscall_establish(NULL, vfs_syscalls_50_syscalls); 334 1.19 pgoyette } 335 1.19 pgoyette 336 1.19 pgoyette int 337 1.19 pgoyette vfs_syscalls_50_fini(void) 338 1.19 pgoyette { 339 1.19 pgoyette 340 1.19 pgoyette return syscall_disestablish(NULL, vfs_syscalls_50_syscalls); 341 1.19 pgoyette } 342