Btrfs: add helper for em merge logic
authorLiu Bo <bo.li.liu@oracle.com>
Fri, 5 Jan 2018 19:51:10 +0000 (12:51 -0700)
committerDavid Sterba <dsterba@suse.com>
Mon, 22 Jan 2018 15:08:21 +0000 (16:08 +0100)
This is a prepare work for the following extent map selftest, which
runs tests against em merge logic.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
Reviewed-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/ctree.h
fs/btrfs/inode.c

index 1a462ab85c49888a3962b026a74ede8c47182fc1..1e05fc7e0e3594005ebe5e98eef89a2f4a6b811c 100644 (file)
@@ -3143,6 +3143,8 @@ struct btrfs_delalloc_work *btrfs_alloc_delalloc_work(struct inode *inode,
                                                    int delay_iput);
 void btrfs_wait_and_free_delalloc_work(struct btrfs_delalloc_work *work);
 
+int btrfs_add_extent_mapping(struct extent_map_tree *em_tree,
+                            struct extent_map **em_in, u64 start, u64 len);
 struct extent_map *btrfs_get_extent_fiemap(struct btrfs_inode *inode,
                struct page *page, size_t pg_offset, u64 start,
                u64 len, int create);
index 4ab713bd413949cf57ab406dea972086e851cdaa..c6a05ee3d74b7de764dde8513e0a9279f5525611 100644 (file)
@@ -6925,6 +6925,51 @@ static noinline int uncompress_inline(struct btrfs_path *path,
        return ret;
 }
 
+int btrfs_add_extent_mapping(struct extent_map_tree *em_tree,
+                            struct extent_map **em_in, u64 start, u64 len)
+{
+       int ret;
+       struct extent_map *em = *em_in;
+
+       ret = add_extent_mapping(em_tree, em, 0);
+       /* it is possible that someone inserted the extent into the tree
+        * while we had the lock dropped.  It is also possible that
+        * an overlapping map exists in the tree
+        */
+       if (ret == -EEXIST) {
+               struct extent_map *existing;
+
+               ret = 0;
+
+               existing = search_extent_mapping(em_tree, start, len);
+               /*
+                * existing will always be non-NULL, since there must be
+                * extent causing the -EEXIST.
+                */
+               if (start >= existing->start &&
+                   start < extent_map_end(existing)) {
+                       free_extent_map(em);
+                       *em_in = existing;
+                       ret = 0;
+               } else {
+                       /*
+                        * The existing extent map is the one nearest to
+                        * the [start, start + len) range which overlaps
+                        */
+                       ret = merge_extent_mapping(em_tree, existing,
+                                                  em, start);
+                       free_extent_map(existing);
+                       if (ret) {
+                               free_extent_map(em);
+                               *em_in = NULL;
+                       }
+               }
+       }
+
+       ASSERT(ret == 0 || ret == -EEXIST);
+       return ret;
+}
+
 /*
  * a bit scary, this does extent mapping from logical file offset to the disk.
  * the ugly parts come from merging extents from the disk with the in-ram
@@ -7138,40 +7183,7 @@ insert:
 
        err = 0;
        write_lock(&em_tree->lock);
-       ret = add_extent_mapping(em_tree, em, 0);
-       /* it is possible that someone inserted the extent into the tree
-        * while we had the lock dropped.  It is also possible that
-        * an overlapping map exists in the tree
-        */
-       if (ret == -EEXIST) {
-               struct extent_map *existing;
-
-               ret = 0;
-
-               existing = search_extent_mapping(em_tree, start, len);
-               /*
-                * existing will always be non-NULL, since there must be
-                * extent causing the -EEXIST.
-                */
-               if (start >= existing->start &&
-                   start < extent_map_end(existing)) {
-                       free_extent_map(em);
-                       em = existing;
-                       err = 0;
-               } else {
-                       /*
-                        * The existing extent map is the one nearest to
-                        * the [start, start + len) range which overlaps
-                        */
-                       err = merge_extent_mapping(em_tree, existing,
-                                                  em, start);
-                       free_extent_map(existing);
-                       if (err) {
-                               free_extent_map(em);
-                               em = NULL;
-                       }
-               }
-       }
+       err = btrfs_add_extent_mapping(em_tree, &em, start, len);
        write_unlock(&em_tree->lock);
 out: