summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/ufs/ufs/ufs_quota.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c
index 11d2e4b..1eb1ef2 100644
--- a/sys/ufs/ufs/ufs_quota.c
+++ b/sys/ufs/ufs/ufs_quota.c
@@ -411,6 +411,7 @@ quotaon(td, mp, type, fname)
struct dquot *dq;
int error, flags;
struct nameidata nd;
+ int restart;
error = suser_cred(td->td_ucred, PRISON_ROOT);
if (error)
@@ -457,13 +458,14 @@ quotaon(td, mp, type, fname)
*/
mtx_lock(&mntvnode_mtx);
again:
+ restart = 0;
for (vp = TAILQ_FIRST(&mp->mnt_nvnodelist); vp != NULL; vp = nextvp) {
if (vp->v_mount != mp)
goto again;
nextvp = TAILQ_NEXT(vp, v_nmntvnodes);
-
+ VI_LOCK(vp);
mtx_unlock(&mntvnode_mtx);
- if (vget(vp, LK_EXCLUSIVE, td)) {
+ if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
mtx_lock(&mntvnode_mtx);
goto again;
}
@@ -473,11 +475,13 @@ again:
continue;
}
error = getinoquota(VTOI(vp));
- vput(vp);
mtx_lock(&mntvnode_mtx);
+ if (TAILQ_NEXT(vp, v_nmntvnodes) != nextvp)
+ restart = 1;
+ vput(vp);
if (error)
break;
- if (TAILQ_NEXT(vp, v_nmntvnodes) != nextvp)
+ if (restart)
goto again;
}
mtx_unlock(&mntvnode_mtx);
@@ -501,6 +505,7 @@ quotaoff(td, mp, type)
struct ufsmount *ump = VFSTOUFS(mp);
struct dquot *dq;
struct inode *ip;
+ int restart;
int error;
error = suser_cred(td->td_ucred, PRISON_ROOT);
@@ -516,15 +521,16 @@ quotaoff(td, mp, type)
*/
mtx_lock(&mntvnode_mtx);
again:
+ restart = 0;
for (vp = TAILQ_FIRST(&mp->mnt_nvnodelist); vp != NULL; vp = nextvp) {
if (vp->v_mount != mp)
goto again;
nextvp = TAILQ_NEXT(vp, v_nmntvnodes);
+ VI_LOCK(vp);
mtx_unlock(&mntvnode_mtx);
- mtx_lock(&vp->v_interlock);
if (vp->v_type == VNON) {
- mtx_unlock(&vp->v_interlock);
+ VI_UNLOCK(vp);
mtx_lock(&mntvnode_mtx);
continue;
}
@@ -536,9 +542,11 @@ again:
dq = ip->i_dquot[type];
ip->i_dquot[type] = NODQUOT;
dqrele(vp, dq);
- vput(vp);
mtx_lock(&mntvnode_mtx);
if (TAILQ_NEXT(vp, v_nmntvnodes) != nextvp)
+ restart = 1;
+ vput(vp);
+ if (restart)
goto again;
}
mtx_unlock(&mntvnode_mtx);
@@ -731,6 +739,7 @@ qsync(mp)
struct thread *td = curthread; /* XXX */
struct vnode *vp, *nextvp;
struct dquot *dq;
+ int restart;
int i, error;
/*
@@ -748,14 +757,15 @@ qsync(mp)
*/
mtx_lock(&mntvnode_mtx);
again:
+ restart = 0;
for (vp = TAILQ_FIRST(&mp->mnt_nvnodelist); vp != NULL; vp = nextvp) {
if (vp->v_mount != mp)
goto again;
nextvp = TAILQ_NEXT(vp, v_nmntvnodes);
+ VI_LOCK(vp);
mtx_unlock(&mntvnode_mtx);
- mtx_lock(&vp->v_interlock);
if (vp->v_type == VNON) {
- mtx_unlock(&vp->v_interlock);
+ VI_UNLOCK(vp);
mtx_lock(&mntvnode_mtx);
continue;
}
@@ -771,9 +781,11 @@ again:
if (dq != NODQUOT && (dq->dq_flags & DQ_MOD))
dqsync(vp, dq);
}
- vput(vp);
- mtx_lock(&mntvnode_mtx);
if (TAILQ_NEXT(vp, v_nmntvnodes) != nextvp)
+ restart = 1;
+ mtx_lock(&mntvnode_mtx);
+ vput(vp);
+ if (restart)
goto again;
}
mtx_unlock(&mntvnode_mtx);
OpenPOWER on IntegriCloud