diff options
Diffstat (limited to 'fs/gfs2/quota.c')
-rw-r--r-- | fs/gfs2/quota.c | 85 |
1 files changed, 34 insertions, 51 deletions
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index d1962b2f67f9..98a01db1f6dc 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -494,11 +494,11 @@ static void qdsb_put(struct gfs2_quota_data *qd) | |||
494 | int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) | 494 | int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) |
495 | { | 495 | { |
496 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 496 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
497 | struct gfs2_alloc *al = ip->i_alloc; | 497 | struct gfs2_qadata *qa = ip->i_qadata; |
498 | struct gfs2_quota_data **qd = al->al_qd; | 498 | struct gfs2_quota_data **qd = qa->qa_qd; |
499 | int error; | 499 | int error; |
500 | 500 | ||
501 | if (gfs2_assert_warn(sdp, !al->al_qd_num) || | 501 | if (gfs2_assert_warn(sdp, !qa->qa_qd_num) || |
502 | gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags))) | 502 | gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags))) |
503 | return -EIO; | 503 | return -EIO; |
504 | 504 | ||
@@ -508,20 +508,20 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
508 | error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, qd); | 508 | error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, qd); |
509 | if (error) | 509 | if (error) |
510 | goto out; | 510 | goto out; |
511 | al->al_qd_num++; | 511 | qa->qa_qd_num++; |
512 | qd++; | 512 | qd++; |
513 | 513 | ||
514 | error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, qd); | 514 | error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, qd); |
515 | if (error) | 515 | if (error) |
516 | goto out; | 516 | goto out; |
517 | al->al_qd_num++; | 517 | qa->qa_qd_num++; |
518 | qd++; | 518 | qd++; |
519 | 519 | ||
520 | if (uid != NO_QUOTA_CHANGE && uid != ip->i_inode.i_uid) { | 520 | if (uid != NO_QUOTA_CHANGE && uid != ip->i_inode.i_uid) { |
521 | error = qdsb_get(sdp, QUOTA_USER, uid, qd); | 521 | error = qdsb_get(sdp, QUOTA_USER, uid, qd); |
522 | if (error) | 522 | if (error) |
523 | goto out; | 523 | goto out; |
524 | al->al_qd_num++; | 524 | qa->qa_qd_num++; |
525 | qd++; | 525 | qd++; |
526 | } | 526 | } |
527 | 527 | ||
@@ -529,7 +529,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
529 | error = qdsb_get(sdp, QUOTA_GROUP, gid, qd); | 529 | error = qdsb_get(sdp, QUOTA_GROUP, gid, qd); |
530 | if (error) | 530 | if (error) |
531 | goto out; | 531 | goto out; |
532 | al->al_qd_num++; | 532 | qa->qa_qd_num++; |
533 | qd++; | 533 | qd++; |
534 | } | 534 | } |
535 | 535 | ||
@@ -542,16 +542,16 @@ out: | |||
542 | void gfs2_quota_unhold(struct gfs2_inode *ip) | 542 | void gfs2_quota_unhold(struct gfs2_inode *ip) |
543 | { | 543 | { |
544 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 544 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
545 | struct gfs2_alloc *al = ip->i_alloc; | 545 | struct gfs2_qadata *qa = ip->i_qadata; |
546 | unsigned int x; | 546 | unsigned int x; |
547 | 547 | ||
548 | gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags)); | 548 | gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags)); |
549 | 549 | ||
550 | for (x = 0; x < al->al_qd_num; x++) { | 550 | for (x = 0; x < qa->qa_qd_num; x++) { |
551 | qdsb_put(al->al_qd[x]); | 551 | qdsb_put(qa->qa_qd[x]); |
552 | al->al_qd[x] = NULL; | 552 | qa->qa_qd[x] = NULL; |
553 | } | 553 | } |
554 | al->al_qd_num = 0; | 554 | qa->qa_qd_num = 0; |
555 | } | 555 | } |
556 | 556 | ||
557 | static int sort_qd(const void *a, const void *b) | 557 | static int sort_qd(const void *a, const void *b) |
@@ -762,7 +762,6 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda) | |||
762 | struct gfs2_quota_data *qd; | 762 | struct gfs2_quota_data *qd; |
763 | loff_t offset; | 763 | loff_t offset; |
764 | unsigned int nalloc = 0, blocks; | 764 | unsigned int nalloc = 0, blocks; |
765 | struct gfs2_alloc *al = NULL; | ||
766 | int error; | 765 | int error; |
767 | 766 | ||
768 | gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota), | 767 | gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota), |
@@ -792,26 +791,19 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda) | |||
792 | nalloc++; | 791 | nalloc++; |
793 | } | 792 | } |
794 | 793 | ||
795 | al = gfs2_alloc_get(ip); | ||
796 | if (!al) { | ||
797 | error = -ENOMEM; | ||
798 | goto out_gunlock; | ||
799 | } | ||
800 | /* | 794 | /* |
801 | * 1 blk for unstuffing inode if stuffed. We add this extra | 795 | * 1 blk for unstuffing inode if stuffed. We add this extra |
802 | * block to the reservation unconditionally. If the inode | 796 | * block to the reservation unconditionally. If the inode |
803 | * doesn't need unstuffing, the block will be released to the | 797 | * doesn't need unstuffing, the block will be released to the |
804 | * rgrp since it won't be allocated during the transaction | 798 | * rgrp since it won't be allocated during the transaction |
805 | */ | 799 | */ |
806 | al->al_requested = 1; | ||
807 | /* +3 in the end for unstuffing block, inode size update block | 800 | /* +3 in the end for unstuffing block, inode size update block |
808 | * and another block in case quota straddles page boundary and | 801 | * and another block in case quota straddles page boundary and |
809 | * two blocks need to be updated instead of 1 */ | 802 | * two blocks need to be updated instead of 1 */ |
810 | blocks = num_qd * data_blocks + RES_DINODE + num_qd + 3; | 803 | blocks = num_qd * data_blocks + RES_DINODE + num_qd + 3; |
811 | 804 | ||
812 | if (nalloc) | 805 | error = gfs2_inplace_reserve(ip, 1 + |
813 | al->al_requested += nalloc * (data_blocks + ind_blocks); | 806 | (nalloc * (data_blocks + ind_blocks))); |
814 | error = gfs2_inplace_reserve(ip); | ||
815 | if (error) | 807 | if (error) |
816 | goto out_alloc; | 808 | goto out_alloc; |
817 | 809 | ||
@@ -840,8 +832,6 @@ out_end_trans: | |||
840 | out_ipres: | 832 | out_ipres: |
841 | gfs2_inplace_release(ip); | 833 | gfs2_inplace_release(ip); |
842 | out_alloc: | 834 | out_alloc: |
843 | gfs2_alloc_put(ip); | ||
844 | out_gunlock: | ||
845 | gfs2_glock_dq_uninit(&i_gh); | 835 | gfs2_glock_dq_uninit(&i_gh); |
846 | out: | 836 | out: |
847 | while (qx--) | 837 | while (qx--) |
@@ -925,7 +915,7 @@ fail: | |||
925 | int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid) | 915 | int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid) |
926 | { | 916 | { |
927 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 917 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
928 | struct gfs2_alloc *al = ip->i_alloc; | 918 | struct gfs2_qadata *qa = ip->i_qadata; |
929 | struct gfs2_quota_data *qd; | 919 | struct gfs2_quota_data *qd; |
930 | unsigned int x; | 920 | unsigned int x; |
931 | int error = 0; | 921 | int error = 0; |
@@ -938,15 +928,15 @@ int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
938 | sdp->sd_args.ar_quota != GFS2_QUOTA_ON) | 928 | sdp->sd_args.ar_quota != GFS2_QUOTA_ON) |
939 | return 0; | 929 | return 0; |
940 | 930 | ||
941 | sort(al->al_qd, al->al_qd_num, sizeof(struct gfs2_quota_data *), | 931 | sort(qa->qa_qd, qa->qa_qd_num, sizeof(struct gfs2_quota_data *), |
942 | sort_qd, NULL); | 932 | sort_qd, NULL); |
943 | 933 | ||
944 | for (x = 0; x < al->al_qd_num; x++) { | 934 | for (x = 0; x < qa->qa_qd_num; x++) { |
945 | int force = NO_FORCE; | 935 | int force = NO_FORCE; |
946 | qd = al->al_qd[x]; | 936 | qd = qa->qa_qd[x]; |
947 | if (test_and_clear_bit(QDF_REFRESH, &qd->qd_flags)) | 937 | if (test_and_clear_bit(QDF_REFRESH, &qd->qd_flags)) |
948 | force = FORCE; | 938 | force = FORCE; |
949 | error = do_glock(qd, force, &al->al_qd_ghs[x]); | 939 | error = do_glock(qd, force, &qa->qa_qd_ghs[x]); |
950 | if (error) | 940 | if (error) |
951 | break; | 941 | break; |
952 | } | 942 | } |
@@ -955,7 +945,7 @@ int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
955 | set_bit(GIF_QD_LOCKED, &ip->i_flags); | 945 | set_bit(GIF_QD_LOCKED, &ip->i_flags); |
956 | else { | 946 | else { |
957 | while (x--) | 947 | while (x--) |
958 | gfs2_glock_dq_uninit(&al->al_qd_ghs[x]); | 948 | gfs2_glock_dq_uninit(&qa->qa_qd_ghs[x]); |
959 | gfs2_quota_unhold(ip); | 949 | gfs2_quota_unhold(ip); |
960 | } | 950 | } |
961 | 951 | ||
@@ -1000,7 +990,7 @@ static int need_sync(struct gfs2_quota_data *qd) | |||
1000 | 990 | ||
1001 | void gfs2_quota_unlock(struct gfs2_inode *ip) | 991 | void gfs2_quota_unlock(struct gfs2_inode *ip) |
1002 | { | 992 | { |
1003 | struct gfs2_alloc *al = ip->i_alloc; | 993 | struct gfs2_qadata *qa = ip->i_qadata; |
1004 | struct gfs2_quota_data *qda[4]; | 994 | struct gfs2_quota_data *qda[4]; |
1005 | unsigned int count = 0; | 995 | unsigned int count = 0; |
1006 | unsigned int x; | 996 | unsigned int x; |
@@ -1008,14 +998,14 @@ void gfs2_quota_unlock(struct gfs2_inode *ip) | |||
1008 | if (!test_and_clear_bit(GIF_QD_LOCKED, &ip->i_flags)) | 998 | if (!test_and_clear_bit(GIF_QD_LOCKED, &ip->i_flags)) |
1009 | goto out; | 999 | goto out; |
1010 | 1000 | ||
1011 | for (x = 0; x < al->al_qd_num; x++) { | 1001 | for (x = 0; x < qa->qa_qd_num; x++) { |
1012 | struct gfs2_quota_data *qd; | 1002 | struct gfs2_quota_data *qd; |
1013 | int sync; | 1003 | int sync; |
1014 | 1004 | ||
1015 | qd = al->al_qd[x]; | 1005 | qd = qa->qa_qd[x]; |
1016 | sync = need_sync(qd); | 1006 | sync = need_sync(qd); |
1017 | 1007 | ||
1018 | gfs2_glock_dq_uninit(&al->al_qd_ghs[x]); | 1008 | gfs2_glock_dq_uninit(&qa->qa_qd_ghs[x]); |
1019 | 1009 | ||
1020 | if (sync && qd_trylock(qd)) | 1010 | if (sync && qd_trylock(qd)) |
1021 | qda[count++] = qd; | 1011 | qda[count++] = qd; |
@@ -1048,7 +1038,7 @@ static int print_message(struct gfs2_quota_data *qd, char *type) | |||
1048 | int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) | 1038 | int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) |
1049 | { | 1039 | { |
1050 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1040 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1051 | struct gfs2_alloc *al = ip->i_alloc; | 1041 | struct gfs2_qadata *qa = ip->i_qadata; |
1052 | struct gfs2_quota_data *qd; | 1042 | struct gfs2_quota_data *qd; |
1053 | s64 value; | 1043 | s64 value; |
1054 | unsigned int x; | 1044 | unsigned int x; |
@@ -1060,8 +1050,8 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
1060 | if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) | 1050 | if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) |
1061 | return 0; | 1051 | return 0; |
1062 | 1052 | ||
1063 | for (x = 0; x < al->al_qd_num; x++) { | 1053 | for (x = 0; x < qa->qa_qd_num; x++) { |
1064 | qd = al->al_qd[x]; | 1054 | qd = qa->qa_qd[x]; |
1065 | 1055 | ||
1066 | if (!((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || | 1056 | if (!((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || |
1067 | (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags)))) | 1057 | (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags)))) |
@@ -1099,7 +1089,7 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
1099 | void gfs2_quota_change(struct gfs2_inode *ip, s64 change, | 1089 | void gfs2_quota_change(struct gfs2_inode *ip, s64 change, |
1100 | u32 uid, u32 gid) | 1090 | u32 uid, u32 gid) |
1101 | { | 1091 | { |
1102 | struct gfs2_alloc *al = ip->i_alloc; | 1092 | struct gfs2_qadata *qa = ip->i_qadata; |
1103 | struct gfs2_quota_data *qd; | 1093 | struct gfs2_quota_data *qd; |
1104 | unsigned int x; | 1094 | unsigned int x; |
1105 | 1095 | ||
@@ -1108,8 +1098,8 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change, | |||
1108 | if (ip->i_diskflags & GFS2_DIF_SYSTEM) | 1098 | if (ip->i_diskflags & GFS2_DIF_SYSTEM) |
1109 | return; | 1099 | return; |
1110 | 1100 | ||
1111 | for (x = 0; x < al->al_qd_num; x++) { | 1101 | for (x = 0; x < qa->qa_qd_num; x++) { |
1112 | qd = al->al_qd[x]; | 1102 | qd = qa->qa_qd[x]; |
1113 | 1103 | ||
1114 | if ((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || | 1104 | if ((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || |
1115 | (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags))) { | 1105 | (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags))) { |
@@ -1529,7 +1519,6 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, | |||
1529 | unsigned int data_blocks, ind_blocks; | 1519 | unsigned int data_blocks, ind_blocks; |
1530 | unsigned int blocks = 0; | 1520 | unsigned int blocks = 0; |
1531 | int alloc_required; | 1521 | int alloc_required; |
1532 | struct gfs2_alloc *al; | ||
1533 | loff_t offset; | 1522 | loff_t offset; |
1534 | int error; | 1523 | int error; |
1535 | 1524 | ||
@@ -1594,15 +1583,12 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, | |||
1594 | if (gfs2_is_stuffed(ip)) | 1583 | if (gfs2_is_stuffed(ip)) |
1595 | alloc_required = 1; | 1584 | alloc_required = 1; |
1596 | if (alloc_required) { | 1585 | if (alloc_required) { |
1597 | al = gfs2_alloc_get(ip); | ||
1598 | if (al == NULL) | ||
1599 | goto out_i; | ||
1600 | gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota), | 1586 | gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota), |
1601 | &data_blocks, &ind_blocks); | 1587 | &data_blocks, &ind_blocks); |
1602 | blocks = al->al_requested = 1 + data_blocks + ind_blocks; | 1588 | blocks = 1 + data_blocks + ind_blocks; |
1603 | error = gfs2_inplace_reserve(ip); | 1589 | error = gfs2_inplace_reserve(ip, blocks); |
1604 | if (error) | 1590 | if (error) |
1605 | goto out_alloc; | 1591 | goto out_i; |
1606 | blocks += gfs2_rg_blocks(ip); | 1592 | blocks += gfs2_rg_blocks(ip); |
1607 | } | 1593 | } |
1608 | 1594 | ||
@@ -1617,11 +1603,8 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, | |||
1617 | 1603 | ||
1618 | gfs2_trans_end(sdp); | 1604 | gfs2_trans_end(sdp); |
1619 | out_release: | 1605 | out_release: |
1620 | if (alloc_required) { | 1606 | if (alloc_required) |
1621 | gfs2_inplace_release(ip); | 1607 | gfs2_inplace_release(ip); |
1622 | out_alloc: | ||
1623 | gfs2_alloc_put(ip); | ||
1624 | } | ||
1625 | out_i: | 1608 | out_i: |
1626 | gfs2_glock_dq_uninit(&i_gh); | 1609 | gfs2_glock_dq_uninit(&i_gh); |
1627 | out_q: | 1610 | out_q: |