aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/quota/xfs_trans_dquot.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/quota/xfs_trans_dquot.c')
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c68
1 files changed, 36 insertions, 32 deletions
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index d8e131ec0aa8..9168918db252 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -595,12 +595,19 @@ xfs_trans_unreserve_and_mod_dquots(
595 } 595 }
596} 596}
597 597
598STATIC int
599xfs_quota_error(uint flags)
600{
601 if (flags & XFS_QMOPT_ENOSPC)
602 return ENOSPC;
603 return EDQUOT;
604}
605
598/* 606/*
599 * This reserves disk blocks and inodes against a dquot. 607 * This reserves disk blocks and inodes against a dquot.
600 * Flags indicate if the dquot is to be locked here and also 608 * Flags indicate if the dquot is to be locked here and also
601 * if the blk reservation is for RT or regular blocks. 609 * if the blk reservation is for RT or regular blocks.
602 * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check. 610 * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check.
603 * Returns EDQUOT if quota is exceeded.
604 */ 611 */
605STATIC int 612STATIC int
606xfs_trans_dqresv( 613xfs_trans_dqresv(
@@ -666,19 +673,15 @@ xfs_trans_dqresv(
666 */ 673 */
667 if (hardlimit > 0ULL && 674 if (hardlimit > 0ULL &&
668 (hardlimit <= nblks + *resbcountp)) { 675 (hardlimit <= nblks + *resbcountp)) {
669 error = EDQUOT; 676 error = xfs_quota_error(flags);
670 goto error_return; 677 goto error_return;
671 } 678 }
672 679
673 if (softlimit > 0ULL && 680 if (softlimit > 0ULL &&
674 (softlimit <= nblks + *resbcountp)) { 681 (softlimit <= nblks + *resbcountp)) {
675 /*
676 * If timer or warnings has expired,
677 * return EDQUOT
678 */
679 if ((timer != 0 && get_seconds() > timer) || 682 if ((timer != 0 && get_seconds() > timer) ||
680 (warns != 0 && warns >= warnlimit)) { 683 (warns != 0 && warns >= warnlimit)) {
681 error = EDQUOT; 684 error = xfs_quota_error(flags);
682 goto error_return; 685 goto error_return;
683 } 686 }
684 } 687 }
@@ -695,16 +698,12 @@ xfs_trans_dqresv(
695 if (!softlimit) 698 if (!softlimit)
696 softlimit = q->qi_isoftlimit; 699 softlimit = q->qi_isoftlimit;
697 if (hardlimit > 0ULL && count >= hardlimit) { 700 if (hardlimit > 0ULL && count >= hardlimit) {
698 error = EDQUOT; 701 error = xfs_quota_error(flags);
699 goto error_return; 702 goto error_return;
700 } else if (softlimit > 0ULL && count >= softlimit) { 703 } else if (softlimit > 0ULL && count >= softlimit) {
701 /*
702 * If timer or warnings has expired,
703 * return EDQUOT
704 */
705 if ((timer != 0 && get_seconds() > timer) || 704 if ((timer != 0 && get_seconds() > timer) ||
706 (warns != 0 && warns >= warnlimit)) { 705 (warns != 0 && warns >= warnlimit)) {
707 error = EDQUOT; 706 error = xfs_quota_error(flags);
708 goto error_return; 707 goto error_return;
709 } 708 }
710 } 709 }
@@ -751,13 +750,14 @@ error_return:
751 750
752 751
753/* 752/*
754 * Given a dquot(s), make disk block and/or inode reservations against them. 753 * Given dquot(s), make disk block and/or inode reservations against them.
755 * The fact that this does the reservation against both the usr and 754 * The fact that this does the reservation against both the usr and
756 * grp quotas is important, because this follows a both-or-nothing 755 * grp/prj quotas is important, because this follows a both-or-nothing
757 * approach. 756 * approach.
758 * 757 *
759 * flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked. 758 * flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked.
760 * XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown. 759 * XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
760 * XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT. Used by pquota.
761 * XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks 761 * XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
762 * XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks 762 * XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
763 * dquots are unlocked on return, if they were not locked by caller. 763 * dquots are unlocked on return, if they were not locked by caller.
@@ -772,25 +772,27 @@ xfs_trans_reserve_quota_bydquots(
772 long ninos, 772 long ninos,
773 uint flags) 773 uint flags)
774{ 774{
775 int resvd; 775 int resvd = 0, error;
776 776
777 if (! XFS_IS_QUOTA_ON(mp)) 777 if (!XFS_IS_QUOTA_ON(mp))
778 return (0); 778 return 0;
779 779
780 if (tp && tp->t_dqinfo == NULL) 780 if (tp && tp->t_dqinfo == NULL)
781 xfs_trans_alloc_dqinfo(tp); 781 xfs_trans_alloc_dqinfo(tp);
782 782
783 ASSERT(flags & XFS_QMOPT_RESBLK_MASK); 783 ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
784 resvd = 0;
785 784
786 if (udqp) { 785 if (udqp) {
787 if (xfs_trans_dqresv(tp, mp, udqp, nblks, ninos, flags)) 786 error = xfs_trans_dqresv(tp, mp, udqp, nblks, ninos,
788 return (EDQUOT); 787 (flags & ~XFS_QMOPT_ENOSPC));
788 if (error)
789 return error;
789 resvd = 1; 790 resvd = 1;
790 } 791 }
791 792
792 if (gdqp) { 793 if (gdqp) {
793 if (xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags)) { 794 error = xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags);
795 if (error) {
794 /* 796 /*
795 * can't do it, so backout previous reservation 797 * can't do it, so backout previous reservation
796 */ 798 */
@@ -799,14 +801,14 @@ xfs_trans_reserve_quota_bydquots(
799 xfs_trans_dqresv(tp, mp, udqp, 801 xfs_trans_dqresv(tp, mp, udqp,
800 -nblks, -ninos, flags); 802 -nblks, -ninos, flags);
801 } 803 }
802 return (EDQUOT); 804 return error;
803 } 805 }
804 } 806 }
805 807
806 /* 808 /*
807 * Didn't change anything critical, so, no need to log 809 * Didn't change anything critical, so, no need to log
808 */ 810 */
809 return (0); 811 return 0;
810} 812}
811 813
812 814
@@ -814,8 +816,6 @@ xfs_trans_reserve_quota_bydquots(
814 * Lock the dquot and change the reservation if we can. 816 * Lock the dquot and change the reservation if we can.
815 * This doesn't change the actual usage, just the reservation. 817 * This doesn't change the actual usage, just the reservation.
816 * The inode sent in is locked. 818 * The inode sent in is locked.
817 *
818 * Returns 0 on success, EDQUOT or other errors otherwise
819 */ 819 */
820STATIC int 820STATIC int
821xfs_trans_reserve_quota_nblks( 821xfs_trans_reserve_quota_nblks(
@@ -824,20 +824,24 @@ xfs_trans_reserve_quota_nblks(
824 xfs_inode_t *ip, 824 xfs_inode_t *ip,
825 long nblks, 825 long nblks,
826 long ninos, 826 long ninos,
827 uint type) 827 uint flags)
828{ 828{
829 int error; 829 int error;
830 830
831 if (!XFS_IS_QUOTA_ON(mp)) 831 if (!XFS_IS_QUOTA_ON(mp))
832 return (0); 832 return 0;
833 if (XFS_IS_PQUOTA_ON(mp))
834 flags |= XFS_QMOPT_ENOSPC;
833 835
834 ASSERT(ip->i_ino != mp->m_sb.sb_uquotino); 836 ASSERT(ip->i_ino != mp->m_sb.sb_uquotino);
835 ASSERT(ip->i_ino != mp->m_sb.sb_gquotino); 837 ASSERT(ip->i_ino != mp->m_sb.sb_gquotino);
836 838
837 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); 839 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
838 ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); 840 ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));
839 ASSERT((type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_RTBLKS || 841 ASSERT((flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
840 (type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_BLKS); 842 XFS_TRANS_DQ_RES_RTBLKS ||
843 (flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
844 XFS_TRANS_DQ_RES_BLKS);
841 845
842 /* 846 /*
843 * Reserve nblks against these dquots, with trans as the mediator. 847 * Reserve nblks against these dquots, with trans as the mediator.
@@ -845,8 +849,8 @@ xfs_trans_reserve_quota_nblks(
845 error = xfs_trans_reserve_quota_bydquots(tp, mp, 849 error = xfs_trans_reserve_quota_bydquots(tp, mp,
846 ip->i_udquot, ip->i_gdquot, 850 ip->i_udquot, ip->i_gdquot,
847 nblks, ninos, 851 nblks, ninos,
848 type); 852 flags);
849 return (error); 853 return error;
850} 854}
851 855
852/* 856/*