summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2011-06-10 22:19:44 +0000
committerjeff <jeff@FreeBSD.org>2011-06-10 22:19:44 +0000
commitaee45716ce4441d848c1ad13aa99f30b06ebae77 (patch)
tree60a83de4d8c75bc2a228e898298b84af74e7745d /sys/ufs
parent2cdd0660a5978b8ea67c7857423395ceb93c8439 (diff)
downloadFreeBSD-src-aee45716ce4441d848c1ad13aa99f30b06ebae77.zip
FreeBSD-src-aee45716ce4441d848c1ad13aa99f30b06ebae77.tar.gz
- Add support for referencing quota structures without needing the inode
pointer for softupdates. Submitted by: mckusick
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ufs/quota.h6
-rw-r--r--sys/ufs/ufs/ufs_quota.c95
2 files changed, 101 insertions, 0 deletions
diff --git a/sys/ufs/ufs/quota.h b/sys/ufs/ufs/quota.h
index ca0dcce..3dfcf26 100644
--- a/sys/ufs/ufs/quota.h
+++ b/sys/ufs/ufs/quota.h
@@ -239,6 +239,12 @@ int setuse(struct thread *, struct mount *, u_long, int, void *);
int getquotasize(struct thread *, struct mount *, u_long, int, void *);
vfs_quotactl_t ufs_quotactl;
+#ifdef SOFTUPDATES
+int quotaref(struct vnode *, struct dquot **);
+void quotarele(struct dquot **);
+void quotaadj(struct dquot **, struct ufsmount *, int64_t);
+#endif /* SOFTUPDATES */
+
#else /* !_KERNEL */
#include <sys/cdefs.h>
diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c
index be82b8f..59e89f9 100644
--- a/sys/ufs/ufs/ufs_quota.c
+++ b/sys/ufs/ufs/ufs_quota.c
@@ -1613,6 +1613,101 @@ dqflush(struct vnode *vp)
}
/*
+ * The following three functions are provided for the adjustment of
+ * quotas by the soft updates code.
+ */
+#ifdef SOFTUPDATES
+/*
+ * Acquire a reference to the quota structures associated with a vnode.
+ * Return count of number of quota structures found.
+ */
+int
+quotaref(vp, qrp)
+ struct vnode *vp;
+ struct dquot **qrp;
+{
+ struct inode *ip;
+ struct dquot *dq;
+ int i, found;
+
+ for (i = 0; i < MAXQUOTAS; i++)
+ qrp[i] = NODQUOT;
+ /*
+ * Disk quotas must be turned off for system files. Currently
+ * snapshot and quota files.
+ */
+ if ((vp->v_vflag & VV_SYSTEM) != 0)
+ return (0);
+ /*
+ * Iterate through and copy active quotas.
+ */
+ found = 0;
+ ip = VTOI(vp);
+ for (i = 0; i < MAXQUOTAS; i++) {
+ if ((dq = ip->i_dquot[i]) == NODQUOT)
+ continue;
+ DQREF(dq);
+ qrp[i] = dq;
+ found++;
+ }
+ return (found);
+}
+
+/*
+ * Release a set of quota structures obtained from a vnode.
+ */
+void
+quotarele(qrp)
+ struct dquot **qrp;
+{
+ struct dquot *dq;
+ int i;
+
+ for (i = 0; i < MAXQUOTAS; i++) {
+ if ((dq = qrp[i]) == NODQUOT)
+ continue;
+ dqrele(NULL, dq);
+ }
+}
+
+/*
+ * Adjust the number of blocks associated with a quota.
+ * Positive numbers when adding blocks; negative numbers when freeing blocks.
+ */
+void
+quotaadj(qrp, ump, blkcount)
+ struct dquot **qrp;
+ struct ufsmount *ump;
+ int64_t blkcount;
+{
+ struct dquot *dq;
+ ufs2_daddr_t ncurblocks;
+ int i;
+
+ if (blkcount == 0)
+ return;
+ for (i = 0; i < MAXQUOTAS; i++) {
+ if ((dq = qrp[i]) == NODQUOT)
+ continue;
+ DQI_LOCK(dq);
+ DQI_WAIT(dq, PINOD+1, "adjqta");
+ ncurblocks = dq->dq_curblocks + blkcount;
+ if (ncurblocks >= 0)
+ dq->dq_curblocks = ncurblocks;
+ else
+ dq->dq_curblocks = 0;
+ if (blkcount < 0)
+ dq->dq_flags &= ~DQ_BLKS;
+ else if (dq->dq_curblocks + blkcount >= dq->dq_bsoftlimit &&
+ dq->dq_curblocks < dq->dq_bsoftlimit)
+ dq->dq_btime = time_second + ump->um_btime[i];
+ dq->dq_flags |= DQ_MOD;
+ DQI_UNLOCK(dq);
+ }
+}
+#endif /* SOFTUPDATES */
+
+/*
* 32-bit / 64-bit conversion functions.
*
* 32-bit quota records are stored in native byte order. Attention must
OpenPOWER on IntegriCloud