Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

btrfs: Move and unexport btrfs_rmap_block

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>

authored by

Nikolay Borisov and committed by
David Sterba
96a14336 68c467cb

+91 -71
+86
fs/btrfs/block-group.c
··· 15 15 #include "tree-log.h" 16 16 #include "delalloc-space.h" 17 17 #include "discard.h" 18 + #include "raid56.h" 18 19 19 20 /* 20 21 * Return target flags in extended format or 0 if restripe for this chunk_type ··· 1560 1559 if (flags & BTRFS_BLOCK_GROUP_SYSTEM) 1561 1560 fs_info->avail_system_alloc_bits |= extra_flags; 1562 1561 write_sequnlock(&fs_info->profiles_lock); 1562 + } 1563 + 1564 + /** 1565 + * btrfs_rmap_block - Map a physical disk address to a list of logical addresses 1566 + * @chunk_start: logical address of block group 1567 + * @physical: physical address to map to logical addresses 1568 + * @logical: return array of logical addresses which map to @physical 1569 + * @naddrs: length of @logical 1570 + * @stripe_len: size of IO stripe for the given block group 1571 + * 1572 + * Maps a particular @physical disk address to a list of @logical addresses. 1573 + * Used primarily to exclude those portions of a block group that contain super 1574 + * block copies. 1575 + */ 1576 + EXPORT_FOR_TESTS 1577 + int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start, 1578 + u64 physical, u64 **logical, int *naddrs, int *stripe_len) 1579 + { 1580 + struct extent_map *em; 1581 + struct map_lookup *map; 1582 + u64 *buf; 1583 + u64 bytenr; 1584 + u64 length; 1585 + u64 stripe_nr; 1586 + u64 rmap_len; 1587 + int i, j, nr = 0; 1588 + 1589 + em = btrfs_get_chunk_map(fs_info, chunk_start, 1); 1590 + if (IS_ERR(em)) 1591 + return -EIO; 1592 + 1593 + map = em->map_lookup; 1594 + length = em->len; 1595 + rmap_len = map->stripe_len; 1596 + 1597 + if (map->type & BTRFS_BLOCK_GROUP_RAID10) 1598 + length = div_u64(length, map->num_stripes / map->sub_stripes); 1599 + else if (map->type & BTRFS_BLOCK_GROUP_RAID0) 1600 + length = div_u64(length, map->num_stripes); 1601 + else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) { 1602 + length = div_u64(length, nr_data_stripes(map)); 1603 + rmap_len = map->stripe_len * nr_data_stripes(map); 1604 + } 1605 + 1606 + buf = kcalloc(map->num_stripes, sizeof(u64), GFP_NOFS); 1607 + BUG_ON(!buf); /* -ENOMEM */ 1608 + 1609 + for (i = 0; i < map->num_stripes; i++) { 1610 + if (map->stripes[i].physical > physical || 1611 + map->stripes[i].physical + length <= physical) 1612 + continue; 1613 + 1614 + stripe_nr = physical - map->stripes[i].physical; 1615 + stripe_nr = div64_u64(stripe_nr, map->stripe_len); 1616 + 1617 + if (map->type & BTRFS_BLOCK_GROUP_RAID10) { 1618 + stripe_nr = stripe_nr * map->num_stripes + i; 1619 + stripe_nr = div_u64(stripe_nr, map->sub_stripes); 1620 + } else if (map->type & BTRFS_BLOCK_GROUP_RAID0) { 1621 + stripe_nr = stripe_nr * map->num_stripes + i; 1622 + } 1623 + /* 1624 + * The remaining case would be for RAID56, multiply by 1625 + * nr_data_stripes(). Alternatively, just use rmap_len below 1626 + * instead of map->stripe_len 1627 + */ 1628 + 1629 + bytenr = chunk_start + stripe_nr * rmap_len; 1630 + WARN_ON(nr >= map->num_stripes); 1631 + for (j = 0; j < nr; j++) { 1632 + if (buf[j] == bytenr) 1633 + break; 1634 + } 1635 + if (j == nr) { 1636 + WARN_ON(nr >= map->num_stripes); 1637 + buf[nr++] = bytenr; 1638 + } 1639 + } 1640 + 1641 + *logical = buf; 1642 + *naddrs = nr; 1643 + *stripe_len = rmap_len; 1644 + 1645 + free_extent_map(em); 1646 + return 0; 1563 1647 } 1564 1648 1565 1649 static int exclude_super_stripes(struct btrfs_block_group *cache)
+5
fs/btrfs/block-group.h
··· 283 283 cache->cached == BTRFS_CACHE_ERROR; 284 284 } 285 285 286 + #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS 287 + int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start, 288 + u64 physical, u64 **logical, int *naddrs, int *stripe_len); 289 + #endif 290 + 286 291 #endif /* BTRFS_BLOCK_GROUP_H */
-69
fs/btrfs/volumes.c
··· 6114 6114 return __btrfs_map_block(fs_info, op, logical, length, bbio_ret, 0, 1); 6115 6115 } 6116 6116 6117 - int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start, 6118 - u64 physical, u64 **logical, int *naddrs, int *stripe_len) 6119 - { 6120 - struct extent_map *em; 6121 - struct map_lookup *map; 6122 - u64 *buf; 6123 - u64 bytenr; 6124 - u64 length; 6125 - u64 stripe_nr; 6126 - u64 rmap_len; 6127 - int i, j, nr = 0; 6128 - 6129 - em = btrfs_get_chunk_map(fs_info, chunk_start, 1); 6130 - if (IS_ERR(em)) 6131 - return -EIO; 6132 - 6133 - map = em->map_lookup; 6134 - length = em->len; 6135 - rmap_len = map->stripe_len; 6136 - 6137 - if (map->type & BTRFS_BLOCK_GROUP_RAID10) 6138 - length = div_u64(length, map->num_stripes / map->sub_stripes); 6139 - else if (map->type & BTRFS_BLOCK_GROUP_RAID0) 6140 - length = div_u64(length, map->num_stripes); 6141 - else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) { 6142 - length = div_u64(length, nr_data_stripes(map)); 6143 - rmap_len = map->stripe_len * nr_data_stripes(map); 6144 - } 6145 - 6146 - buf = kcalloc(map->num_stripes, sizeof(u64), GFP_NOFS); 6147 - BUG_ON(!buf); /* -ENOMEM */ 6148 - 6149 - for (i = 0; i < map->num_stripes; i++) { 6150 - if (map->stripes[i].physical > physical || 6151 - map->stripes[i].physical + length <= physical) 6152 - continue; 6153 - 6154 - stripe_nr = physical - map->stripes[i].physical; 6155 - stripe_nr = div64_u64(stripe_nr, map->stripe_len); 6156 - 6157 - if (map->type & BTRFS_BLOCK_GROUP_RAID10) { 6158 - stripe_nr = stripe_nr * map->num_stripes + i; 6159 - stripe_nr = div_u64(stripe_nr, map->sub_stripes); 6160 - } else if (map->type & BTRFS_BLOCK_GROUP_RAID0) { 6161 - stripe_nr = stripe_nr * map->num_stripes + i; 6162 - } /* else if RAID[56], multiply by nr_data_stripes(). 6163 - * Alternatively, just use rmap_len below instead of 6164 - * map->stripe_len */ 6165 - 6166 - bytenr = chunk_start + stripe_nr * rmap_len; 6167 - WARN_ON(nr >= map->num_stripes); 6168 - for (j = 0; j < nr; j++) { 6169 - if (buf[j] == bytenr) 6170 - break; 6171 - } 6172 - if (j == nr) { 6173 - WARN_ON(nr >= map->num_stripes); 6174 - buf[nr++] = bytenr; 6175 - } 6176 - } 6177 - 6178 - *logical = buf; 6179 - *naddrs = nr; 6180 - *stripe_len = rmap_len; 6181 - 6182 - free_extent_map(em); 6183 - return 0; 6184 - } 6185 - 6186 6117 static inline void btrfs_end_bbio(struct btrfs_bio *bbio, struct bio *bio) 6187 6118 { 6188 6119 bio->bi_private = bbio->private;
-2
fs/btrfs/volumes.h
··· 415 415 struct btrfs_bio **bbio_ret); 416 416 int btrfs_get_io_geometry(struct btrfs_fs_info *fs_info, enum btrfs_map_op op, 417 417 u64 logical, u64 len, struct btrfs_io_geometry *io_geom); 418 - int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start, 419 - u64 physical, u64 **logical, int *naddrs, int *stripe_len); 420 418 int btrfs_read_sys_array(struct btrfs_fs_info *fs_info); 421 419 int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info); 422 420 int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, u64 type);