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