btrfs: Move and unexport btrfs_rmap_block
authorNikolay Borisov <nborisov@suse.com>
Tue, 10 Dec 2019 17:57:51 +0000 (19:57 +0200)
committerDavid Sterba <dsterba@suse.com>
Thu, 23 Jan 2020 16:24:34 +0000 (17:24 +0100)
It's used only during initial block group reading to map physical
address of super block to a list of logical ones. Make it private to
block-group.c, add proper kernel doc and ensure it's exported only for
tests.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/block-group.c
fs/btrfs/block-group.h
fs/btrfs/volumes.c
fs/btrfs/volumes.h

index 6480976ddc780fc12294b91126d435bb98f0e321..00cb40210b53226d1a00bcaa9fec800fe12e9eef 100644 (file)
@@ -15,6 +15,7 @@
 #include "tree-log.h"
 #include "delalloc-space.h"
 #include "discard.h"
+#include "raid56.h"
 
 /*
  * Return target flags in extended format or 0 if restripe for this chunk_type
@@ -1561,6 +1562,91 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
        write_sequnlock(&fs_info->profiles_lock);
 }
 
+/**
+ * btrfs_rmap_block - Map a physical disk address to a list of logical addresses
+ * @chunk_start:   logical address of block group
+ * @physical:     physical address to map to logical addresses
+ * @logical:      return array of logical addresses which map to @physical
+ * @naddrs:       length of @logical
+ * @stripe_len:    size of IO stripe for the given block group
+ *
+ * Maps a particular @physical disk address to a list of @logical addresses.
+ * Used primarily to exclude those portions of a block group that contain super
+ * block copies.
+ */
+EXPORT_FOR_TESTS
+int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start,
+                    u64 physical, u64 **logical, int *naddrs, int *stripe_len)
+{
+       struct extent_map *em;
+       struct map_lookup *map;
+       u64 *buf;
+       u64 bytenr;
+       u64 length;
+       u64 stripe_nr;
+       u64 rmap_len;
+       int i, j, nr = 0;
+
+       em = btrfs_get_chunk_map(fs_info, chunk_start, 1);
+       if (IS_ERR(em))
+               return -EIO;
+
+       map = em->map_lookup;
+       length = em->len;
+       rmap_len = map->stripe_len;
+
+       if (map->type & BTRFS_BLOCK_GROUP_RAID10)
+               length = div_u64(length, map->num_stripes / map->sub_stripes);
+       else if (map->type & BTRFS_BLOCK_GROUP_RAID0)
+               length = div_u64(length, map->num_stripes);
+       else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) {
+               length = div_u64(length, nr_data_stripes(map));
+               rmap_len = map->stripe_len * nr_data_stripes(map);
+       }
+
+       buf = kcalloc(map->num_stripes, sizeof(u64), GFP_NOFS);
+       BUG_ON(!buf); /* -ENOMEM */
+
+       for (i = 0; i < map->num_stripes; i++) {
+               if (map->stripes[i].physical > physical ||
+                   map->stripes[i].physical + length <= physical)
+                       continue;
+
+               stripe_nr = physical - map->stripes[i].physical;
+               stripe_nr = div64_u64(stripe_nr, map->stripe_len);
+
+               if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
+                       stripe_nr = stripe_nr * map->num_stripes + i;
+                       stripe_nr = div_u64(stripe_nr, map->sub_stripes);
+               } else if (map->type & BTRFS_BLOCK_GROUP_RAID0) {
+                       stripe_nr = stripe_nr * map->num_stripes + i;
+               }
+               /*
+                * The remaining case would be for RAID56, multiply by
+                * nr_data_stripes().  Alternatively, just use rmap_len below
+                * instead of map->stripe_len
+                */
+
+               bytenr = chunk_start + stripe_nr * rmap_len;
+               WARN_ON(nr >= map->num_stripes);
+               for (j = 0; j < nr; j++) {
+                       if (buf[j] == bytenr)
+                               break;
+               }
+               if (j == nr) {
+                       WARN_ON(nr >= map->num_stripes);
+                       buf[nr++] = bytenr;
+               }
+       }
+
+       *logical = buf;
+       *naddrs = nr;
+       *stripe_len = rmap_len;
+
+       free_extent_map(em);
+       return 0;
+}
+
 static int exclude_super_stripes(struct btrfs_block_group *cache)
 {
        struct btrfs_fs_info *fs_info = cache->fs_info;
index 5cf1ea33f284e32679e468e5f92478470d62c688..107bb557ca8de8ea08d2e0d62613105ae0b95b04 100644 (file)
@@ -283,4 +283,9 @@ static inline int btrfs_block_group_done(struct btrfs_block_group *cache)
                cache->cached == BTRFS_CACHE_ERROR;
 }
 
