aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pritchard <mpp@FreeBSD.org>2007-01-20 11:58:32 +0000
committerMike Pritchard <mpp@FreeBSD.org>2007-01-20 11:58:32 +0000
commitdb9b81eabc76221652e33df7223832eeec789eb1 (patch)
tree6a47b77ab38ba0b99bba086730b7d5d814291037
parentf0cad96d231e4047f6a50d3784b59d34b2434c21 (diff)
Notes
-rw-r--r--sys/ufs/ffs/ffs_alloc.c2
-rw-r--r--sys/ufs/ffs/ffs_snapshot.c14
-rw-r--r--sys/ufs/ufs/quota.h2
-rw-r--r--sys/ufs/ufs/ufs_quota.c53
4 files changed, 41 insertions, 30 deletions
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index 827af171d8b9..a746a69a2de5 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -188,6 +188,7 @@ retry:
*bnp = bno;
return (0);
}
+nospace:
#ifdef QUOTA
UFS_UNLOCK(ump);
/*
@@ -196,7 +197,6 @@ retry:
(void) chkdq(ip, -btodb(size), cred, FORCE);
UFS_LOCK(ump);
#endif
-nospace:
if (fs->fs_pendingblocks > 0 && reclaimed == 0) {
reclaimed = 1;
softdep_request_cleanup(fs, ITOV(ip));
diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c
index 6ab9af25bcde..14b231cda6eb 100644
--- a/sys/ufs/ffs/ffs_snapshot.c
+++ b/sys/ufs/ffs/ffs_snapshot.c
@@ -281,6 +281,7 @@ restart:
return (error);
}
vp = nd.ni_vp;
+ vp->v_vflag |= VV_SYSTEM;
ip = VTOI(vp);
devvp = ip->i_devvp;
/*
@@ -367,18 +368,6 @@ restart:
if (error)
goto out;
}
-#ifdef QUOTA
- /*
- * Turn off disk quotas for snapshot file.
- */
- (void) chkdq(ip, -DIP(ip, i_blocks), KERNCRED, FORCE);
- for (i = 0; i < MAXQUOTAS; i++) {
- if (ip->i_dquot[i] != NODQUOT) {
- dqrele(vp, ip->i_dquot[i]);
- ip->i_dquot[i] = NODQUOT;
- }
- }
-#endif
/*
* Change inode to snapshot type file.
*/
@@ -682,7 +671,6 @@ loop:
devvp->v_vflag |= VV_COPYONWRITE;
VI_UNLOCK(devvp);
ASSERT_VOP_LOCKED(vp, "ffs_snapshot vp");
- vp->v_vflag |= VV_SYSTEM;
out1:
KASSERT((sn != NULL && sbp != NULL && error == 0) ||
(sn == NULL && sbp == NULL && error != 0),
diff --git a/sys/ufs/ufs/quota.h b/sys/ufs/ufs/quota.h
index 8fb9eb267c18..a42493e8f17e 100644
--- a/sys/ufs/ufs/quota.h
+++ b/sys/ufs/ufs/quota.h
@@ -174,7 +174,7 @@ struct ucred;
struct vnode;
int chkdq(struct inode *, int64_t, struct ucred *, int);
-int chkiq(struct inode *, ino_t, struct ucred *, int);
+int chkiq(struct inode *, int, struct ucred *, int);
void dqinit(void);
void dqrele(struct vnode *, struct dquot *);
void dquninit(void);
diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c
index c4a93cdbfb7f..a3f426bc7902 100644
--- a/sys/ufs/ufs/ufs_quota.c
+++ b/sys/ufs/ufs/ufs_quota.c
@@ -72,7 +72,7 @@ static MALLOC_DEFINE(M_DQUOT, "ufs_quota", "UFS quota entries");
static char *quotatypes[] = INITQFNAMES;
static int chkdqchg(struct inode *, ufs2_daddr_t, struct ucred *, int);
-static int chkiqchg(struct inode *, ino_t, struct ucred *, int);
+static int chkiqchg(struct inode *, int, struct ucred *, int);
static int dqget(struct vnode *,
u_long, struct ufsmount *, int, struct dquot **);
static int dqsync(struct vnode *, struct dquot *);
@@ -99,13 +99,18 @@ getinoquota(ip)
struct vnode *vp = ITOV(ip);
int error;
-#ifndef NO_FFS_SNAPSHOT
/*
- * Disk quotas must be turned off for snapshot files.
+ * Disk quotas must be turned off for system files. Currently
+ * snapshot and quota files.
*/
- if ((ip->i_flags & SF_SNAPSHOT) != 0)
+ if ((vp->v_vflag & VV_SYSTEM) != 0)
+ return (0);
+ /*
+ * XXX: Turn off quotas for files with a negative UID or GID.
+ * This prevents the creation of 100GB+ quota files.
+ */
+ if ((int)ip->i_uid < 0 || (int)ip->i_gid < 0)
return (0);
-#endif
ump = VFSTOUFS(vp->v_mount);
/*
* Set up the user quota based on file uid.
@@ -140,8 +145,21 @@ chkdq(ip, change, cred, flags)
{
struct dquot *dq;
ufs2_daddr_t ncurblocks;
+ struct vnode *vp = ITOV(ip);
int i, error;
+ /*
+ * Disk quotas must be turned off for system files. Currently
+ * snapshot and quota files.
+ */
+ if ((vp->v_vflag & VV_SYSTEM) != 0)
+ return (0);
+ /*
+ * XXX: Turn off quotas for files with a negative UID or GID.
+ * This prevents the creation of 100GB+ quota files.
+ */
+ if ((int)ip->i_uid < 0 || (int)ip->i_gid < 0)
+ return (0);
#ifdef DIAGNOSTIC
if ((flags & CHOWN) == 0)
chkdquot(ip);
@@ -256,7 +274,7 @@ chkdqchg(ip, change, cred, type)
int
chkiq(ip, change, cred, flags)
struct inode *ip;
- ino_t change;
+ int change;
struct ucred *cred;
int flags;
{
@@ -270,7 +288,6 @@ chkiq(ip, change, cred, flags)
#endif
if (change == 0)
return (0);
- /* XXX: change is unsigned */
if (change < 0) {
for (i = 0; i < MAXQUOTAS; i++) {
if ((dq = ip->i_dquot[i]) == NODQUOT)
@@ -281,7 +298,7 @@ chkiq(ip, change, cred, flags)
}
ncurinodes = dq->dq_curinodes + change;
/* XXX: ncurinodes is unsigned */
- if (ncurinodes >= 0)
+ if (dq->dq_curinodes != 0 && ncurinodes >= 0)
dq->dq_curinodes = ncurinodes;
else
dq->dq_curinodes = 0;
@@ -325,7 +342,7 @@ chkiq(ip, change, cred, flags)
static int
chkiqchg(ip, change, cred, type)
struct inode *ip;
- ino_t change;
+ int change;
struct ucred *cred;
int type;
{
@@ -384,15 +401,21 @@ chkdquot(ip)
struct inode *ip;
{
struct ufsmount *ump = VFSTOUFS(ITOV(ip)->v_mount);
+ struct vnode *vp = ITOV(ip);
int i;
-#ifndef NO_FFS_SNAPSHOT
/*
- * Disk quotas must be turned off for snapshot files.
+ * Disk quotas must be turned off for system files. Currently
+ * these are snapshots and quota files.
*/
- if ((ip->i_flags & SF_SNAPSHOT) != 0)
+ if ((vp->v_vflag & VV_SYSTEM) != 0)
return;
-#endif
+ /*
+ * XXX: Turn off quotas for files with a negative UID or GID.
+ * This prevents the creation of 100GB+ quota files.
+ */
+ if ((int)ip->i_uid < 0 || (int)ip->i_gid < 0)
+ return (0);
for (i = 0; i < MAXQUOTAS; i++) {
if (ump->um_quotas[i] == NULLVP ||
(ump->um_qflags[i] & (QTF_OPENING|QTF_CLOSING)))
@@ -929,7 +952,7 @@ dqget(vp, id, ump, type, dqp)
aiov.iov_base = &dq->dq_dqb;
aiov.iov_len = sizeof (struct dqblk);
auio.uio_resid = sizeof (struct dqblk);
- auio.uio_offset = (off_t)(id * sizeof (struct dqblk));
+ auio.uio_offset = (off_t)id * sizeof (struct dqblk);
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_rw = UIO_READ;
auio.uio_td = (struct thread *)0;
@@ -1044,7 +1067,7 @@ dqsync(vp, dq)
aiov.iov_base = &dq->dq_dqb;
aiov.iov_len = sizeof (struct dqblk);
auio.uio_resid = sizeof (struct dqblk);
- auio.uio_offset = (off_t)(dq->dq_id * sizeof (struct dqblk));
+ auio.uio_offset = (off_t)dq->dq_id * sizeof (struct dqblk);
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_rw = UIO_WRITE;
auio.uio_td = (struct thread *)0;