diff options
Diffstat (limited to 'fs/ocfs2/alloc.c')
| -rw-r--r-- | fs/ocfs2/alloc.c | 40 | 
1 files changed, 36 insertions, 4 deletions
| diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 8750ae1b8636..e2edff38be52 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -4742,6 +4742,7 @@ int ocfs2_add_clusters_in_btree(handle_t *handle,  				enum ocfs2_alloc_restarted *reason_ret)  {  	int status = 0, err = 0; +	int need_free = 0;  	int free_extents;  	enum ocfs2_alloc_restarted reason = RESTART_NONE;  	u32 bit_off, num_bits; @@ -4796,7 +4797,8 @@ int ocfs2_add_clusters_in_btree(handle_t *handle,  					      OCFS2_JOURNAL_ACCESS_WRITE);  	if (status < 0) {  		mlog_errno(status); -		goto leave; +		need_free = 1; +		goto bail;  	}  	block = ocfs2_clusters_to_blocks(osb->sb, bit_off); @@ -4807,7 +4809,8 @@ int ocfs2_add_clusters_in_btree(handle_t *handle,  				     num_bits, flags, meta_ac);  	if (status < 0) {  		mlog_errno(status); -		goto leave; +		need_free = 1; +		goto bail;  	}  	ocfs2_journal_dirty(handle, et->et_root_bh); @@ -4821,6 +4824,19 @@ int ocfs2_add_clusters_in_btree(handle_t *handle,  		reason = RESTART_TRANS;  	} +bail: +	if (need_free) { +		if (data_ac->ac_which == OCFS2_AC_USE_LOCAL) +			ocfs2_free_local_alloc_bits(osb, handle, data_ac, +					bit_off, num_bits); +		else +			ocfs2_free_clusters(handle, +					data_ac->ac_inode, +					data_ac->ac_bh, +					ocfs2_clusters_to_blocks(osb->sb, bit_off), +					num_bits); +	} +  leave:  	if (reason_ret)  		*reason_ret = reason; @@ -6805,6 +6821,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,  					 struct buffer_head *di_bh)  {  	int ret, i, has_data, num_pages = 0; +	int need_free = 0; +	u32 bit_off, num;  	handle_t *handle;  	u64 uninitialized_var(block);  	struct ocfs2_inode_info *oi = OCFS2_I(inode); @@ -6850,7 +6868,6 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,  	}  	if (has_data) { -		u32 bit_off, num;  		unsigned int page_end;  		u64 phys; @@ -6886,6 +6903,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,  		ret = ocfs2_grab_eof_pages(inode, 0, end, pages, &num_pages);  		if (ret) {  			mlog_errno(ret); +			need_free = 1;  			goto out_commit;  		} @@ -6896,6 +6914,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,  		ret = ocfs2_read_inline_data(inode, pages[0], di_bh);  		if (ret) {  			mlog_errno(ret); +			need_free = 1;  			goto out_commit;  		} @@ -6927,6 +6946,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,  		ret = ocfs2_insert_extent(handle, &et, 0, block, 1, 0, NULL);  		if (ret) {  			mlog_errno(ret); +			need_free = 1;  			goto out_commit;  		} @@ -6938,6 +6958,18 @@ out_commit:  		dquot_free_space_nodirty(inode,  					  ocfs2_clusters_to_bytes(osb->sb, 1)); +	if (need_free) { +		if (data_ac->ac_which == OCFS2_AC_USE_LOCAL) +			ocfs2_free_local_alloc_bits(osb, handle, data_ac, +					bit_off, num); +		else +			ocfs2_free_clusters(handle, +					data_ac->ac_inode, +					data_ac->ac_bh, +					ocfs2_clusters_to_blocks(osb->sb, bit_off), +					num); +	} +  	ocfs2_commit_trans(osb, handle);  out_unlock: @@ -7126,7 +7158,7 @@ int ocfs2_truncate_inline(struct inode *inode, struct buffer_head *di_bh,  	if (end > i_size_read(inode))  		end = i_size_read(inode); -	BUG_ON(start >= end); +	BUG_ON(start > end);  	if (!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) ||  	    !(le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) || | 