+#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
+int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start,
+                    u64 physical, u64 **logical, int *naddrs, int *stripe_len);
+#endif
+
 #endif /* BTRFS_BLOCK_GROUP_H */
index 9658c53eec7b17c30f2ad41cce83d46327974b25..ab1b3c35c5eb35b83dbccd1ffe47ab7406df41ae 100644 (file)
@@ -6114,75 +6114,6 @@ int btrfs_map_sblock(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
        return __btrfs_map_block(fs_info, op, logical, length, bbio_ret, 0, 1);
 }
 
-int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start,
-                    u64 physical, u64 **logical, int *naddrs, int *stripe_len)
-{
-       struct extent_map *em;
-       struct map_lookup *map;
-       u64 *buf;
-       u64 bytenr;
-       u64 length;
-       u64 stripe_nr;
-       u64 rmap_len;
-       int i, j, nr = 0;
-
-       em = btrfs_get_chunk_map(fs_info, chunk_start, 1);
-       if (IS_ERR(em))
-               return -EIO;
-
-       map = em->map_lookup;
-       length = em->len;
-       rmap_len = map->stripe_len;
-
-       if (map->type & BTRFS_BLOCK_GROUP_RAID10)
-               length = div_u64(length, map->num_stripes / map->sub_stripes);
-       else if (map->type & BTRFS_BLOCK_GROUP_RAID0)
-               length = div_u64(length, map->num_stripes);
-       else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) {
-               length = div_u64(length, nr_data_stripes(map));
-               rmap_len = map->stripe_len * nr_data_stripes(map);
-       }
-
-       buf = kcalloc(map->num_stripes, sizeof(u64), GFP_NOFS);
-       BUG_ON(!buf); /* -ENOMEM */
-
-       for (i = 0; i < map->num_stripes; i++) {
-               if (map->stripes[i].physical > physical ||
-                   map->stripes[i].physical + length <= physical)
-                       continue;
-
-               stripe_nr = physical - map->stripes[i].physical;
-               stripe_nr = div64_u64(stripe_nr, map->stripe_len);
-
-               if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
-                       stripe_nr = stripe_nr * map->num_stripes + i;
-                       stripe_nr = div_u64(stripe_nr, map->sub_stripes);
-               } else if (map->type & BTRFS_BLOCK_GROUP_RAID0) {
-                       stripe_nr = stripe_nr * map->num_stripes + i;
-               } /* else if RAID[56], multiply by nr_data_stripes().
-                  * Alternatively, just use rmap_len below instead of
-                  * map->stripe_len */
-
-               bytenr = chunk_start + stripe_nr * rmap_len;
-               WARN_ON(nr >= map->num_stripes);
-               for (j = 0; j < nr; j++) {
-                       if (buf[j] == bytenr)
-                               break;
-               }
-               if (j == nr) {
-                       WARN_ON(nr >= map->num_stripes);
-                       buf[nr++] = bytenr;
-               }
-       }
-
-       *logical = buf;
-       *naddrs = nr;
-       *stripe_len = rmap_len;
-
-       free_extent_map(em);
-       return 0;
-}
-
 static inline void btrfs_end_bbio(struct btrfs_bio *bbio, struct bio *bio)
 {
        bio->bi_private = bbio->private;
index 81f21e42b887e9c2e7a16a310306de8def6334b0..9c7d4fe5c39a6d1dd83ba0cbe6a614258535e285 100644 (file)
@@ -415,8 +415,6 @@ int btrfs_map_sblock(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
                     struct btrfs_bio **bbio_ret);
 int btrfs_get_io_geometry(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
                u64 logical, u64 len, struct btrfs_io_geometry *io_geom);
-int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start,
-                    u64 physical, u64 **logical, int *naddrs, int *stripe_len);
 int btrfs_read_sys_array(struct btrfs_fs_info *fs_info);
 int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info);
 int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, u64 type);