···595595 }596596}597597598598+STATIC int599599+xfs_quota_error(uint flags)600600+{601601+ if (flags & XFS_QMOPT_ENOSPC)602602+ return ENOSPC;603603+ return EDQUOT;604604+}605605+598606/*599607 * This reserves disk blocks and inodes against a dquot.600608 * Flags indicate if the dquot is to be locked here and also601609 * if the blk reservation is for RT or regular blocks.602610 * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check.603603- * Returns EDQUOT if quota is exceeded.604611 */605612STATIC int606613xfs_trans_dqresv(···673666 */674667 if (hardlimit > 0ULL &&675668 (hardlimit <= nblks + *resbcountp)) {676676- error = EDQUOT;669669+ error = xfs_quota_error(flags);677670 goto error_return;678671 }679672680673 if (softlimit > 0ULL &&681674 (softlimit <= nblks + *resbcountp)) {682682- /*683683- * If timer or warnings has expired,684684- * return EDQUOT685685- */686675 if ((timer != 0 && get_seconds() > timer) ||687676 (warns != 0 && warns >= warnlimit)) {688688- error = EDQUOT;677677+ error = xfs_quota_error(flags);689678 goto error_return;690679 }691680 }···698695 if (!softlimit)699696 softlimit = q->qi_isoftlimit;700697 if (hardlimit > 0ULL && count >= hardlimit) {701701- error = EDQUOT;698698+ error = xfs_quota_error(flags);702699 goto error_return;703700 } else if (softlimit > 0ULL && count >= softlimit) {704704- /*705705- * If timer or warnings has expired,706706- * return EDQUOT707707- */708701 if ((timer != 0 && get_seconds() > timer) ||709702 (warns != 0 && warns >= warnlimit)) {710710- error = EDQUOT;703703+ error = xfs_quota_error(flags);711704 goto error_return;712705 }713706 }···750751751752752753/*753753- * Given a dquot(s), make disk block and/or inode reservations against them.754754+ * Given dquot(s), make disk block and/or inode reservations against them.754755 * The fact that this does the reservation against both the usr and755755- * grp quotas is important, because this follows a both-or-nothing756756+ * grp/prj quotas is important, because this follows a both-or-nothing756757 * approach.757758 *758759 * flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked.759760 * XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.761761+ * XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT. Used by pquota.760762 * XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks761763 * XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks762764 * dquots are unlocked on return, if they were not locked by caller.···772772 long ninos,773773 uint flags)774774{775775- int resvd;775775+ int resvd = 0, error;776776777777- if (! XFS_IS_QUOTA_ON(mp))778778- return (0);777777+ if (!XFS_IS_QUOTA_ON(mp))778778+ return 0;779779780780 if (tp && tp->t_dqinfo == NULL)781781 xfs_trans_alloc_dqinfo(tp);782782783783 ASSERT(flags & XFS_QMOPT_RESBLK_MASK);784784- resvd = 0;785784786785 if (udqp) {787787- if (xfs_trans_dqresv(tp, mp, udqp, nblks, ninos, flags))788788- return (EDQUOT);786786+ error = xfs_trans_dqresv(tp, mp, udqp, nblks, ninos,787787+ (flags & ~XFS_QMOPT_ENOSPC));788788+ if (error)789789+ return error;789790 resvd = 1;790791 }791792792793 if (gdqp) {793793- if (xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags)) {794794+ error = xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags);795795+ if (error) {794796 /*795797 * can't do it, so backout previous reservation796798 */···801799 xfs_trans_dqresv(tp, mp, udqp,802800 -nblks, -ninos, flags);803801 }804804- return (EDQUOT);802802+ return error;805803 }806804 }807805808806 /*809807 * Didn't change anything critical, so, no need to log810808 */811811- return (0);809809+ return 0;812810}813811814812···816814 * Lock the dquot and change the reservation if we can.817815 * This doesn't change the actual usage, just the reservation.818816 * The inode sent in is locked.819819- *820820- * Returns 0 on success, EDQUOT or other errors otherwise821817 */822818STATIC int823819xfs_trans_reserve_quota_nblks(···824824 xfs_inode_t *ip,825825 long nblks,826826 long ninos,827827- uint type)827827+ uint flags)828828{829829 int error;830830831831 if (!XFS_IS_QUOTA_ON(mp))832832- return (0);832832+ return 0;833833+ if (XFS_IS_PQUOTA_ON(mp))834834+ flags |= XFS_QMOPT_ENOSPC;833835834836 ASSERT(ip->i_ino != mp->m_sb.sb_uquotino);835837 ASSERT(ip->i_ino != mp->m_sb.sb_gquotino);836838837839 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));838840 ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));839839- ASSERT((type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_RTBLKS ||840840- (type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_BLKS);841841+ ASSERT((flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==842842+ XFS_TRANS_DQ_RES_RTBLKS ||843843+ (flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==844844+ XFS_TRANS_DQ_RES_BLKS);841845842846 /*843847 * Reserve nblks against these dquots, with trans as the mediator.···849845 error = xfs_trans_reserve_quota_bydquots(tp, mp,850846 ip->i_udquot, ip->i_gdquot,851847 nblks, ninos,852852- type);853853- return (error);848848+ flags);849849+ return error;854850}855851856852/*
+5-6
fs/xfs/xfs_bmap.c
···47194719 /*47204720 * Make a transaction-less quota reservation for47214721 * delayed allocation blocks. This number gets47224722- * adjusted later.47234723- * We return EDQUOT if we haven't allocated47244724- * blks already inside this loop;47224722+ * adjusted later. We return if we haven't47234723+ * allocated blocks already inside this loop.47254724 */47264726- if (XFS_TRANS_RESERVE_QUOTA_NBLKS(47254725+ if ((error = XFS_TRANS_RESERVE_QUOTA_NBLKS(47274726 mp, NULL, ip, (long)alen, 0,47284727 rt ? XFS_QMOPT_RES_RTBLKS :47294729- XFS_QMOPT_RES_REGBLKS)) {47284728+ XFS_QMOPT_RES_REGBLKS))) {47304729 if (n == 0) {47314730 *nmap = 0;47324731 ASSERT(cur == NULL);47334733- return XFS_ERROR(EDQUOT);47324732+ return error;47344733 }47354734 break;47364735 }
+3-2
fs/xfs/xfs_quota.h
···196196#define XFS_QMOPT_QUOTAOFF 0x0000080 /* quotas are being turned off */197197#define XFS_QMOPT_UMOUNTING 0x0000100 /* filesys is being unmounted */198198#define XFS_QMOPT_DOLOG 0x0000200 /* log buf changes (in quotacheck) */199199-#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */199199+#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if needed */200200#define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */201201-#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot, if damaged. */201201+#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */202202#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */203203+#define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */203204204205/*205206 * flags to xfs_trans_mod_dquot to indicate which field needs to be