]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/ocfs2/alloc.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
[karo-tx-linux.git] / fs / ocfs2 / alloc.c
index a93bf98922565ab120d85f995f0cb565deb1e144..fcae9ef1a328750ca08cda37691bb51dad5293ef 100644 (file)
@@ -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);