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