diff options
Diffstat (limited to 'fs/ocfs2/suballoc.c')
-rw-r--r-- | fs/ocfs2/suballoc.c | 29 |
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 | ||
1611 | void 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 | |||
1610 | static int ocfs2_bg_discontig_fix_by_rec(struct ocfs2_suballoc_result *res, | 1626 | static 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 | ||
1713 | out_loc_only: | 1733 | out_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); | |
2095 | out: | 2117 | out: |
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; |