diff options
-rw-r--r-- | fs/ocfs2/alloc.c | 28 | ||||
-rw-r--r-- | fs/ocfs2/alloc.h | 2 | ||||
-rw-r--r-- | fs/ocfs2/dir.c | 2 | ||||
-rw-r--r-- | fs/ocfs2/file.c | 2 |
4 files changed, 24 insertions, 10 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 | ||
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index ca381c584127..fb09b97db162 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h | |||
@@ -142,7 +142,7 @@ int ocfs2_remove_btree_range(struct inode *inode, | |||
142 | struct ocfs2_extent_tree *et, | 142 | struct ocfs2_extent_tree *et, |
143 | u32 cpos, u32 phys_cpos, u32 len, int flags, | 143 | u32 cpos, u32 phys_cpos, u32 len, int flags, |
144 | struct ocfs2_cached_dealloc_ctxt *dealloc, | 144 | struct ocfs2_cached_dealloc_ctxt *dealloc, |
145 | u64 refcount_loc); | 145 | u64 refcount_loc, bool refcount_tree_locked); |
146 | 146 | ||
147 | int ocfs2_num_free_extents(struct ocfs2_super *osb, | 147 | int ocfs2_num_free_extents(struct ocfs2_super *osb, |
148 | struct ocfs2_extent_tree *et); | 148 | struct ocfs2_extent_tree *et); |
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 79d56dc981bc..319e786175af 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
@@ -4479,7 +4479,7 @@ int ocfs2_dx_dir_truncate(struct inode *dir, struct buffer_head *di_bh) | |||
4479 | p_cpos = ocfs2_blocks_to_clusters(dir->i_sb, blkno); | 4479 | p_cpos = ocfs2_blocks_to_clusters(dir->i_sb, blkno); |
4480 | 4480 | ||
4481 | ret = ocfs2_remove_btree_range(dir, &et, cpos, p_cpos, clen, 0, | 4481 | ret = ocfs2_remove_btree_range(dir, &et, cpos, p_cpos, clen, 0, |
4482 | &dealloc, 0); | 4482 | &dealloc, 0, false); |
4483 | if (ret) { | 4483 | if (ret) { |
4484 | mlog_errno(ret); | 4484 | mlog_errno(ret); |
4485 | goto out; | 4485 | goto out; |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 69fb9f75b082..3950693dd0f6 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1803,7 +1803,7 @@ static int ocfs2_remove_inode_range(struct inode *inode, | |||
1803 | 1803 | ||
1804 | ret = ocfs2_remove_btree_range(inode, &et, trunc_cpos, | 1804 | ret = ocfs2_remove_btree_range(inode, &et, trunc_cpos, |
1805 | phys_cpos, trunc_len, flags, | 1805 | phys_cpos, trunc_len, flags, |
1806 | &dealloc, refcount_loc); | 1806 | &dealloc, refcount_loc, false); |
1807 | if (ret < 0) { | 1807 | if (ret < 0) { |
1808 | mlog_errno(ret); | 1808 | mlog_errno(ret); |
1809 | goto out; | 1809 | goto out; |