Skip to content

Commit 96a1433

Browse files
lorddoskiaskdave
authored andcommitted
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 <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 68c467c commit 96a1433

File tree

4 files changed

+91
-71
lines changed

4 files changed

+91
-71
lines changed

fs/btrfs/block-group.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "tree-log.h"
1616
#include "delalloc-space.h"
1717
#include "discard.h"
18+
#include "raid56.h"
1819

1920
/*
2021
* 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)
15611562
write_sequnlock(&fs_info->profiles_lock);
15621563
}
15631564

1565+
/**
1566+
* btrfs_rmap_block - Map a physical disk address to a list of logical addresses
1567+
* @chunk_start: logical address of block group
1568+
* @physical: physical address to map to logical addresses
1569+
* @logical: return array of logical addresses which map to @physical
1570+
* @naddrs: length of @logical
1571+
* @stripe_len: size of IO stripe for the given block group
1572+
*
1573+
* Maps a particular @physical disk address to a list of @logical addresses.
1574+
* Used primarily to exclude those portions of a block group that contain super
1575+
* block copies.
1576+
*/
1577+
EXPORT_FOR_TESTS
1578+
int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start,
1579+
u64 physical, u64 **logical, int *naddrs, int *stripe_len)
1580+
{
1581+
struct extent_map *em;
1582+
struct map_lookup *map;
1583+
u64 *buf;
1584+
u64 bytenr;
1585+
u64 length;
1586+
u64 stripe_nr;
1587+
u64 rmap_len;
1588+
int i, j, nr = 0;
1589+
1590+
em = btrfs_get_chunk_map(fs_info, chunk_start, 1);
1591+
if (IS_ERR(em))
1592+
return -EIO;
1593+
1594+
map = em->map_lookup;
1595+
length = em->len;
1596+
rmap_len = map->stripe_len;
1597+
1598+
if (map->type & BTRFS_BLOCK_GROUP_RAID10)
1599+
length = div_u64(length, map->num_stripes / map->sub_stripes);
1600+
else if (map->type & BTRFS_BLOCK_GROUP_RAID0)
1601+
length = div_u64(length, map->num_stripes);
1602+
else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) {
1603+
length = div_u64(length, nr_data_stripes(map));
1604+
rmap_len = map->stripe_len * nr_data_stripes(map);
1605+
}
1606+
1607+
buf = kcalloc(map->num_stripes, sizeof(u64), GFP_NOFS);
1608+
BUG_ON(!buf); /* -ENOMEM */
1609+
1610+
for (i = 0; i < map->num_stripes; i++) {
1611+
if (map->stripes[i].physical > physical ||
1612+
map->stripes[i].physical + length <= physical)
1613+
continue;
1614+
1615+
stripe_nr = physical - map->stripes[i].physical;
1616+
stripe_nr = div64_u64(stripe_nr, map->stripe_len);
1617+
1618+
if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
1619+
stripe_nr = stripe_nr * map->num_stripes + i;
1620+
stripe_nr = div_u64(stripe_nr, map->sub_stripes);
1621+
} else if (map->type & BTRFS_BLOCK_GROUP_RAID0) {
1622+
stripe_nr = stripe_nr * map->num_stripes + i;
1623+
}
1624+
/*
1625+
* The remaining case would be for RAID56, multiply by
1626+
* nr_data_stripes(). Alternatively, just use rmap_len below
1627+
* instead of map->stripe_len
1628+
*/
1629+
1630+
bytenr = chunk_start + stripe_nr * rmap_len;
1631+
WARN_ON(nr >= map->num_stripes);
1632+
for (j = 0; j < nr; j++) {
1633+
if (buf[j] == bytenr)
1634+
break;
1635+
}
1636+
if (j == nr) {
1637+
WARN_ON(nr >= map->num_stripes);
1638+
buf[nr++] = bytenr;
1639+
}
1640+
}
1641+
1642+
*logical = buf;
1643+
*naddrs = nr;
1644+
*stripe_len = rmap_len;
1645+
1646+
free_extent_map(em);
1647+
return 0;
1648+
}
1649+
15641650
static int exclude_super_stripes(struct btrfs_block_group *cache)
15651651
{
15661652
struct btrfs_fs_info *fs_info = cache->fs_info;

fs/btrfs/block-group.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,4 +283,9 @@ static inline int btrfs_block_group_done(struct btrfs_block_group *cache)
283283
cache->cached == BTRFS_CACHE_ERROR;
284284
}
285285

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+
286291
#endif /* BTRFS_BLOCK_GROUP_H */

fs/btrfs/volumes.c

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -6114,75 +6114,6 @@ int btrfs_map_sblock(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
61146114
return __btrfs_map_block(fs_info, op, logical, length, bbio_ret, 0, 1);
61156115
}
61166116

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-
61866117
static inline void btrfs_end_bbio(struct btrfs_bio *bbio, struct bio *bio)
61876118
{
61886119
bio->bi_private = bbio->private;

fs/btrfs/volumes.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,6 @@ int btrfs_map_sblock(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
415415
struct btrfs_bio **bbio_ret);
416416
int btrfs_get_io_geometry(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
417417
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);
420418
int btrfs_read_sys_array(struct btrfs_fs_info *fs_info);
421419
int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info);
422420
int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, u64 type);

0 commit comments

Comments
 (0)