aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/alloc.c28
-rw-r--r--fs/ocfs2/alloc.h2
-rw-r--r--fs/ocfs2/dir.c2
-rw-r--r--fs/ocfs2/file.c2
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
7149bail: 7161bail:
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
147int ocfs2_num_free_extents(struct ocfs2_super *osb, 147int 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;