diff options
Diffstat (limited to 'fs/ocfs2/alloc.c')
-rw-r--r-- | fs/ocfs2/alloc.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index a93bf9892256..fcae9ef1a328 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -5662,7 +5662,7 @@ int ocfs2_remove_btree_range(struct inode *inode, | |||
5662 | struct ocfs2_extent_tree *et, | 5662 | struct ocfs2_extent_tree *et, |
5663 | u32 cpos, u32 phys_cpos, u32 len, int flags, | 5663 | u32 cpos, u32 phys_cpos, u32 len, int flags, |
5664 | struct ocfs2_cached_dealloc_ctxt *dealloc, | 5664 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
5665 | u64 refcount_loc) | 5665 | u64 refcount_loc, bool refcount_tree_locked) |
5666 | { | 5666 | { |
5667 | int ret, credits = 0, extra_blocks = 0; | 5667 | int ret, credits = 0, extra_blocks = 0; |
5668 | u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos); | 5668 | u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos); |
@@ -5676,11 +5676,13 @@ int ocfs2_remove_btree_range(struct inode *inode, | |||
5676 | BUG_ON(!(OCFS2_I(inode)->ip_dyn_features & | 5676 | BUG_ON(!(OCFS2_I(inode)->ip_dyn_features & |
5677 | OCFS2_HAS_REFCOUNT_FL)); | 5677 | OCFS2_HAS_REFCOUNT_FL)); |
5678 | 5678 | ||
5679 | ret = ocfs2_lock_refcount_tree(osb, refcount_loc, 1, | 5679 | if (!refcount_tree_locked) { |
5680 | &ref_tree, NULL); | 5680 | ret = ocfs2_lock_refcount_tree(osb, refcount_loc, 1, |
5681 | if (ret) { | 5681 | &ref_tree, NULL); |
5682 | mlog_errno(ret); | 5682 | if (ret) { |
5683 | goto bail; | 5683 | mlog_errno(ret); |
5684 | goto bail; | ||
5685 | } | ||
5684 | } | 5686 | } |
5685 | 5687 | ||
5686 | ret = ocfs2_prepare_refcount_change_for_del(inode, | 5688 | ret = ocfs2_prepare_refcount_change_for_del(inode, |
@@ -7021,6 +7023,7 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb, | |||
7021 | u64 refcount_loc = le64_to_cpu(di->i_refcount_loc); | 7023 | u64 refcount_loc = le64_to_cpu(di->i_refcount_loc); |
7022 | struct ocfs2_extent_tree et; | 7024 | struct ocfs2_extent_tree et; |
7023 | struct ocfs2_cached_dealloc_ctxt dealloc; | 7025 | struct ocfs2_cached_dealloc_ctxt dealloc; |
7026 | struct ocfs2_refcount_tree *ref_tree = NULL; | ||
7024 | 7027 | ||
7025 | ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh); | 7028 | ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh); |
7026 | ocfs2_init_dealloc_ctxt(&dealloc); | 7029 | ocfs2_init_dealloc_ctxt(&dealloc); |
@@ -7130,9 +7133,18 @@ start: | |||
7130 | 7133 | ||
7131 | phys_cpos = ocfs2_blocks_to_clusters(inode->i_sb, blkno); | 7134 | phys_cpos = ocfs2_blocks_to_clusters(inode->i_sb, blkno); |
7132 | 7135 | ||
7136 | if ((flags & OCFS2_EXT_REFCOUNTED) && trunc_len && !ref_tree) { | ||
7137 | status = ocfs2_lock_refcount_tree(osb, refcount_loc, 1, | ||
7138 | &ref_tree, NULL); | ||
7139 | if (status) { | ||
7140 | mlog_errno(status); | ||
7141 | goto bail; | ||
7142 | } | ||
7143 | } | ||
7144 | |||
7133 | status = ocfs2_remove_btree_range(inode, &et, trunc_cpos, | 7145 | status = ocfs2_remove_btree_range(inode, &et, trunc_cpos, |
7134 | phys_cpos, trunc_len, flags, &dealloc, | 7146 | phys_cpos, trunc_len, flags, &dealloc, |
7135 | refcount_loc); | 7147 | refcount_loc, true); |
7136 | if (status < 0) { | 7148 | if (status < 0) { |
7137 | mlog_errno(status); | 7149 | mlog_errno(status); |
7138 | goto bail; | 7150 | goto bail; |
@@ -7147,6 +7159,8 @@ start: | |||
7147 | goto start; | 7159 | goto start; |
7148 | 7160 | ||
7149 | bail: | 7161 | bail: |
7162 | if (ref_tree) | ||
7163 | ocfs2_unlock_refcount_tree(osb, ref_tree, 1); | ||
7150 | 7164 | ||
7151 | ocfs2_schedule_truncate_log_flush(osb, 1); | 7165 | ocfs2_schedule_truncate_log_flush(osb, 1); |
7152 | 7166 | ||