aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/suballoc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/suballoc.c')
-rw-r--r--fs/ocfs2/suballoc.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index 47ae2663a6f5..0cb889a17ae1 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -771,6 +771,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
771 spin_unlock(&OCFS2_I(alloc_inode)->ip_lock); 771 spin_unlock(&OCFS2_I(alloc_inode)->ip_lock);
772 i_size_write(alloc_inode, le64_to_cpu(fe->i_size)); 772 i_size_write(alloc_inode, le64_to_cpu(fe->i_size));
773 alloc_inode->i_blocks = ocfs2_inode_sector_count(alloc_inode); 773 alloc_inode->i_blocks = ocfs2_inode_sector_count(alloc_inode);
774 ocfs2_update_inode_fsync_trans(handle, alloc_inode, 0);
774 775
775 status = 0; 776 status = 0;
776 777
@@ -1607,6 +1608,21 @@ out:
1607 return ret; 1608 return ret;
1608} 1609}
1609 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
1610static 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,
1611 struct ocfs2_extent_rec *rec, 1627 struct ocfs2_extent_rec *rec,
1612 struct ocfs2_chain_list *cl) 1628 struct ocfs2_chain_list *cl)
@@ -1707,8 +1723,12 @@ static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac,
1707 1723
1708 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,
1709 res->sr_bit_offset, res->sr_bits); 1725 res->sr_bit_offset, res->sr_bits);
1710 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));
1711 mlog_errno(ret); 1730 mlog_errno(ret);
1731 }
1712 1732
1713out_loc_only: 1733out_loc_only:
1714 *bits_left = le16_to_cpu(gd->bg_free_bits_count); 1734 *bits_left = le16_to_cpu(gd->bg_free_bits_count);
@@ -1838,6 +1858,8 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac,
1838 res->sr_bit_offset, 1858 res->sr_bit_offset,
1839 res->sr_bits); 1859 res->sr_bits);
1840 if (status < 0) { 1860 if (status < 0) {
1861 ocfs2_rollback_alloc_dinode_counts(alloc_inode,
1862 ac->ac_bh, res->sr_bits, chain);
1841 mlog_errno(status); 1863 mlog_errno(status);
1842 goto bail; 1864 goto bail;
1843 } 1865 }
@@ -2091,7 +2113,7 @@ int ocfs2_find_new_inode_loc(struct inode *dir,
2091 2113
2092 ac->ac_find_loc_priv = res; 2114 ac->ac_find_loc_priv = res;
2093 *fe_blkno = res->sr_blkno; 2115 *fe_blkno = res->sr_blkno;
2094 2116 ocfs2_update_inode_fsync_trans(handle, dir, 0);
2095out: 2117out:
2096 if (handle) 2118 if (handle)
2097 ocfs2_commit_trans(OCFS2_SB(dir->i_sb), handle); 2119 ocfs2_commit_trans(OCFS2_SB(dir->i_sb), handle);
@@ -2149,6 +2171,8 @@ int ocfs2_claim_new_inode_at_loc(handle_t *handle,
2149 res->sr_bit_offset, 2171 res->sr_bit_offset,
2150 res->sr_bits); 2172 res->sr_bits);
2151 if (ret < 0) { 2173 if (ret < 0) {
2174 ocfs2_rollback_alloc_dinode_counts(ac->ac_inode,
2175 ac->ac_bh, res->sr_bits, chain);
2152 mlog_errno(ret); 2176 mlog_errno(ret);
2153 goto out; 2177 goto out;
2154 } 2178 }
@@ -2870,6 +2894,7 @@ int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res)
2870 status = ocfs2_inode_lock(inode_alloc_inode, &alloc_bh, 0); 2894 status = ocfs2_inode_lock(inode_alloc_inode, &alloc_bh, 0);
2871 if (status < 0) { 2895 if (status < 0) {
2872 mutex_unlock(&inode_alloc_inode->i_mutex); 2896 mutex_unlock(&inode_alloc_inode->i_mutex);
2897 iput(inode_alloc_inode);
2873 mlog(ML_ERROR, "lock on alloc inode on slot %u failed %d\n", 2898 mlog(ML_ERROR, "lock on alloc inode on slot %u failed %d\n",
2874 (u32)suballoc_slot, status); 2899 (u32)suballoc_slot, status);
2875 goto bail; 2900 goto bail;