1 /* $NetBSD: vfs_syscalls_20.c,v 1.46 2020/06/28 14:37:53 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * (c) UNIX System Laboratories, Inc. 7 * All or some portions of this file are derived from material licensed 8 * to the University of California by American Telephone and Telegraph 9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 10 * the permission of UNIX System Laboratories, Inc. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)vfs_syscalls.c 8.42 (Berkeley) 7/31/95 37 */ 38 39 #include <sys/cdefs.h> 40 __KERNEL_RCSID(0, "$NetBSD: vfs_syscalls_20.c,v 1.46 2020/06/28 14:37:53 christos Exp $"); 41 42 #ifdef _KERNEL_OPT 43 #include "opt_compat_netbsd.h" 44 #endif 45 46 #include <sys/param.h> 47 #include <sys/systm.h> 48 #include <sys/namei.h> 49 #include <sys/filedesc.h> 50 #include <sys/kernel.h> 51 #include <sys/file.h> 52 #include <sys/stat.h> 53 #include <sys/vnode.h> 54 #include <sys/mount.h> 55 #include <sys/proc.h> 56 #include <sys/uio.h> 57 #include <sys/dirent.h> 58 #include <sys/sysctl.h> 59 #include <sys/syscall.h> 60 #include <sys/syscallvar.h> 61 #include <sys/syscallargs.h> 62 #include <sys/kauth.h> 63 #include <sys/vfs_syscalls.h> 64 65 #include <compat/common/compat_mod.h> 66 67 #include <compat/sys/mount.h> 68 #include <compat/sys/statvfs.h> 69 70 static const struct syscall_package vfs_syscalls_20_syscalls[] = { 71 { SYS_compat_20_fhstatfs, 0, (sy_call_t *)compat_20_sys_fhstatfs }, 72 { SYS_compat_20_fstatfs, 0, (sy_call_t *)compat_20_sys_fstatfs }, 73 { SYS_compat_20_getfsstat, 0, (sy_call_t *)compat_20_sys_getfsstat }, 74 { SYS_compat_20_statfs, 0, (sy_call_t *)compat_20_sys_statfs }, 75 { 0, 0, NULL } 76 }; 77 78 /* 79 * Get filesystem statistics. 80 */ 81 /* ARGSUSED */ 82 int 83 compat_20_sys_statfs(struct lwp *l, const struct compat_20_sys_statfs_args *uap, register_t *retval) 84 { 85 /* { 86 syscallarg(const char *) path; 87 syscallarg(struct statfs12 *) buf; 88 } */ 89 struct mount *mp; 90 struct statvfs *sbuf; 91 int error; 92 struct vnode *vp; 93 94 error = namei_simple_user(SCARG(uap, path), 95 NSM_FOLLOW_TRYEMULROOT, &vp); 96 if (error != 0) 97 return error; 98 99 mp = vp->v_mount; 100 101 sbuf = STATVFSBUF_GET(); 102 if ((error = dostatvfs(mp, sbuf, l, 0, 1)) != 0) 103 goto done; 104 105 error = statvfs_to_statfs12_copy(sbuf, SCARG(uap, buf), 0); 106 done: 107 vrele(vp); 108 STATVFSBUF_PUT(sbuf); 109 return error; 110 } 111 112 /* 113 * Get filesystem statistics. 114 */ 115 /* ARGSUSED */ 116 int 117 compat_20_sys_fstatfs(struct lwp *l, const struct compat_20_sys_fstatfs_args *uap, register_t *retval) 118 { 119 /* { 120 syscallarg(int) fd; 121 syscallarg(struct statfs12 *) buf; 122 } */ 123 struct file *fp; 124 struct mount *mp; 125 struct statvfs *sbuf; 126 int error; 127 128 /* fd_getvnode() will use the descriptor for us */ 129 if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) 130 return (error); 131 mp = fp->f_vnode->v_mount; 132 sbuf = STATVFSBUF_GET(); 133 if ((error = dostatvfs(mp, sbuf, l, 0, 1)) != 0) 134 goto out; 135 error = statvfs_to_statfs12_copy(sbuf, SCARG(uap, buf), 0); 136 out: 137 fd_putfile(SCARG(uap, fd)); 138 STATVFSBUF_PUT(sbuf); 139 return error; 140 } 141 142 143 /* 144 * Get statistics on all filesystems. 145 */ 146 int 147 compat_20_sys_getfsstat(struct lwp *l, const struct compat_20_sys_getfsstat_args *uap, register_t *retval) 148 { 149 /* { 150 syscallarg(struct statfs12 *) buf; 151 syscallarg(long) bufsize; 152 syscallarg(int) flags; 153 } */ 154 return do_sys_getvfsstat(l, SCARG(uap, buf), SCARG(uap, bufsize), 155 SCARG(uap, flags), statvfs_to_statfs12_copy, 156 sizeof(struct statfs12), retval); 157 } 158 159 int 160 compat_20_sys_fhstatfs(struct lwp *l, const struct compat_20_sys_fhstatfs_args *uap, register_t *retval) 161 { 162 /* { 163 syscallarg(const struct compat_30_fhandle *) fhp; 164 syscallarg(struct statfs12 *) buf; 165 } */ 166 struct statvfs *sbuf; 167 struct compat_30_fhandle fh; 168 struct mount *mp; 169 struct vnode *vp; 170 int error; 171 172 /* 173 * Must be super user 174 */ 175 if ((error = kauth_authorize_system(l->l_cred, 176 KAUTH_SYSTEM_FILEHANDLE, 0, NULL, NULL, NULL))) 177 return (error); 178 179 if ((error = copyin(SCARG(uap, fhp), &fh, sizeof(fh))) != 0) 180 return (error); 181 182 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) 183 return (ESTALE); 184 error = VFS_FHTOVP(mp, (struct fid*)&fh.fh_fid, LK_EXCLUSIVE, &vp); 185 if (error != 0) 186 return (error); 187 mp = vp->v_mount; 188 VOP_UNLOCK(vp); 189 sbuf = STATVFSBUF_GET(); 190 if ((error = VFS_STATVFS(mp, sbuf)) != 0) 191 goto out; 192 error = statvfs_to_statfs12_copy(sbuf, SCARG(uap, buf), 0); 193 out: 194 vrele(vp); 195 STATVFSBUF_PUT(sbuf); 196 return error; 197 } 198 199 int 200 vfs_syscalls_20_init(void) 201 { 202 203 return syscall_establish(NULL, vfs_syscalls_20_syscalls); 204 } 205 206 int 207 vfs_syscalls_20_fini(void) 208 { 209 210 return syscall_disestablish(NULL, vfs_syscalls_20_syscalls); 211 } 212