1/* $NetBSD: ffs_quota2.c,v 1.7 2020/01/17 20:08:10 ad 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.7 2020/01/17 20:08:10 ad 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/vnode.h> 37#include <sys/mount.h> 38#include <sys/kauth.h> 39 40#include <ufs/ufs/quota2.h> 41#include <ufs/ufs/inode.h> 42#include <ufs/ufs/ufsmount.h> 43#include <ufs/ffs/ffs_extern.h> 44#include <ufs/ffs/fs.h> 45 46int 47ffs_quota2_mount(struct mount *mp) 48{ 49 struct ufsmount *ump = VFSTOUFS(mp); 50 struct fs *fs = ump->um_fs; 51 int error; 52 struct vnode *vp; 53 struct lwp *l = curlwp; 54 55 if ((fs->fs_flags & FS_DOQUOTA2) == 0) 56 return 0; 57 58 ump->um_flags |= UFS_QUOTA2; 59 ump->umq2_bsize = fs->fs_bsize; 60 ump->umq2_bmask = fs->fs_qbmask; 61 if (fs->fs_quota_magic != Q2_HEAD_MAGIC) { 62 printf("%s: invalid quota magic number\n", 63 mp->mnt_stat.f_mntonname); 64 return EINVAL; 65 } 66 if ((fs->fs_quota_flags & FS_Q2_DO_TYPE(USRQUOTA)) && 67 fs->fs_quotafile[USRQUOTA] == 0) { 68 printf("%s: no user quota inode\n", 69 mp->mnt_stat.f_mntonname); 70 return EINVAL; 71 } 72 if ((fs->fs_quota_flags & FS_Q2_DO_TYPE(GRPQUOTA)) && 73 fs->fs_quotafile[GRPQUOTA] == 0) { 74 printf("%s: no group quota inode\n", 75 mp->mnt_stat.f_mntonname); 76 return EINVAL; 77 } 78 79 if (fs->fs_quota_flags & FS_Q2_DO_TYPE(USRQUOTA) && 80 ump->um_quotas[USRQUOTA] == NULLVP) { 81 error = VFS_VGET(mp, fs->fs_quotafile[USRQUOTA], 82 LK_EXCLUSIVE, &vp); 83 if (error) { 84 printf("%s: can't vget() user quota inode: %d\n", 85 mp->mnt_stat.f_mntonname, error); 86 return error; 87 } 88 ump->um_quotas[USRQUOTA] = vp; 89 ump->um_cred[USRQUOTA] = l->l_cred; 90 mutex_enter(vp->v_interlock); 91 vp->v_writecount++; 92 mutex_exit(vp->v_interlock); 93 VOP_UNLOCK(vp); 94 } 95 if (fs->fs_quota_flags & FS_Q2_DO_TYPE(GRPQUOTA) && 96 ump->um_quotas[GRPQUOTA] == NULLVP) { 97 error = VFS_VGET(mp, fs->fs_quotafile[GRPQUOTA], 98 LK_EXCLUSIVE, &vp); 99 if (error) { 100 vn_close(ump->um_quotas[USRQUOTA], 101 FREAD|FWRITE, l->l_cred); 102 printf("%s: can't vget() group quota inode: %d\n", 103 mp->mnt_stat.f_mntonname, error); 104 return error; 105 } 106 ump->um_quotas[GRPQUOTA] = vp; 107 ump->um_cred[GRPQUOTA] = l->l_cred; 108 mutex_enter(vp->v_interlock); 109 vp->v_vflag |= VV_SYSTEM; 110 vp->v_writecount++; 111 mutex_exit(vp->v_interlock); 112 VOP_UNLOCK(vp); 113 } 114 115 mp->mnt_flag |= MNT_QUOTA; 116 return 0; 117} 118