Exemplo n.º 1
0
/*
 * Sync quota file for given vnode to disk.
 */
int
qsyncvp(struct vnode *vp)
{
    struct ufsmount *ump = VFSTOUFS(vp->v_mount);
    struct dquot *dq;
    int i;

    /*
     * Check if the mount point has any quotas.
     * If not, simply return.
     */
    for (i = 0; i < MAXQUOTAS; i++)
        if (ump->um_quotas[i] != NULLVP)
            break;
    if (i == MAXQUOTAS)
        return (0);
    /*
     * Search quotas associated with this vnode
     * synchronizing any modified dquot structures.
     */
    for (i = 0; i < MAXQUOTAS; i++) {
        dq = VTOI(vp)->i_dquot[i];
        if (dq != NODQUOT)
            dqsync(vp, dq);
    }
    return (0);
}
Exemplo n.º 2
0
/*
 * Release a reference to a dquot.
 */
static void
dqrele(struct vnode *vp, struct dquot *dq)
{

	if (dq == NODQUOT)
		return;
	mutex_enter(&dq->dq_interlock);
	for (;;) {
		mutex_enter(&dqlock);
		if (dq->dq_cnt > 1) {
			dq->dq_cnt--;
			mutex_exit(&dqlock);
			mutex_exit(&dq->dq_interlock);
			return;
		}
		if ((dq->dq_flags & DQ_MOD) == 0)
			break;
		mutex_exit(&dqlock);
		(void) dqsync(vp, dq);
	}
	KASSERT(dq->dq_cnt == 1 && (dq->dq_flags & DQ_MOD) == 0);
	LIST_REMOVE(dq, dq_hash);
	mutex_exit(&dqlock);
	mutex_exit(&dq->dq_interlock);
	mutex_destroy(&dq->dq_interlock);
	pool_cache_put(dquot_cache, dq);
}
Exemplo n.º 3
0
/*
 * Q_SYNC - sync quota files to disk.
 */
int
qsync(struct mount *mp)
{
	struct ufsmount *ump = VFSTOUFS(mp);
	struct thread *td = curthread;		/* XXX */
	struct vnode *vp, *mvp;
	struct dquot *dq;
	int i, error;

	/*
	 * Check if the mount point has any quotas.
	 * If not, simply return.
	 */
	UFS_LOCK(ump);
	for (i = 0; i < MAXQUOTAS; i++)
		if (ump->um_quotas[i] != NULLVP)
			break;
	UFS_UNLOCK(ump);
	if (i == MAXQUOTAS)
		return (0);
	/*
	 * Search vnodes associated with this mount point,
	 * synchronizing any modified dquot structures.
	 */
again:
	MNT_VNODE_FOREACH_ACTIVE(vp, mp, mvp) {
		if (vp->v_type == VNON) {
			VI_UNLOCK(vp);
			continue;
		}
		error = vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td);
		if (error) {
			if (error == ENOENT) {
				MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
				goto again;
			}
			continue;
		}
		for (i = 0; i < MAXQUOTAS; i++) {
			dq = VTOI(vp)->i_dquot[i];
			if (dq != NODQUOT)
				dqsync(vp, dq);
		}
		vput(vp);
	}
	return (0);
}
Exemplo n.º 4
0
/*
 * Release a reference to a dquot.
 */
void
dqrele(struct vnode *vp, struct dquot *dq)
{

    if (dq == NODQUOT)
        return;
    DQH_LOCK();
    KASSERT(dq->dq_cnt > 0, ("Lost dq %p reference 1", dq));
    if (dq->dq_cnt > 1) {
        dq->dq_cnt--;
        DQH_UNLOCK();
        return;
    }
    DQH_UNLOCK();
sync:
    (void) dqsync(vp, dq);

    DQH_LOCK();
    KASSERT(dq->dq_cnt > 0, ("Lost dq %p reference 2", dq));
    if (--dq->dq_cnt > 0)
    {
        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();
}
Exemplo n.º 5
0
/*
 * Q_SYNC - sync quota files to disk.
 */
int
qsync(struct mount *mp)
{
	struct ufsmount *ump = VFSTOUFS(mp);
	struct vnode *vp, *mvp;
	struct dquot *dq;
	int i, error;

	/*
	 * Check if the mount point has any quotas.
	 * If not, simply return.
	 */
	for (i = 0; i < MAXQUOTAS; i++)
		if (ump->um_quotas[i] != NULLVP)
			break;
	if (i == MAXQUOTAS)
		return (0);

	/* Allocate a marker vnode. */
	if ((mvp = vnalloc(mp)) == NULL)
		return (ENOMEM);

	/*
	 * Search vnodes associated with this mount point,
	 * synchronizing any modified dquot structures.
	 */
	mutex_enter(&mntvnode_lock);
 again:
	for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = vunmark(mvp)) {
		vmark(mvp, vp);
		mutex_enter(&vp->v_interlock);
		if (VTOI(vp) == NULL || vp->v_mount != mp || vismarker(vp) ||
		    vp->v_type == VNON ||
		    (vp->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0) {
			mutex_exit(&vp->v_interlock);
			continue;
		}
		mutex_exit(&mntvnode_lock);
		error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK);
		if (error) {
			mutex_enter(&mntvnode_lock);
			if (error == ENOENT) {
				(void)vunmark(mvp);
				goto again;
			}
			continue;
		}
		for (i = 0; i < MAXQUOTAS; i++) {
			dq = VTOI(vp)->i_dquot[i];
			if (dq == NODQUOT)
				continue;
			mutex_enter(&dq->dq_interlock);
			if (dq->dq_flags & DQ_MOD)
				dqsync(vp, dq);
			mutex_exit(&dq->dq_interlock);
		}
		vput(vp);
		mutex_enter(&mntvnode_lock);
	}
	mutex_exit(&mntvnode_lock);
	vnfree(mvp);
	return (0);
}