aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/move_extents.c5
-rw-r--r--fs/ocfs2/suballoc.c25
-rw-r--r--fs/ocfs2/suballoc.h4
3 files changed, 32 insertions, 2 deletions
diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c
index 3ca939552d9c..599eb4c4c8be 100644
--- a/fs/ocfs2/move_extents.c
+++ b/fs/ocfs2/move_extents.c
@@ -691,8 +691,11 @@ static int ocfs2_move_extent(struct ocfs2_move_extents_context *context,
691 691
692 ret = ocfs2_block_group_set_bits(handle, gb_inode, gd, gd_bh, 692 ret = ocfs2_block_group_set_bits(handle, gb_inode, gd, gd_bh,
693 goal_bit, len); 693 goal_bit, len);
694 if (ret) 694 if (ret) {
695 ocfs2_rollback_alloc_dinode_counts(gb_inode, gb_bh, len,
696 le16_to_cpu(gd->bg_chain));
695 mlog_errno(ret); 697 mlog_errno(ret);
698 }
696 699
697 /* 700 /*
698 * Here we should write the new page out first if we are 701 * Here we should write the new page out first if we are
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index 482d6c2a3ea1..94fb1f3d9e62 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -1608,6 +1608,21 @@ out:
1608 return ret; 1608 return ret;
1609} 1609}
1610 1610
1611void ocfs2_rollback_alloc_dinode_counts(struct inode *inode,
1612 struct buffer_head *di_bh,
1613 u32 num_bits,
1614 u16 chain)
1615{
1616 u32 tmp_used;
1617 struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data;
1618 struct ocfs2_chain_list *cl;
1619
1620 cl = (struct ocfs2_chain_list *)&di->id2.i_chain;
1621 tmp_used = le32_to_cpu(di->id1.bitmap1.i_used);
1622 di->id1.bitmap1.i_used = cpu_to_le32(tmp_used - num_bits);
1623 le32_add_cpu(&cl->cl_recs[chain].c_free, num_bits);
1624}
1625
1611static int ocfs2_bg_discontig_fix_by_rec(struct ocfs2_suballoc_result *res, 1626static int ocfs2_bg_discontig_fix_by_rec(struct ocfs2_suballoc_result *res,
1612 struct ocfs2_extent_rec *rec, 1627 struct ocfs2_extent_rec *rec,
1613 struct ocfs2_chain_list *cl) 1628 struct ocfs2_chain_list *cl)
@@ -1708,8 +1723,12 @@ static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac,
1708 1723
1709 ret = ocfs2_block_group_set_bits(handle, alloc_inode, gd, group_bh, 1724 ret = ocfs2_block_group_set_bits(handle, alloc_inode, gd, group_bh,
1710 res->sr_bit_offset, res->sr_bits); 1725 res->sr_bit_offset, res->sr_bits);
1711 if (ret < 0) 1726 if (ret < 0) {
1727 ocfs2_rollback_alloc_dinode_counts(alloc_inode, ac->ac_bh,
1728 res->sr_bits,
1729 le16_to_cpu(gd->bg_chain));
1712 mlog_errno(ret); 1730 mlog_errno(ret);
1731 }
1713 1732
1714out_loc_only: 1733out_loc_only:
1715 *bits_left = le16_to_cpu(gd->bg_free_bits_count); 1734 *bits_left = le16_to_cpu(gd->bg_free_bits_count);
@@ -1839,6 +1858,8 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac,
1839 res->sr_bit_offset, 1858 res->sr_bit_offset,
1840 res->sr_bits); 1859 res->sr_bits);
1841 if (status < 0) { 1860 if (status < 0) {
1861 ocfs2_rollback_alloc_dinode_counts(alloc_inode,
1862 ac->ac_bh, res->sr_bits, chain);
1842 mlog_errno(status); 1863 mlog_errno(status);
1843 goto bail; 1864 goto bail;
1844 } 1865 }
@@ -2150,6 +2171,8 @@ int ocfs2_claim_new_inode_at_loc(handle_t *handle,
2150 res->sr_bit_offset, 2171 res->sr_bit_offset,
2151 res->sr_bits); 2172 res->sr_bits);
2152 if (ret < 0) { 2173 if (ret < 0) {
2174 ocfs2_rollback_alloc_dinode_counts(ac->ac_inode,
2175 ac->ac_bh, res->sr_bits, chain);
2153 mlog_errno(ret); 2176 mlog_errno(ret);
2154 goto out; 2177 goto out;
2155 } 2178 }
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h
index 218d8036b3e7..2d2501767c0c 100644
--- a/fs/ocfs2/suballoc.h
+++ b/fs/ocfs2/suballoc.h
@@ -91,6 +91,10 @@ int ocfs2_alloc_dinode_update_counts(struct inode *inode,
91 struct buffer_head *di_bh, 91 struct buffer_head *di_bh,
92 u32 num_bits, 92 u32 num_bits,
93 u16 chain); 93 u16 chain);
94void ocfs2_rollback_alloc_dinode_counts(struct inode *inode,
95 struct buffer_head *di_bh,
96 u32 num_bits,
97 u16 chain);
94int ocfs2_block_group_set_bits(handle_t *handle, 98int ocfs2_block_group_set_bits(handle_t *handle,
95 struct inode *alloc_inode, 99 struct inode *alloc_inode,
96 struct ocfs2_group_desc *bg, 100 struct ocfs2_group_desc *bg,