Signed-off-by: Edmund Nadolski <enadol...@suse.com>
Signed-off-by: Jeff Mahoney <je...@suse.com>
---
 fs/btrfs/backref.c   | 30 +++++++++++++++++++-----------
 fs/btrfs/backref.h   |  4 +---
 fs/btrfs/extent_io.c | 22 +++-------------------
 3 files changed, 23 insertions(+), 33 deletions(-)

diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 3725277..35cfa38 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -1580,20 +1580,21 @@ int btrfs_find_all_roots(struct btrfs_trans_handle 
*trans,
 /**
  * btrfs_check_shared - tell us whether an extent is shared
  *
- * @trans: optional trans handle
- *
  * btrfs_check_shared uses the backref walking code but will short
  * circuit as soon as it finds a root or inode that doesn't match the
  * one passed in. This provides a significant performance benefit for
  * callers (such as fiemap) which want to know whether the extent is
  * shared but do not need a ref count.
  *
+ * This attempts to allocate a transaction in order to account for
+ * delayed refs, but continues on even when the alloc fails.
+ *
  * Return: 0 if extent is not shared, 1 if it is shared, < 0 on error.
  */
-int btrfs_check_shared(struct btrfs_trans_handle *trans,
-                      struct btrfs_fs_info *fs_info, u64 root_objectid,
-                      u64 inum, u64 bytenr)
+int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr)
 {
+       struct btrfs_fs_info *fs_info = root->fs_info;
+       struct btrfs_trans_handle *trans;
        struct ulist *tmp = NULL;
        struct ulist *roots = NULL;
        struct ulist_iterator uiter;
@@ -1609,14 +1610,18 @@ int btrfs_check_shared(struct btrfs_trans_handle *trans,
                return -ENOMEM;
        }
 
-       if (trans)
-               btrfs_get_tree_mod_seq(fs_info, &elem);
-       else
+       trans = btrfs_join_transaction(root);
+       if (IS_ERR(trans)) {
+               trans = NULL;
                down_read(&fs_info->commit_root_sem);
+       } else {
+               btrfs_get_tree_mod_seq(fs_info, &elem);
+       }
+
        ULIST_ITER_INIT(&uiter);
        while (1) {
                ret = find_parent_nodes(trans, fs_info, bytenr, elem.seq, tmp,
-                                       roots, NULL, root_objectid, inum, 1);
+                                       roots, NULL, root->objectid, inum, 1);
                if (ret == BACKREF_FOUND_SHARED) {
                        /* this is the only condition under which we return 1 */
                        ret = 1;
@@ -1631,10 +1636,13 @@ int btrfs_check_shared(struct btrfs_trans_handle *trans,
                bytenr = node->val;
                cond_resched();
        }
-       if (trans)
+
+       if (trans) {
                btrfs_put_tree_mod_seq(fs_info, &elem);
-       else
+               btrfs_end_transaction(trans);
+       } else {
                up_read(&fs_info->commit_root_sem);
+       }
        ulist_free(tmp);
        ulist_free(roots);
        return ret;
diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h
index 9c41fba..f9428aa 100644
--- a/fs/btrfs/backref.h
+++ b/fs/btrfs/backref.h
@@ -68,9 +68,7 @@ int btrfs_find_one_extref(struct btrfs_root *root, u64 
inode_objectid,
                          u64 start_off, struct btrfs_path *path,
                          struct btrfs_inode_extref **ret_extref,
                          u64 *found_off);
-int btrfs_check_shared(struct btrfs_trans_handle *trans,
-                      struct btrfs_fs_info *fs_info, u64 root_objectid,
-                      u64 inum, u64 bytenr);
+int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr);
 
 int __init btrfs_prelim_ref_init(void);
 void btrfs_prelim_ref_exit(void);
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 7ee62f6..ae31046 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -20,7 +20,6 @@
 #include "locking.h"
 #include "rcu-string.h"
 #include "backref.h"
-#include "transaction.h"
 
 static struct kmem_cache *extent_state_cache;
 static struct kmem_cache *extent_buffer_cache;
@@ -4607,36 +4606,21 @@ int extent_fiemap(struct inode *inode, struct 
fiemap_extent_info *fieinfo,
                        flags |= (FIEMAP_EXTENT_DELALLOC |
                                  FIEMAP_EXTENT_UNKNOWN);
                } else if (fieinfo->fi_extents_max) {
-                       struct btrfs_trans_handle *trans;
-
                        u64 bytenr = em->block_start -
                                (em->start - em->orig_start);
 
                        disko = em->block_start + offset_in_extent;
 
                        /*
-                        * We need a trans handle to get delayed refs
-                        */
-                       trans = btrfs_join_transaction(root);
-                       /*
-                        * It's OK if we can't start a trans we can still check
-                        * from commit_root
-                        */
-                       if (IS_ERR(trans))
-                               trans = NULL;
-
-                       /*
                         * As btrfs supports shared space, this information
                         * can be exported to userspace tools via
                         * flag FIEMAP_EXTENT_SHARED.  If fi_extents_max == 0
                         * then we're just getting a count and we can skip the
                         * lookup stuff.
                         */
-                       ret = btrfs_check_shared(trans, root->fs_info,
-                                       root->objectid,
-                                       btrfs_ino(BTRFS_I(inode)), bytenr);
-                       if (trans)
-                               btrfs_end_transaction(trans);
+                       ret = btrfs_check_shared(root,
+                                                btrfs_ino(BTRFS_I(inode)),
+                                                bytenr);
                        if (ret < 0)
                                goto out_free;
                        if (ret)
-- 
2.10.2

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to