|
@@ -5662,7 +5662,7 @@ int ocfs2_remove_btree_range(struct inode *inode,
|
|
|
struct ocfs2_extent_tree *et,
|
|
|
u32 cpos, u32 phys_cpos, u32 len, int flags,
|
|
|
struct ocfs2_cached_dealloc_ctxt *dealloc,
|
|
|
- u64 refcount_loc)
|
|
|
+ u64 refcount_loc, bool refcount_tree_locked)
|
|
|
{
|
|
|
int ret, credits = 0, extra_blocks = 0;
|
|
|
u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos);
|
|
@@ -5676,11 +5676,13 @@ int ocfs2_remove_btree_range(struct inode *inode,
|
|
|
BUG_ON(!(OCFS2_I(inode)->ip_dyn_features &
|
|
|
OCFS2_HAS_REFCOUNT_FL));
|
|
|
|
|
|
- ret = ocfs2_lock_refcount_tree(osb, refcount_loc, 1,
|
|
|
- &ref_tree, NULL);
|
|
|
- if (ret) {
|
|
|
- mlog_errno(ret);
|
|
|
- goto bail;
|
|
|
+ if (!refcount_tree_locked) {
|
|
|
+ ret = ocfs2_lock_refcount_tree(osb, refcount_loc, 1,
|
|
|
+ &ref_tree, NULL);
|
|
|
+ if (ret) {
|
|
|
+ mlog_errno(ret);
|
|
|
+ goto bail;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
ret = ocfs2_prepare_refcount_change_for_del(inode,
|
|
@@ -7021,6 +7023,7 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb,
|
|
|
u64 refcount_loc = le64_to_cpu(di->i_refcount_loc);
|
|
|
struct ocfs2_extent_tree et;
|
|
|
struct ocfs2_cached_dealloc_ctxt dealloc;
|
|
|
+ struct ocfs2_refcount_tree *ref_tree = NULL;
|
|
|
|
|
|
ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh);
|
|
|
ocfs2_init_dealloc_ctxt(&dealloc);
|
|
@@ -7130,9 +7133,18 @@ start:
|
|
|
|
|
|
phys_cpos = ocfs2_blocks_to_clusters(inode->i_sb, blkno);
|
|
|
|
|
|
+ if ((flags & OCFS2_EXT_REFCOUNTED) && trunc_len && !ref_tree) {
|
|
|
+ status = ocfs2_lock_refcount_tree(osb, refcount_loc, 1,
|
|
|
+ &ref_tree, NULL);
|
|
|
+ if (status) {
|
|
|
+ mlog_errno(status);
|
|
|
+ goto bail;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
status = ocfs2_remove_btree_range(inode, &et, trunc_cpos,
|
|
|
phys_cpos, trunc_len, flags, &dealloc,
|
|
|
- refcount_loc);
|
|
|
+ refcount_loc, true);
|
|
|
if (status < 0) {
|
|
|
mlog_errno(status);
|
|
|
goto bail;
|
|
@@ -7147,6 +7159,8 @@ start:
|
|
|
goto start;
|
|
|
|
|
|
bail:
|
|
|
+ if (ref_tree)
|
|
|
+ ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
|
|
|
|
|
|
ocfs2_schedule_truncate_log_flush(osb, 1);
|
|
|
|