diff options
-rw-r--r-- | sys/ufs/ufs/ufs_quota.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c index 5f068c0..2db0444 100644 --- a/sys/ufs/ufs/ufs_quota.c +++ b/sys/ufs/ufs/ufs_quota.c @@ -1262,7 +1262,7 @@ dqrele(struct vnode *vp, struct dquot *dq) return; } DQH_UNLOCK(); - +sync: (void) dqsync(vp, dq); DQH_LOCK(); @@ -1271,6 +1271,18 @@ dqrele(struct vnode *vp, struct dquot *dq) DQH_UNLOCK(); return; } + + /* + * The dq may become dirty after it is synced but before it is + * put to the free list. Checking the DQ_MOD there without + * locking dq should be safe since no other references to the + * dq exist. + */ + if ((dq->dq_flags & DQ_MOD) != 0) { + dq->dq_cnt++; + DQH_UNLOCK(); + goto sync; + } TAILQ_INSERT_TAIL(&dqfreelist, dq, dq_freelist); DQH_UNLOCK(); } |