Module Name: src Committed By: bouyer Date: Mon Jan 31 15:24:11 UTC 2011
Modified Files: src/sys/ufs/ufs [bouyer-quota2]: quota1_subr.c quota2_prop.c quota2_subr.c ufs_quota.c ufs_quota.h ufs_quota1.c ufs_quota2.c Log Message: Catch up with Q2V -> QL renaming Enforce limits for quota2. pass quota type (*QUOTA) and limit type (QL_*) to KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT, to make it possible to skip limit checks for some quota type only if a listener wants to. To generate a diff of this commit: cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/sys/ufs/ufs/quota1_subr.c \ src/sys/ufs/ufs/ufs_quota1.c cvs rdiff -u -r1.1.2.3 -r1.1.2.4 src/sys/ufs/ufs/quota2_prop.c \ src/sys/ufs/ufs/quota2_subr.c src/sys/ufs/ufs/ufs_quota.h cvs rdiff -u -r1.68.4.5 -r1.68.4.6 src/sys/ufs/ufs/ufs_quota.c cvs rdiff -u -r1.1.2.5 -r1.1.2.6 src/sys/ufs/ufs/ufs_quota2.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/ufs/ufs/quota1_subr.c diff -u src/sys/ufs/ufs/quota1_subr.c:1.1.2.1 src/sys/ufs/ufs/quota1_subr.c:1.1.2.2 --- src/sys/ufs/ufs/quota1_subr.c:1.1.2.1 Fri Jan 28 23:31:16 2011 +++ src/sys/ufs/ufs/quota1_subr.c Mon Jan 31 15:24:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: quota1_subr.c,v 1.1.2.1 2011/01/28 23:31:16 bouyer Exp $ */ +/* $NetBSD: quota1_subr.c,v 1.1.2.2 2011/01/31 15:24:10 bouyer Exp $ */ /*- * Copyright (c) 2010 Manuel Bouyer * All rights reserved. @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: quota1_subr.c,v 1.1.2.1 2011/01/28 23:31:16 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: quota1_subr.c,v 1.1.2.2 2011/01/31 15:24:10 bouyer Exp $"); #include <sys/types.h> #include <machine/limits.h> @@ -61,35 +61,35 @@ void dqblk2q2e(const struct dqblk *dqblk, struct quota2_entry *q2e) { - q2e->q2e_val[Q2V_BLOCK].q2v_hardlimit = + q2e->q2e_val[QL_BLOCK].q2v_hardlimit = dqblk2q2e_limit(dqblk->dqb_bhardlimit); - q2e->q2e_val[Q2V_BLOCK].q2v_softlimit = + q2e->q2e_val[QL_BLOCK].q2v_softlimit = dqblk2q2e_limit(dqblk->dqb_bsoftlimit); - q2e->q2e_val[Q2V_BLOCK].q2v_cur = dqblk->dqb_curblocks; - q2e->q2e_val[Q2V_BLOCK].q2v_time = dqblk->dqb_btime; + q2e->q2e_val[QL_BLOCK].q2v_cur = dqblk->dqb_curblocks; + q2e->q2e_val[QL_BLOCK].q2v_time = dqblk->dqb_btime; - q2e->q2e_val[Q2V_FILE].q2v_hardlimit = + q2e->q2e_val[QL_FILE].q2v_hardlimit = dqblk2q2e_limit(dqblk->dqb_ihardlimit); - q2e->q2e_val[Q2V_FILE].q2v_softlimit = + q2e->q2e_val[QL_FILE].q2v_softlimit = dqblk2q2e_limit(dqblk->dqb_isoftlimit); - q2e->q2e_val[Q2V_FILE].q2v_cur = dqblk->dqb_curinodes; - q2e->q2e_val[Q2V_FILE].q2v_time = dqblk->dqb_itime; + q2e->q2e_val[QL_FILE].q2v_cur = dqblk->dqb_curinodes; + q2e->q2e_val[QL_FILE].q2v_time = dqblk->dqb_itime; } void q2e2dqblk(const struct quota2_entry *q2e, struct dqblk *dqblk) { dqblk->dqb_bhardlimit = - q2e2dqblk_limit(q2e->q2e_val[Q2V_BLOCK].q2v_hardlimit); + q2e2dqblk_limit(q2e->q2e_val[QL_BLOCK].q2v_hardlimit); dqblk->dqb_bsoftlimit = - q2e2dqblk_limit(q2e->q2e_val[Q2V_BLOCK].q2v_softlimit); - dqblk->dqb_curblocks = q2e->q2e_val[Q2V_BLOCK].q2v_cur; - dqblk->dqb_btime = q2e->q2e_val[Q2V_BLOCK].q2v_time; + q2e2dqblk_limit(q2e->q2e_val[QL_BLOCK].q2v_softlimit); + dqblk->dqb_curblocks = q2e->q2e_val[QL_BLOCK].q2v_cur; + dqblk->dqb_btime = q2e->q2e_val[QL_BLOCK].q2v_time; dqblk->dqb_ihardlimit = - q2e2dqblk_limit(q2e->q2e_val[Q2V_FILE].q2v_hardlimit); + q2e2dqblk_limit(q2e->q2e_val[QL_FILE].q2v_hardlimit); dqblk->dqb_isoftlimit = - q2e2dqblk_limit(q2e->q2e_val[Q2V_FILE].q2v_softlimit); - dqblk->dqb_curinodes = q2e->q2e_val[Q2V_FILE].q2v_cur; - dqblk->dqb_itime = q2e->q2e_val[Q2V_FILE].q2v_time; + q2e2dqblk_limit(q2e->q2e_val[QL_FILE].q2v_softlimit); + dqblk->dqb_curinodes = q2e->q2e_val[QL_FILE].q2v_cur; + dqblk->dqb_itime = q2e->q2e_val[QL_FILE].q2v_time; } Index: src/sys/ufs/ufs/ufs_quota1.c diff -u src/sys/ufs/ufs/ufs_quota1.c:1.1.2.1 src/sys/ufs/ufs/ufs_quota1.c:1.1.2.2 --- src/sys/ufs/ufs/ufs_quota1.c:1.1.2.1 Thu Jan 20 14:25:03 2011 +++ src/sys/ufs/ufs/ufs_quota1.c Mon Jan 31 15:24:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_quota1.c,v 1.1.2.1 2011/01/20 14:25:03 bouyer Exp $ */ +/* $NetBSD: ufs_quota1.c,v 1.1.2.2 2011/01/31 15:24:10 bouyer Exp $ */ /* * Copyright (c) 1982, 1986, 1990, 1993, 1995 @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ufs_quota1.c,v 1.1.2.1 2011/01/20 14:25:03 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ufs_quota1.c,v 1.1.2.2 2011/01/31 15:24:10 bouyer Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -88,12 +88,13 @@ } return (0); } - if ((flags & FORCE) == 0 && - kauth_authorize_system(cred, KAUTH_SYSTEM_FS_QUOTA, - KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT, NULL, NULL, NULL) != 0) { - for (i = 0; i < MAXQUOTAS; i++) { - if ((dq = ip->i_dquot[i]) == NODQUOT) - continue; + for (i = 0; i < MAXQUOTAS; i++) { + if ((dq = ip->i_dquot[i]) == NODQUOT) + continue; + if ((flags & FORCE) == 0 && + kauth_authorize_system(cred, KAUTH_SYSTEM_FS_QUOTA, + KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT, KAUTH_ARG(i), + KAUTH_ARG(QL_BLOCK), NULL) != 0) { mutex_enter(&dq->dq_interlock); error = chkdqchg(ip, change, cred, i); mutex_exit(&dq->dq_interlock); @@ -195,12 +196,12 @@ } return (0); } - if ((flags & FORCE) == 0 && kauth_authorize_system(cred, - KAUTH_SYSTEM_FS_QUOTA, KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT, NULL, - NULL, NULL) != 0) { - for (i = 0; i < MAXQUOTAS; i++) { - if ((dq = ip->i_dquot[i]) == NODQUOT) - continue; + for (i = 0; i < MAXQUOTAS; i++) { + if ((dq = ip->i_dquot[i]) == NODQUOT) + continue; + if ((flags & FORCE) == 0 && kauth_authorize_system(cred, + KAUTH_SYSTEM_FS_QUOTA, KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT, + KAUTH_ARG(i), KAUTH_ARG(QL_FILE), NULL) != 0) { mutex_enter(&dq->dq_interlock); error = chkiqchg(ip, change, cred, i); mutex_exit(&dq->dq_interlock); Index: src/sys/ufs/ufs/quota2_prop.c diff -u src/sys/ufs/ufs/quota2_prop.c:1.1.2.3 src/sys/ufs/ufs/quota2_prop.c:1.1.2.4 --- src/sys/ufs/ufs/quota2_prop.c:1.1.2.3 Sun Jan 30 00:25:19 2011 +++ src/sys/ufs/ufs/quota2_prop.c Mon Jan 31 15:24:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: quota2_prop.c,v 1.1.2.3 2011/01/30 00:25:19 bouyer Exp $ */ +/* $NetBSD: quota2_prop.c,v 1.1.2.4 2011/01/31 15:24:10 bouyer Exp $ */ /*- * Copyright (c) 2010 Manuel Bouyer * All rights reserved. @@ -34,7 +34,7 @@ #include <ufs/ufs/quota2_prop.h> -const char *quota2_valnames[] = QUOTA2_VALNAMES_INIT; +const char *quota2_valnames[] = INITQLNAMES; prop_dictionary_t prop_dictionary_get_dict(prop_dictionary_t dict, const char *key) @@ -76,7 +76,7 @@ { int i, error; prop_dictionary_t val; - for (i = 0; i < NQ2V; i++) { + for (i = 0; i < N_QL; i++) { val = prop_dictionary_get_dict(data, quota2_valnames[i]); if (val == NULL) continue; @@ -111,7 +111,7 @@ { int i, error; prop_dictionary_t val; - for (i = 0; i < NQ2V; i++) { + for (i = 0; i < N_QL; i++) { val = prop_dictionary_get_dict(data, quota2_valnames[i]); if (val == NULL) return EINVAL; @@ -269,7 +269,7 @@ goto err; } } - for (i = 0; i < NQ2V; i++) { + for (i = 0; i < N_QL; i++) { dict2 = q2vtoprop(&q2e->q2e_val[i]); if (dict2 == NULL) goto err; Index: src/sys/ufs/ufs/quota2_subr.c diff -u src/sys/ufs/ufs/quota2_subr.c:1.1.2.3 src/sys/ufs/ufs/quota2_subr.c:1.1.2.4 --- src/sys/ufs/ufs/quota2_subr.c:1.1.2.3 Fri Jan 28 23:30:34 2011 +++ src/sys/ufs/ufs/quota2_subr.c Mon Jan 31 15:24:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: quota2_subr.c,v 1.1.2.3 2011/01/28 23:30:34 bouyer Exp $ */ +/* $NetBSD: quota2_subr.c,v 1.1.2.4 2011/01/31 15:24:10 bouyer Exp $ */ /*- * Copyright (c) 2010 Manuel Bouyer * All rights reserved. @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: quota2_subr.c,v 1.1.2.3 2011/01/28 23:30:34 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: quota2_subr.c,v 1.1.2.4 2011/01/31 15:24:10 bouyer Exp $"); #include <sys/param.h> #include <sys/time.h> @@ -76,7 +76,7 @@ q2h->q2h_hash_shift = q2h_hash_shift; q2h->q2h_hash_size = ufs_rw16(quota2_hash_size, ns); /* setup defaut entry: unlimited, 7 days grace */ - for (i = 0; i < NQ2V; i++) { + for (i = 0; i < N_QL; i++) { q2h->q2h_defentry.q2e_val[i].q2v_hardlimit = q2h->q2h_defentry.q2e_val[i].q2v_softlimit = ufs_rw64(UQUAD_MAX, ns); @@ -102,9 +102,9 @@ quota2_ufs_rwq2e(const struct quota2_entry *s, struct quota2_entry *d, int needswap) { - quota2_ufs_rwq2v(&s->q2e_val[Q2V_BLOCK], &d->q2e_val[Q2V_BLOCK], + quota2_ufs_rwq2v(&s->q2e_val[QL_BLOCK], &d->q2e_val[QL_BLOCK], needswap); - quota2_ufs_rwq2v(&s->q2e_val[Q2V_FILE], &d->q2e_val[Q2V_FILE], + quota2_ufs_rwq2v(&s->q2e_val[QL_FILE], &d->q2e_val[QL_FILE], needswap); d->q2e_uid = ufs_rw32(s->q2e_uid, needswap); } Index: src/sys/ufs/ufs/ufs_quota.h diff -u src/sys/ufs/ufs/ufs_quota.h:1.1.2.3 src/sys/ufs/ufs/ufs_quota.h:1.1.2.4 --- src/sys/ufs/ufs/ufs_quota.h:1.1.2.3 Sun Jan 30 00:25:20 2011 +++ src/sys/ufs/ufs/ufs_quota.h Mon Jan 31 15:24:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_quota.h,v 1.1.2.3 2011/01/30 00:25:20 bouyer Exp $ */ +/* $NetBSD: ufs_quota.h,v 1.1.2.4 2011/01/31 15:24:10 bouyer Exp $ */ /* * Copyright (c) 1982, 1986, 1990, 1993, 1995 @@ -73,8 +73,7 @@ */ #define DQ_MOD 0x04 /* this quota modified since read */ #define DQ_FAKE 0x08 /* no limits here, just usage */ -#define DQ_BLKS 0x10 /* has been warned about blk limit */ -#define DQ_INODS 0x20 /* has been warned about inode limit */ +#define DQ_WARN(ltype) (0x10 << ltype) /* has been warned about "type" limit */ /* * Shorthand notation. */ Index: src/sys/ufs/ufs/ufs_quota.c diff -u src/sys/ufs/ufs/ufs_quota.c:1.68.4.5 src/sys/ufs/ufs/ufs_quota.c:1.68.4.6 --- src/sys/ufs/ufs/ufs_quota.c:1.68.4.5 Sun Jan 30 19:38:46 2011 +++ src/sys/ufs/ufs/ufs_quota.c Mon Jan 31 15:24:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_quota.c,v 1.68.4.5 2011/01/30 19:38:46 bouyer Exp $ */ +/* $NetBSD: ufs_quota.c,v 1.68.4.6 2011/01/31 15:24:10 bouyer Exp $ */ /* * Copyright (c) 1982, 1986, 1990, 1993, 1995 @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.68.4.5 2011/01/30 19:38:46 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.68.4.6 2011/01/31 15:24:10 bouyer Exp $"); #if defined(_KERNEL_OPT) #include "opt_quota.h" @@ -682,7 +682,6 @@ return 0; } - #ifdef DIAGNOSTIC /* * Check the hash chains for stray dquot's. Index: src/sys/ufs/ufs/ufs_quota2.c diff -u src/sys/ufs/ufs/ufs_quota2.c:1.1.2.5 src/sys/ufs/ufs/ufs_quota2.c:1.1.2.6 --- src/sys/ufs/ufs/ufs_quota2.c:1.1.2.5 Sun Jan 30 00:25:20 2011 +++ src/sys/ufs/ufs/ufs_quota2.c Mon Jan 31 15:24:11 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_quota2.c,v 1.1.2.5 2011/01/30 00:25:20 bouyer Exp $ */ +/* $NetBSD: ufs_quota2.c,v 1.1.2.6 2011/01/31 15:24:11 bouyer Exp $ */ /*- * Copyright (c) 2010 Manuel Bouyer * All rights reserved. @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.1.2.5 2011/01/30 00:25:20 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.1.2.6 2011/01/31 15:24:11 bouyer Exp $"); #include <sys/buf.h> #include <sys/param.h> @@ -71,7 +71,10 @@ struct quota2_entry **, int); static int quota2_walk_list(struct ufsmount *, struct buf *, int, uint64_t *, int, void *, - int (*func)(struct ufsmount *, uint64_t *, struct quota2_entry *, uint64_t, void *)); + int (*func)(struct ufsmount *, uint64_t *, struct quota2_entry *, + uint64_t, void *)); + +static const char *valtypes[] = INITQLNAMES; static int getq2h(struct ufsmount *ump, int type, @@ -354,8 +357,9 @@ int error; struct buf *bp[MAXQUOTAS]; struct quota2_entry *q2e[MAXQUOTAS]; + struct quota2_val *q2v; struct dquot *dq; - int64_t ncurblks; + uint64_t ncurblks, soft, hard; struct ufsmount *ump = ip->i_ump; const int needswap = UFS_MPNEEDSWAP(ump); int i; @@ -373,40 +377,103 @@ } return 0; } - if (change < 0 || change > 0) { + if (change < 0) { for (i = 0; i < MAXQUOTAS; i++) { dq = ip->i_dquot[i]; if (dq == NODQUOT) continue; - if (q2e[i] == NULL) + if (q2e[i] == NULL) { + mutex_exit(&dq->dq_interlock); continue; - ncurblks = - ufs_rw64(q2e[i]->q2e_val[vtype].q2v_cur, needswap); - if (change < 0 && ncurblks < -change) + } + q2v = &q2e[i]->q2e_val[vtype]; + ncurblks = ufs_rw64(q2v->q2v_cur, needswap); + if (ncurblks < -change) ncurblks = 0; else ncurblks += change; - q2e[i]->q2e_val[vtype].q2v_cur = - ufs_rw64(ncurblks, needswap); + q2v->q2v_cur = ufs_rw64(ncurblks, needswap); VOP_BWRITE(bp[i]); mutex_exit(&dq->dq_interlock); } return 0; } + /* see if the allocation is allowed */ + for (i = 0; i < MAXQUOTAS; i++) { + if ((flags & FORCE) != 0 || + kauth_authorize_system(cred, KAUTH_SYSTEM_FS_QUOTA, + KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT, + KAUTH_ARG(i), KAUTH_ARG(vtype), NULL) == 0) { + /* don't check this limit */ + continue; + } + dq = ip->i_dquot[i]; + if (dq == NODQUOT) + continue; + KASSERT(q2e[i] != NULL); + q2v = &q2e[i]->q2e_val[vtype]; + ncurblks = ufs_rw64(q2v->q2v_cur, needswap); + soft = ufs_rw64(q2v->q2v_softlimit, needswap); + hard = ufs_rw64(q2v->q2v_hardlimit, needswap); + if (ncurblks + change >= hard) { + if ((dq->dq_flags & DQ_WARN(vtype)) == 0) { + uprintf("\n%s: write failed, %s %s limit " + "reached\n", + ITOV(ip)->v_mount->mnt_stat.f_mntonname, + quotatypes[i], valtypes[vtype]); + dq->dq_flags |= DQ_WARN(vtype); + } + error = EDQUOT; + } else if (ncurblks >= soft && + time_second > ufs_rw64(q2v->q2v_time, needswap)) { + if ((dq->dq_flags & DQ_WARN(vtype)) == 0) { + uprintf("\n%s: write failed, %s %s " + "limit reached\n", + ump->um_mountp->mnt_stat.f_mntonname, + quotatypes[i], valtypes[vtype]); + dq->dq_flags |= DQ_WARN(vtype); + } + error = EDQUOT; + } + } - return 0; + /* now do the allocation if allowed */ + for (i = 0; i < MAXQUOTAS; i++) { + dq = ip->i_dquot[i]; + if (dq == NODQUOT) + continue; + KASSERT(q2e[i] != NULL); + if (error == 0) { + q2v = &q2e[i]->q2e_val[vtype]; + ncurblks = ufs_rw64(q2v->q2v_cur, needswap); + soft = ufs_rw64(q2v->q2v_softlimit, needswap); + if (ncurblks < soft && (ncurblks + change) >= soft) { + q2v->q2v_time = ufs_rw64(time_second + + ufs_rw64(q2v->q2v_grace, needswap), + needswap); + uprintf("\n%s: warning, %s %s quota exceeded\n", + ump->um_mountp->mnt_stat.f_mntonname, + quotatypes[i], valtypes[vtype]); + } + q2v->q2v_cur = ufs_rw64(ncurblks + change, needswap); + VOP_BWRITE(bp[i]); + } else + brelse(bp[i], 0); + mutex_exit(&dq->dq_interlock); + } + return error; } int chkdq2(struct inode *ip, int64_t change, kauth_cred_t cred, int flags) { - return quota2_check(ip, Q2V_BLOCK, change, cred, flags); + return quota2_check(ip, QL_BLOCK, change, cred, flags); } int chkiq2(struct inode *ip, int32_t change, kauth_cred_t cred, int flags) { - return quota2_check(ip, Q2V_FILE, change, cred, flags); + return quota2_check(ip, QL_FILE, change, cred, flags); } int