Loading fs/xfs/quota/xfs_qm.c +10 −7 Original line number Diff line number Diff line Loading @@ -2624,7 +2624,7 @@ xfs_qm_vop_chown_reserve( { int error; xfs_mount_t *mp; uint delblks, blkflags; uint delblks, blkflags, prjflags = 0; xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq; ASSERT(XFS_ISLOCKED_INODE(ip)); Loading @@ -2650,10 +2650,13 @@ xfs_qm_vop_chown_reserve( } } if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) { if ((XFS_IS_GQUOTA_ON(ip->i_mount) && ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id)) || (XFS_IS_PQUOTA_ON(ip->i_mount) && ip->i_d.di_projid != be32_to_cpu(gdqp->q_core.d_id))) { if (XFS_IS_PQUOTA_ON(ip->i_mount) && ip->i_d.di_projid != be32_to_cpu(gdqp->q_core.d_id)) prjflags = XFS_QMOPT_ENOSPC; if (prjflags || (XFS_IS_GQUOTA_ON(ip->i_mount) && ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id))) { delblksgdq = gdqp; if (delblks) { ASSERT(ip->i_gdquot); Loading @@ -2664,7 +2667,7 @@ xfs_qm_vop_chown_reserve( if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount, delblksudq, delblksgdq, ip->i_d.di_nblocks, 1, flags | blkflags))) flags | blkflags | prjflags))) return (error); /* Loading @@ -2681,7 +2684,7 @@ xfs_qm_vop_chown_reserve( ASSERT(unresudq || unresgdq); if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0, flags | blkflags))) flags | blkflags | prjflags))) return (error); xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0, Loading fs/xfs/quota/xfs_trans_dquot.c +36 −32 Original line number Diff line number Diff line Loading @@ -595,12 +595,19 @@ xfs_trans_unreserve_and_mod_dquots( } } STATIC int xfs_quota_error(uint flags) { if (flags & XFS_QMOPT_ENOSPC) return ENOSPC; return EDQUOT; } /* * This reserves disk blocks and inodes against a dquot. * Flags indicate if the dquot is to be locked here and also * if the blk reservation is for RT or regular blocks. * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check. * Returns EDQUOT if quota is exceeded. */ STATIC int xfs_trans_dqresv( Loading Loading @@ -666,19 +673,15 @@ xfs_trans_dqresv( */ if (hardlimit > 0ULL && (hardlimit <= nblks + *resbcountp)) { error = EDQUOT; error = xfs_quota_error(flags); goto error_return; } if (softlimit > 0ULL && (softlimit <= nblks + *resbcountp)) { /* * If timer or warnings has expired, * return EDQUOT */ if ((timer != 0 && get_seconds() > timer) || (warns != 0 && warns >= warnlimit)) { error = EDQUOT; error = xfs_quota_error(flags); goto error_return; } } Loading @@ -695,16 +698,12 @@ xfs_trans_dqresv( if (!softlimit) softlimit = q->qi_isoftlimit; if (hardlimit > 0ULL && count >= hardlimit) { error = EDQUOT; error = xfs_quota_error(flags); goto error_return; } else if (softlimit > 0ULL && count >= softlimit) { /* * If timer or warnings has expired, * return EDQUOT */ if ((timer != 0 && get_seconds() > timer) || (warns != 0 && warns >= warnlimit)) { error = EDQUOT; error = xfs_quota_error(flags); goto error_return; } } Loading Loading @@ -751,13 +750,14 @@ xfs_trans_dqresv( /* * Given a dquot(s), make disk block and/or inode reservations against them. * 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 quotas is important, because this follows a both-or-nothing * grp/prj 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_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. Loading @@ -772,25 +772,27 @@ xfs_trans_reserve_quota_bydquots( long ninos, uint flags) { int resvd; int resvd = 0, error; if (!XFS_IS_QUOTA_ON(mp)) return (0); 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, mp, udqp, nblks, ninos, flags)) return (EDQUOT); error = xfs_trans_dqresv(tp, mp, udqp, nblks, ninos, (flags & ~XFS_QMOPT_ENOSPC)); if (error) return error; resvd = 1; } if (gdqp) { if (xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags)) { error = xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags); if (error) { /* * can't do it, so backout previous reservation */ Loading @@ -799,14 +801,14 @@ xfs_trans_reserve_quota_bydquots( xfs_trans_dqresv(tp, mp, udqp, -nblks, -ninos, flags); } return (EDQUOT); return error; } } /* * Didn't change anything critical, so, no need to log */ return (0); return 0; } Loading @@ -814,8 +816,6 @@ xfs_trans_reserve_quota_bydquots( * Lock the dquot and change the reservation if we can. * This doesn't change the actual usage, just the reservation. * The inode sent in is locked. * * Returns 0 on success, EDQUOT or other errors otherwise */ STATIC int xfs_trans_reserve_quota_nblks( Loading @@ -824,20 +824,24 @@ xfs_trans_reserve_quota_nblks( xfs_inode_t *ip, long nblks, long ninos, uint type) uint flags) { int error; if (!XFS_IS_QUOTA_ON(mp)) return (0); return 0; if (XFS_IS_PQUOTA_ON(mp)) flags |= XFS_QMOPT_ENOSPC; ASSERT(ip->i_ino != mp->m_sb.sb_uquotino); ASSERT(ip->i_ino != mp->m_sb.sb_gquotino); ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); ASSERT((type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_RTBLKS || (type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_BLKS); ASSERT((flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) == XFS_TRANS_DQ_RES_RTBLKS || (flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) == XFS_TRANS_DQ_RES_BLKS); /* * Reserve nblks against these dquots, with trans as the mediator. Loading @@ -845,8 +849,8 @@ xfs_trans_reserve_quota_nblks( error = xfs_trans_reserve_quota_bydquots(tp, mp, ip->i_udquot, ip->i_gdquot, nblks, ninos, type); return (error); flags); return error; } /* Loading fs/xfs/xfs_bmap.c +5 −6 Original line number Diff line number Diff line Loading @@ -4719,18 +4719,17 @@ xfs_bmapi( /* * Make a transaction-less quota reservation for * delayed allocation blocks. This number gets * adjusted later. * We return EDQUOT if we haven't allocated * blks already inside this loop; * adjusted later. We return if we haven't * allocated blocks already inside this loop. */ if (XFS_TRANS_RESERVE_QUOTA_NBLKS( if ((error = XFS_TRANS_RESERVE_QUOTA_NBLKS( mp, NULL, ip, (long)alen, 0, rt ? XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS)) { XFS_QMOPT_RES_REGBLKS))) { if (n == 0) { *nmap = 0; ASSERT(cur == NULL); return XFS_ERROR(EDQUOT); return error; } break; } Loading fs/xfs/xfs_quota.h +3 −2 Original line number Diff line number Diff line Loading @@ -196,10 +196,11 @@ typedef struct xfs_qoff_logformat { #define XFS_QMOPT_QUOTAOFF 0x0000080 /* quotas are being turned off */ #define XFS_QMOPT_UMOUNTING 0x0000100 /* filesys is being unmounted */ #define XFS_QMOPT_DOLOG 0x0000200 /* log buf changes (in quotacheck) */ #define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */ #define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if needed */ #define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */ #define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot, if damaged. */ #define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */ #define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */ #define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */ /* * flags to xfs_trans_mod_dquot to indicate which field needs to be Loading Loading
fs/xfs/quota/xfs_qm.c +10 −7 Original line number Diff line number Diff line Loading @@ -2624,7 +2624,7 @@ xfs_qm_vop_chown_reserve( { int error; xfs_mount_t *mp; uint delblks, blkflags; uint delblks, blkflags, prjflags = 0; xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq; ASSERT(XFS_ISLOCKED_INODE(ip)); Loading @@ -2650,10 +2650,13 @@ xfs_qm_vop_chown_reserve( } } if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) { if ((XFS_IS_GQUOTA_ON(ip->i_mount) && ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id)) || (XFS_IS_PQUOTA_ON(ip->i_mount) && ip->i_d.di_projid != be32_to_cpu(gdqp->q_core.d_id))) { if (XFS_IS_PQUOTA_ON(ip->i_mount) && ip->i_d.di_projid != be32_to_cpu(gdqp->q_core.d_id)) prjflags = XFS_QMOPT_ENOSPC; if (prjflags || (XFS_IS_GQUOTA_ON(ip->i_mount) && ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id))) { delblksgdq = gdqp; if (delblks) { ASSERT(ip->i_gdquot); Loading @@ -2664,7 +2667,7 @@ xfs_qm_vop_chown_reserve( if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount, delblksudq, delblksgdq, ip->i_d.di_nblocks, 1, flags | blkflags))) flags | blkflags | prjflags))) return (error); /* Loading @@ -2681,7 +2684,7 @@ xfs_qm_vop_chown_reserve( ASSERT(unresudq || unresgdq); if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0, flags | blkflags))) flags | blkflags | prjflags))) return (error); xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0, Loading
fs/xfs/quota/xfs_trans_dquot.c +36 −32 Original line number Diff line number Diff line Loading @@ -595,12 +595,19 @@ xfs_trans_unreserve_and_mod_dquots( } } STATIC int xfs_quota_error(uint flags) { if (flags & XFS_QMOPT_ENOSPC) return ENOSPC; return EDQUOT; } /* * This reserves disk blocks and inodes against a dquot. * Flags indicate if the dquot is to be locked here and also * if the blk reservation is for RT or regular blocks. * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check. * Returns EDQUOT if quota is exceeded. */ STATIC int xfs_trans_dqresv( Loading Loading @@ -666,19 +673,15 @@ xfs_trans_dqresv( */ if (hardlimit > 0ULL && (hardlimit <= nblks + *resbcountp)) { error = EDQUOT; error = xfs_quota_error(flags); goto error_return; } if (softlimit > 0ULL && (softlimit <= nblks + *resbcountp)) { /* * If timer or warnings has expired, * return EDQUOT */ if ((timer != 0 && get_seconds() > timer) || (warns != 0 && warns >= warnlimit)) { error = EDQUOT; error = xfs_quota_error(flags); goto error_return; } } Loading @@ -695,16 +698,12 @@ xfs_trans_dqresv( if (!softlimit) softlimit = q->qi_isoftlimit; if (hardlimit > 0ULL && count >= hardlimit) { error = EDQUOT; error = xfs_quota_error(flags); goto error_return; } else if (softlimit > 0ULL && count >= softlimit) { /* * If timer or warnings has expired, * return EDQUOT */ if ((timer != 0 && get_seconds() > timer) || (warns != 0 && warns >= warnlimit)) { error = EDQUOT; error = xfs_quota_error(flags); goto error_return; } } Loading Loading @@ -751,13 +750,14 @@ xfs_trans_dqresv( /* * Given a dquot(s), make disk block and/or inode reservations against them. * 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 quotas is important, because this follows a both-or-nothing * grp/prj 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_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. Loading @@ -772,25 +772,27 @@ xfs_trans_reserve_quota_bydquots( long ninos, uint flags) { int resvd; int resvd = 0, error; if (!XFS_IS_QUOTA_ON(mp)) return (0); 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, mp, udqp, nblks, ninos, flags)) return (EDQUOT); error = xfs_trans_dqresv(tp, mp, udqp, nblks, ninos, (flags & ~XFS_QMOPT_ENOSPC)); if (error) return error; resvd = 1; } if (gdqp) { if (xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags)) { error = xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags); if (error) { /* * can't do it, so backout previous reservation */ Loading @@ -799,14 +801,14 @@ xfs_trans_reserve_quota_bydquots( xfs_trans_dqresv(tp, mp, udqp, -nblks, -ninos, flags); } return (EDQUOT); return error; } } /* * Didn't change anything critical, so, no need to log */ return (0); return 0; } Loading @@ -814,8 +816,6 @@ xfs_trans_reserve_quota_bydquots( * Lock the dquot and change the reservation if we can. * This doesn't change the actual usage, just the reservation. * The inode sent in is locked. * * Returns 0 on success, EDQUOT or other errors otherwise */ STATIC int xfs_trans_reserve_quota_nblks( Loading @@ -824,20 +824,24 @@ xfs_trans_reserve_quota_nblks( xfs_inode_t *ip, long nblks, long ninos, uint type) uint flags) { int error; if (!XFS_IS_QUOTA_ON(mp)) return (0); return 0; if (XFS_IS_PQUOTA_ON(mp)) flags |= XFS_QMOPT_ENOSPC; ASSERT(ip->i_ino != mp->m_sb.sb_uquotino); ASSERT(ip->i_ino != mp->m_sb.sb_gquotino); ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); ASSERT((type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_RTBLKS || (type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_BLKS); ASSERT((flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) == XFS_TRANS_DQ_RES_RTBLKS || (flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) == XFS_TRANS_DQ_RES_BLKS); /* * Reserve nblks against these dquots, with trans as the mediator. Loading @@ -845,8 +849,8 @@ xfs_trans_reserve_quota_nblks( error = xfs_trans_reserve_quota_bydquots(tp, mp, ip->i_udquot, ip->i_gdquot, nblks, ninos, type); return (error); flags); return error; } /* Loading
fs/xfs/xfs_bmap.c +5 −6 Original line number Diff line number Diff line Loading @@ -4719,18 +4719,17 @@ xfs_bmapi( /* * Make a transaction-less quota reservation for * delayed allocation blocks. This number gets * adjusted later. * We return EDQUOT if we haven't allocated * blks already inside this loop; * adjusted later. We return if we haven't * allocated blocks already inside this loop. */ if (XFS_TRANS_RESERVE_QUOTA_NBLKS( if ((error = XFS_TRANS_RESERVE_QUOTA_NBLKS( mp, NULL, ip, (long)alen, 0, rt ? XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS)) { XFS_QMOPT_RES_REGBLKS))) { if (n == 0) { *nmap = 0; ASSERT(cur == NULL); return XFS_ERROR(EDQUOT); return error; } break; } Loading
fs/xfs/xfs_quota.h +3 −2 Original line number Diff line number Diff line Loading @@ -196,10 +196,11 @@ typedef struct xfs_qoff_logformat { #define XFS_QMOPT_QUOTAOFF 0x0000080 /* quotas are being turned off */ #define XFS_QMOPT_UMOUNTING 0x0000100 /* filesys is being unmounted */ #define XFS_QMOPT_DOLOG 0x0000200 /* log buf changes (in quotacheck) */ #define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */ #define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if needed */ #define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */ #define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot, if damaged. */ #define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */ #define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */ #define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */ /* * flags to xfs_trans_mod_dquot to indicate which field needs to be Loading