aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
authorAbhijith Das <adas@redhat.com>2008-03-06 18:43:52 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2008-03-31 05:41:30 -0400
commit20b95bf2c4c5c28e093aa42699e67829b6cd7fd0 (patch)
treee611fb6ee336f37609a5881a0846ffdf80bf58dc /fs/gfs2
parent182fe5abd8ebbb3a00c1be91f44e4783e139918c (diff)
[GFS2] gfs2_adjust_quota has broken unstuffing code
This patch combines the 2 patches in bug 434736 to correct the lock ordering in the unstuffing of the quota inode in gfs2_adjust_quota and adjusting the number of revokes in gfs2_write_jdata_pagevec Signed-off-by: Abhijith Das <adas@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/ops_address.c3
-rw-r--r--fs/gfs2/quota.c71
2 files changed, 31 insertions, 43 deletions
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 2483d8741060..e72fd47d71eb 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -21,7 +21,6 @@
21#include <linux/gfs2_ondisk.h> 21#include <linux/gfs2_ondisk.h>
22#include <linux/lm_interface.h> 22#include <linux/lm_interface.h>
23#include <linux/backing-dev.h> 23#include <linux/backing-dev.h>
24#include <linux/pagevec.h>
25 24
26#include "gfs2.h" 25#include "gfs2.h"
27#include "incore.h" 26#include "incore.h"
@@ -278,7 +277,7 @@ static int gfs2_write_jdata_pagevec(struct address_space *mapping,
278 int i; 277 int i;
279 int ret; 278 int ret;
280 279
281 ret = gfs2_trans_begin(sdp, nrblocks, 0); 280 ret = gfs2_trans_begin(sdp, nrblocks, nrblocks);
282 if (ret < 0) 281 if (ret < 0)
283 return ret; 282 return ret;
284 283
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 636bccfd2bcf..c71f781db5d7 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -616,17 +616,9 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
616 s64 value; 616 s64 value;
617 int err = -EIO; 617 int err = -EIO;
618 618
619 if (gfs2_is_stuffed(ip)) { 619 if (gfs2_is_stuffed(ip))
620 struct gfs2_alloc *al = gfs2_alloc_get(ip);
621 if (!al)
622 return -ENOMEM;
623 /* just request 1 blk */
624 al->al_requested = 1;
625 gfs2_inplace_reserve(ip);
626 gfs2_unstuff_dinode(ip, NULL); 620 gfs2_unstuff_dinode(ip, NULL);
627 gfs2_inplace_release(ip); 621
628 gfs2_alloc_put(ip);
629 }
630 page = grab_cache_page(mapping, index); 622 page = grab_cache_page(mapping, index);
631 if (!page) 623 if (!page)
632 return -ENOMEM; 624 return -ENOMEM;
@@ -691,7 +683,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
691 unsigned int qx, x; 683 unsigned int qx, x;
692 struct gfs2_quota_data *qd; 684 struct gfs2_quota_data *qd;
693 loff_t offset; 685 loff_t offset;
694 unsigned int nalloc = 0; 686 unsigned int nalloc = 0, blocks;
695 struct gfs2_alloc *al = NULL; 687 struct gfs2_alloc *al = NULL;
696 int error; 688 int error;
697 689
@@ -728,34 +720,33 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
728 nalloc++; 720 nalloc++;
729 } 721 }
730 722
731 if (nalloc) { 723 al = gfs2_alloc_get(ip);
732 al = gfs2_alloc_get(ip); 724 if (!al) {
733 if (!al) { 725 error = -ENOMEM;
734 error = -ENOMEM; 726 goto out_gunlock;
735 goto out_gunlock; 727 }
736 } 728 /*
729 * 1 blk for unstuffing inode if stuffed. We add this extra
730 * block to the reservation unconditionally. If the inode
731 * doesn't need unstuffing, the block will be released to the
732 * rgrp since it won't be allocated during the transaction
733 */
734 al->al_requested = 1;
735 /* +1 in the end for block requested above for unstuffing */
736 blocks = num_qd * data_blocks + RES_DINODE + num_qd + 1;
737 737
738 al->al_requested = nalloc * (data_blocks + ind_blocks); 738 if (nalloc)
739 al->al_requested += nalloc * (data_blocks + ind_blocks);
740 error = gfs2_inplace_reserve(ip);
741 if (error)
742 goto out_alloc;
739 743
740 error = gfs2_inplace_reserve(ip); 744 if (nalloc)
741 if (error) 745 blocks += al->al_rgd->rd_length + nalloc * ind_blocks + RES_STATFS;
742 goto out_alloc; 746
743 747 error = gfs2_trans_begin(sdp, blocks, 0);
744 error = gfs2_trans_begin(sdp, 748 if (error)
745 al->al_rgd->rd_length + 749 goto out_ipres;
746 num_qd * data_blocks +
747 nalloc * ind_blocks +
748 RES_DINODE + num_qd +
749 RES_STATFS, 0);
750 if (error)
751 goto out_ipres;
752 } else {
753 error = gfs2_trans_begin(sdp,
754 num_qd * data_blocks +
755 RES_DINODE + num_qd, 0);
756 if (error)
757 goto out_gunlock;
758 }
759 750
760 for (x = 0; x < num_qd; x++) { 751 for (x = 0; x < num_qd; x++) {
761 qd = qda[x]; 752 qd = qda[x];
@@ -774,11 +765,9 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
774out_end_trans: 765out_end_trans:
775 gfs2_trans_end(sdp); 766 gfs2_trans_end(sdp);
776out_ipres: 767out_ipres:
777 if (nalloc) 768 gfs2_inplace_release(ip);
778 gfs2_inplace_release(ip);
779out_alloc: 769out_alloc:
780 if (nalloc) 770 gfs2_alloc_put(ip);
781 gfs2_alloc_put(ip);
782out_gunlock: 771out_gunlock:
783 gfs2_glock_dq_uninit(&i_gh); 772 gfs2_glock_dq_uninit(&i_gh);
784out: 773out: