1 1.7 ad /* $NetBSD: ffs_quota2.c,v 1.7 2020/01/17 20:08:10 ad Exp $ */ 2 1.2 bouyer /*- 3 1.2 bouyer * Copyright (c) 2010 Manuel Bouyer 4 1.2 bouyer * All rights reserved. 5 1.2 bouyer * 6 1.2 bouyer * Redistribution and use in source and binary forms, with or without 7 1.2 bouyer * modification, are permitted provided that the following conditions 8 1.2 bouyer * are met: 9 1.2 bouyer * 1. Redistributions of source code must retain the above copyright 10 1.2 bouyer * notice, this list of conditions and the following disclaimer. 11 1.2 bouyer * 2. Redistributions in binary form must reproduce the above copyright 12 1.2 bouyer * notice, this list of conditions and the following disclaimer in the 13 1.2 bouyer * documentation and/or other materials provided with the distribution. 14 1.2 bouyer * 15 1.2 bouyer * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 1.2 bouyer * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 1.2 bouyer * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 1.2 bouyer * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 1.2 bouyer * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 1.2 bouyer * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 1.2 bouyer * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 1.2 bouyer * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 1.2 bouyer * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 1.2 bouyer * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 1.2 bouyer * POSSIBILITY OF SUCH DAMAGE. 26 1.2 bouyer */ 27 1.2 bouyer 28 1.2 bouyer #include <sys/cdefs.h> 29 1.7 ad __KERNEL_RCSID(0, "$NetBSD: ffs_quota2.c,v 1.7 2020/01/17 20:08:10 ad Exp $"); 30 1.2 bouyer 31 1.2 bouyer #include <sys/param.h> 32 1.2 bouyer #include <sys/kernel.h> 33 1.2 bouyer #include <sys/systm.h> 34 1.2 bouyer #include <sys/namei.h> 35 1.2 bouyer #include <sys/file.h> 36 1.2 bouyer #include <sys/vnode.h> 37 1.2 bouyer #include <sys/mount.h> 38 1.2 bouyer #include <sys/kauth.h> 39 1.2 bouyer 40 1.2 bouyer #include <ufs/ufs/quota2.h> 41 1.2 bouyer #include <ufs/ufs/inode.h> 42 1.2 bouyer #include <ufs/ufs/ufsmount.h> 43 1.2 bouyer #include <ufs/ffs/ffs_extern.h> 44 1.2 bouyer #include <ufs/ffs/fs.h> 45 1.2 bouyer 46 1.2 bouyer int 47 1.2 bouyer ffs_quota2_mount(struct mount *mp) 48 1.2 bouyer { 49 1.2 bouyer struct ufsmount *ump = VFSTOUFS(mp); 50 1.2 bouyer struct fs *fs = ump->um_fs; 51 1.5 maxv int error; 52 1.2 bouyer struct vnode *vp; 53 1.2 bouyer struct lwp *l = curlwp; 54 1.2 bouyer 55 1.2 bouyer if ((fs->fs_flags & FS_DOQUOTA2) == 0) 56 1.2 bouyer return 0; 57 1.2 bouyer 58 1.2 bouyer ump->um_flags |= UFS_QUOTA2; 59 1.2 bouyer ump->umq2_bsize = fs->fs_bsize; 60 1.2 bouyer ump->umq2_bmask = fs->fs_qbmask; 61 1.2 bouyer if (fs->fs_quota_magic != Q2_HEAD_MAGIC) { 62 1.5 maxv printf("%s: invalid quota magic number\n", 63 1.2 bouyer mp->mnt_stat.f_mntonname); 64 1.2 bouyer return EINVAL; 65 1.2 bouyer } 66 1.5 maxv if ((fs->fs_quota_flags & FS_Q2_DO_TYPE(USRQUOTA)) && 67 1.5 maxv fs->fs_quotafile[USRQUOTA] == 0) { 68 1.5 maxv printf("%s: no user quota inode\n", 69 1.6 msaitoh mp->mnt_stat.f_mntonname); 70 1.5 maxv return EINVAL; 71 1.5 maxv } 72 1.5 maxv if ((fs->fs_quota_flags & FS_Q2_DO_TYPE(GRPQUOTA)) && 73 1.5 maxv fs->fs_quotafile[GRPQUOTA] == 0) { 74 1.5 maxv printf("%s: no group quota inode\n", 75 1.2 bouyer mp->mnt_stat.f_mntonname); 76 1.5 maxv return EINVAL; 77 1.5 maxv } 78 1.2 bouyer 79 1.5 maxv if (fs->fs_quota_flags & FS_Q2_DO_TYPE(USRQUOTA) && 80 1.2 bouyer ump->um_quotas[USRQUOTA] == NULLVP) { 81 1.7 ad error = VFS_VGET(mp, fs->fs_quotafile[USRQUOTA], 82 1.7 ad LK_EXCLUSIVE, &vp); 83 1.2 bouyer if (error) { 84 1.2 bouyer printf("%s: can't vget() user quota inode: %d\n", 85 1.2 bouyer mp->mnt_stat.f_mntonname, error); 86 1.2 bouyer return error; 87 1.2 bouyer } 88 1.2 bouyer ump->um_quotas[USRQUOTA] = vp; 89 1.2 bouyer ump->um_cred[USRQUOTA] = l->l_cred; 90 1.4 rmind mutex_enter(vp->v_interlock); 91 1.2 bouyer vp->v_writecount++; 92 1.4 rmind mutex_exit(vp->v_interlock); 93 1.2 bouyer VOP_UNLOCK(vp); 94 1.2 bouyer } 95 1.5 maxv if (fs->fs_quota_flags & FS_Q2_DO_TYPE(GRPQUOTA) && 96 1.2 bouyer ump->um_quotas[GRPQUOTA] == NULLVP) { 97 1.7 ad error = VFS_VGET(mp, fs->fs_quotafile[GRPQUOTA], 98 1.7 ad LK_EXCLUSIVE, &vp); 99 1.2 bouyer if (error) { 100 1.2 bouyer vn_close(ump->um_quotas[USRQUOTA], 101 1.2 bouyer FREAD|FWRITE, l->l_cred); 102 1.2 bouyer printf("%s: can't vget() group quota inode: %d\n", 103 1.2 bouyer mp->mnt_stat.f_mntonname, error); 104 1.2 bouyer return error; 105 1.2 bouyer } 106 1.2 bouyer ump->um_quotas[GRPQUOTA] = vp; 107 1.2 bouyer ump->um_cred[GRPQUOTA] = l->l_cred; 108 1.4 rmind mutex_enter(vp->v_interlock); 109 1.2 bouyer vp->v_vflag |= VV_SYSTEM; 110 1.2 bouyer vp->v_writecount++; 111 1.4 rmind mutex_exit(vp->v_interlock); 112 1.2 bouyer VOP_UNLOCK(vp); 113 1.2 bouyer } 114 1.5 maxv 115 1.2 bouyer mp->mnt_flag |= MNT_QUOTA; 116 1.2 bouyer return 0; 117 1.2 bouyer } 118