Example #1
0
/*
 * Given dquot(s), make disk block and/or inode reservations against them.
 * The fact that this does the reservation against user, group and
 * project quotas is important, because this follows a all-or-nothing
 * approach.
 *
 * flags = XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
 *	   XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT.  Used by pquota.
 *	   XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
 *	   XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
 * dquots are unlocked on return, if they were not locked by caller.
 */
int
xfs_trans_reserve_quota_bydquots(
    struct xfs_trans	*tp,
    struct xfs_mount	*mp,
    struct xfs_dquot	*udqp,
    struct xfs_dquot	*gdqp,
    struct xfs_dquot	*pdqp,
    long			nblks,
    long			ninos,
    uint			flags)
{
    int		error;

    if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
        return 0;

    if (tp && tp->t_dqinfo == NULL)
        xfs_trans_alloc_dqinfo(tp);

    ASSERT(flags & XFS_QMOPT_RESBLK_MASK);

    if (udqp) {
        error = xfs_trans_dqresv(tp, mp, udqp, nblks, ninos,
                                 (flags & ~XFS_QMOPT_ENOSPC));
        if (error)
            return error;
    }

    if (gdqp) {
        error = xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags);
        if (error)
            goto unwind_usr;
    }

    if (pdqp) {
        error = xfs_trans_dqresv(tp, mp, pdqp, nblks, ninos, flags);
        if (error)
            goto unwind_grp;
    }

    /*
     * Didn't change anything critical, so, no need to log
     */
    return 0;

unwind_grp:
    flags |= XFS_QMOPT_FORCE_RES;
    if (gdqp)
        xfs_trans_dqresv(tp, mp, gdqp, -nblks, -ninos, flags);
unwind_usr:
    flags |= XFS_QMOPT_FORCE_RES;
    if (udqp)
        xfs_trans_dqresv(tp, mp, udqp, -nblks, -ninos, flags);
    return error;
}
/*
 * Given dquot(s), make disk block and/or inode reservations against them.
 * The fact that this does the reservation against both the usr and
 * grp/prj quotas is important, because this follows a both-or-nothing
 * approach.
 *
 * flags = XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
 *	   XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT.  Used by pquota.
 *	   XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
 *	   XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
 * dquots are unlocked on return, if they were not locked by caller.
 */
int
xfs_trans_reserve_quota_bydquots(
	xfs_trans_t	*tp,
	xfs_mount_t	*mp,
	xfs_dquot_t	*udqp,
	xfs_dquot_t	*gdqp,
	long		nblks,
	long		ninos,
	uint		flags)
{
	int		resvd = 0, error;

	if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
		return 0;

	if (tp && tp->t_dqinfo == NULL)
		xfs_trans_alloc_dqinfo(tp);

	ASSERT(flags & XFS_QMOPT_RESBLK_MASK);

	if (udqp) {
		error = xfs_trans_dqresv(tp, mp, udqp, nblks, ninos,
					(flags & ~XFS_QMOPT_ENOSPC));
		if (error)
			return error;
		resvd = 1;
	}

	if (gdqp) {
		error = xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags);
		if (error) {
			/*
			 * can't do it, so backout previous reservation
			 */
			if (resvd) {
				flags |= XFS_QMOPT_FORCE_RES;
				xfs_trans_dqresv(tp, mp, udqp,
						 -nblks, -ninos, flags);
			}
			return error;
		}
	}

	/*
	 * Didn't change anything critical, so, no need to log
	 */
	return 0;
}
Example #3
0
/*
 * Given a dquot(s), make disk block and/or inode reservations against them.
 * The fact that this does the reservation against both the usr and
 * grp quotas is important, because this follows a both-or-nothing
 * approach.
 *
 * flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked.
 *	   XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
 *	   XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
 *	   XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
 * dquots are unlocked on return, if they were not locked by caller.
 */
int
xfs_trans_reserve_quota_bydquots(
	xfs_trans_t	*tp,
	xfs_mount_t	*mp,
	xfs_dquot_t	*udqp,
	xfs_dquot_t	*gdqp,
	long		nblks,
	long		ninos,
	uint		flags)
{
	int		resvd;

	if (! XFS_IS_QUOTA_ON(mp))
		return (0);

	if (tp && tp->t_dqinfo == NULL)
		xfs_trans_alloc_dqinfo(tp);

	ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
	resvd = 0;

	if (udqp) {
		if (xfs_trans_dqresv(tp, udqp, nblks, ninos, flags))
			return (EDQUOT);
		resvd = 1;
	}

	if (gdqp) {
		if (xfs_trans_dqresv(tp, gdqp, nblks, ninos, flags)) {
			/*
			 * can't do it, so backout previous reservation
			 */
			if (resvd) {
				xfs_trans_dqresv(tp, udqp,  -nblks, -ninos,
						 flags);
			}
			return (EDQUOT);
		}
	}

	/*
	 * Didnt change anything critical, so, no need to log
	 */
	return (0);
}