Btrfs: move extent map specific code to extent_map.c
These helpers are extent map specific, move them to extent_map.c. 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>
This commit is contained in:
parent
7b4df058b0
commit
c04e61b5e4
|
@ -3143,8 +3143,6 @@ 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);
|
||||
|
|
|
@ -454,3 +454,128 @@ void replace_extent_mapping(struct extent_map_tree *tree,
|
|||
|
||||
setup_extent_mapping(tree, new, modified);
|
||||
}
|
||||
|
||||
static struct extent_map *next_extent_map(struct extent_map *em)
|
||||
{
|
||||
struct rb_node *next;
|
||||
|
||||
next = rb_next(&em->rb_node);
|
||||
if (!next)
|
||||
return NULL;
|
||||
return container_of(next, struct extent_map, rb_node);
|
||||
}
|
||||
|
||||
static struct extent_map *prev_extent_map(struct extent_map *em)
|
||||
{
|
||||
struct rb_node *prev;
|
||||
|
||||
prev = rb_prev(&em->rb_node);
|
||||
if (!prev)
|
||||
return NULL;
|
||||
return container_of(prev, struct extent_map, rb_node);
|
||||
}
|
||||
|
||||
/* helper for btfs_get_extent. Given an existing extent in the tree,
|
||||
* the existing extent is the nearest extent to map_start,
|
||||
* and an extent that you want to insert, deal with overlap and insert
|
||||
* the best fitted new extent into the tree.
|
||||
*/
|
||||
static int merge_extent_mapping(struct extent_map_tree *em_tree,
|
||||
struct extent_map *existing,
|
||||
struct extent_map *em,
|
||||
u64 map_start)
|
||||
{
|
||||
struct extent_map *prev;
|
||||
struct extent_map *next;
|
||||
u64 start;
|
||||
u64 end;
|
||||
u64 start_diff;
|
||||
|
||||
BUG_ON(map_start < em->start || map_start >= extent_map_end(em));
|
||||
|
||||
if (existing->start > map_start) {
|
||||
next = existing;
|
||||
prev = prev_extent_map(next);
|
||||
} else {
|
||||
prev = existing;
|
||||
next = next_extent_map(prev);
|
||||
}
|
||||
|
||||
start = prev ? extent_map_end(prev) : em->start;
|
||||
start = max_t(u64, start, em->start);
|
||||
end = next ? next->start : extent_map_end(em);
|
||||
end = min_t(u64, end, extent_map_end(em));
|
||||
start_diff = start - em->start;
|
||||
em->start = start;
|
||||
em->len = end - start;
|
||||
if (em->block_start < EXTENT_MAP_LAST_BYTE &&
|
||||
!test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) {
|
||||
em->block_start += start_diff;
|
||||
em->block_len = em->len;
|
||||
}
|
||||
return add_extent_mapping(em_tree, em, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* btrfs_add_extent_mapping - add extent mapping into em_tree
|
||||
* @em_tree - the extent tree into which we want to insert the extent mapping
|
||||
* @em_in - extent we are inserting
|
||||
* @start - start of the logical range btrfs_get_extent() is requesting
|
||||
* @len - length of the logical range btrfs_get_extent() is requesting
|
||||
*
|
||||
* Note that @em_in's range may be different from [start, start+len),
|
||||
* but they must be overlapped.
|
||||
*
|
||||
* Insert @em_in into @em_tree. In case there is an overlapping range, handle
|
||||
* the -EEXIST by either:
|
||||
* a) Returning the existing extent in @em_in if @start is within the
|
||||
* existing em.
|
||||
* b) Merge the existing extent with @em_in passed in.
|
||||
*
|
||||
* Return 0 on success, otherwise -EEXIST.
|
||||
*
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -91,4 +91,6 @@ int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, u64 gen
|
|||
void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em);
|
||||
struct extent_map *search_extent_mapping(struct extent_map_tree *tree,
|
||||
u64 start, u64 len);
|
||||
int btrfs_add_extent_mapping(struct extent_map_tree *em_tree,
|
||||
struct extent_map **em_in, u64 start, u64 len);
|
||||
#endif
|
||||
|
|
107
fs/btrfs/inode.c
107
fs/btrfs/inode.c
|
@ -6817,68 +6817,6 @@ out_fail_inode:
|
|||
goto out_fail;
|
||||
}
|
||||
|
||||
/* Find next extent map of a given extent map, caller needs to ensure locks */
|
||||
static struct extent_map *next_extent_map(struct extent_map *em)
|
||||
{
|
||||
struct rb_node *next;
|
||||
|
||||
next = rb_next(&em->rb_node);
|
||||
if (!next)
|
||||
return NULL;
|
||||
return container_of(next, struct extent_map, rb_node);
|
||||
}
|
||||
|
||||
static struct extent_map *prev_extent_map(struct extent_map *em)
|
||||
{
|
||||
struct rb_node *prev;
|
||||
|
||||
prev = rb_prev(&em->rb_node);
|
||||
if (!prev)
|
||||
return NULL;
|
||||
return container_of(prev, struct extent_map, rb_node);
|
||||
}
|
||||
|
||||
/* helper for btfs_get_extent. Given an existing extent in the tree,
|
||||
* the existing extent is the nearest extent to map_start,
|
||||
* and an extent that you want to insert, deal with overlap and insert
|
||||
* the best fitted new extent into the tree.
|
||||
*/
|
||||
static int merge_extent_mapping(struct extent_map_tree *em_tree,
|
||||
struct extent_map *existing,
|
||||
struct extent_map *em,
|
||||
u64 map_start)
|
||||
{
|
||||
struct extent_map *prev;
|
||||
struct extent_map *next;
|
||||
u64 start;
|
||||
u64 end;
|
||||
u64 start_diff;
|
||||
|
||||
BUG_ON(map_start < em->start || map_start >= extent_map_end(em));
|
||||
|
||||
if (existing->start > map_start) {
|
||||
next = existing;
|
||||
prev = prev_extent_map(next);
|
||||
} else {
|
||||
prev = existing;
|
||||
next = next_extent_map(prev);
|
||||
}
|
||||
|
||||
start = prev ? extent_map_end(prev) : em->start;
|
||||
start = max_t(u64, start, em->start);
|
||||
end = next ? next->start : extent_map_end(em);
|
||||
end = min_t(u64, end, extent_map_end(em));
|
||||
start_diff = start - em->start;
|
||||
em->start = start;
|
||||
em->len = end - start;
|
||||
if (em->block_start < EXTENT_MAP_LAST_BYTE &&
|
||||
!test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) {
|
||||
em->block_start += start_diff;
|
||||
em->block_len = em->len;
|
||||
}
|
||||
return add_extent_mapping(em_tree, em, 0);
|
||||
}
|
||||
|
||||
static noinline int uncompress_inline(struct btrfs_path *path,
|
||||
struct page *page,
|
||||
size_t pg_offset, u64 extent_offset,
|
||||
|
@ -6925,51 +6863,6 @@ 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
|
||||
|
|
Loading…
Reference in New Issue