1/* $NetBSD: compat_50_quota.c,v 1.4 2022/09/21 07:15:24 dholland Exp $ */ 2 3/*- 4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Christos Zoulas. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31#include <sys/cdefs.h> 32__KERNEL_RCSID(0, "$NetBSD: compat_50_quota.c,v 1.4 2022/09/21 07:15:24 dholland Exp $"); 33 34#if defined(_KERNEL_OPT) 35#include "opt_compat_netbsd.h" 36#endif 37 38#include <sys/module.h> 39#include <sys/namei.h> 40#include <sys/param.h> 41#include <sys/quota.h> 42#include <sys/quotactl.h> 43#include <sys/systm.h> 44#include <sys/syscall.h> 45#include <sys/syscallvar.h> 46#include <sys/syscallargs.h> 47#include <sys/vfs_syscalls.h> 48#include <sys/vnode.h> 49 50#include <ufs/ufs/quota1.h> 51 52static const struct syscall_package vfs_syscalls_50_quota_syscalls[] = { 53 { SYS_compat_50_quotactl, 0, (sy_call_t *)compat_50_sys_quotactl }, 54 { 0, 0, NULL } 55}; 56 57/* ARGSUSED */ 58int 59compat_50_sys_quotactl(struct lwp *l, const struct compat_50_sys_quotactl_args *uap, register_t *retval) 60{ 61 /* { 62 syscallarg(const char *) path; 63 syscallarg(int) cmd; 64 syscallarg(int) uid; 65 syscallarg(void *) arg; 66 } */ 67 struct vnode *vp; 68 struct mount *mp; 69 int q1cmd; 70 int idtype; 71 char *qfile; 72 struct dqblk dqblk; 73 struct quotakey key; 74 struct quotaval blocks, files; 75 struct quotastat qstat; 76 int error; 77 78 error = namei_simple_user(SCARG(uap, path), 79 NSM_FOLLOW_TRYEMULROOT, &vp); 80 if (error != 0) 81 return (error); 82 83 mp = vp->v_mount; 84 q1cmd = SCARG(uap, cmd); 85 idtype = quota_idtype_from_ufs(q1cmd & SUBCMDMASK); 86 if (idtype == -1) { 87 return EINVAL; 88 } 89 90 switch ((q1cmd & ~SUBCMDMASK) >> SUBCMDSHIFT) { 91 case Q_QUOTAON: 92 qfile = PNBUF_GET(); 93 error = copyinstr(SCARG(uap, arg), qfile, PATH_MAX, NULL); 94 if (error != 0) { 95 PNBUF_PUT(qfile); 96 break; 97 } 98 99 error = vfs_quotactl_quotaon(mp, idtype, qfile); 100 101 PNBUF_PUT(qfile); 102 break; 103 104 case Q_QUOTAOFF: 105 error = vfs_quotactl_quotaoff(mp, idtype); 106 break; 107 108 case Q_GETQUOTA: 109 key.qk_idtype = idtype; 110 key.qk_id = SCARG(uap, uid); 111 112 key.qk_objtype = QUOTA_OBJTYPE_BLOCKS; 113 error = vfs_quotactl_get(mp, &key, &blocks); 114 if (error) { 115 break; 116 } 117 118 key.qk_objtype = QUOTA_OBJTYPE_FILES; 119 error = vfs_quotactl_get(mp, &key, &files); 120 if (error) { 121 break; 122 } 123 124 quotavals_to_dqblk(&blocks, &files, &dqblk); 125 error = copyout(&dqblk, SCARG(uap, arg), sizeof(dqblk)); 126 break; 127 128 case Q_SETQUOTA: 129 error = copyin(SCARG(uap, arg), &dqblk, sizeof(dqblk)); 130 if (error) { 131 break; 132 } 133 dqblk_to_quotavals(&dqblk, &blocks, &files); 134 135 key.qk_idtype = idtype; 136 key.qk_id = SCARG(uap, uid); 137 138 key.qk_objtype = QUOTA_OBJTYPE_BLOCKS; 139 error = vfs_quotactl_put(mp, &key, &blocks); 140 if (error) { 141 break; 142 } 143 144 key.qk_objtype = QUOTA_OBJTYPE_FILES; 145 error = vfs_quotactl_put(mp, &key, &files); 146 break; 147 148 case Q_SYNC: 149 /* 150 * not supported but used only to see if quota is supported, 151 * emulate with stat 152 * 153 * XXX should probably be supported 154 */ 155 (void)idtype; /* not used */ 156 157 error = vfs_quotactl_stat(mp, &qstat); 158 break; 159 160 case Q_SETUSE: 161 default: 162 error = EOPNOTSUPP; 163 break; 164 } 165 166 vrele(vp); 167 return error; 168} 169 170MODULE(MODULE_CLASS_EXEC, compat_50_quota, "compat_50,ufs"); 171 172static int 173compat_50_quota_modcmd(modcmd_t cmd, void *arg) 174{ 175 176 switch (cmd) { 177 case MODULE_CMD_INIT: 178 return syscall_establish(NULL, vfs_syscalls_50_quota_syscalls); 179 case MODULE_CMD_FINI: 180 return syscall_disestablish(NULL, vfs_syscalls_50_quota_syscalls); 181 default: 182 return ENOTTY; 183 } 184} 185