mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
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
4 changed files with 127 additions and 109 deletions
|
@ -3143,8 +3143,6 @@ struct btrfs_delalloc_work *btrfs_alloc_delalloc_work(struct inode *inode,
|
||||||
int delay_iput);
|
int delay_iput);
|
||||||
void btrfs_wait_and_free_delalloc_work(struct btrfs_delalloc_work *work);
|
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 extent_map *btrfs_get_extent_fiemap(struct btrfs_inode *inode,
|
||||||
struct page *page, size_t pg_offset, u64 start,
|
struct page *page, size_t pg_offset, u64 start,
|
||||||
u64 len, int create);
|
u64 len, int create);
|
||||||
|
|
|
@ -454,3 +454,128 @@ void replace_extent_mapping(struct extent_map_tree *tree,
|
||||||
|
|
||||||
setup_extent_mapping(tree, new, modified);
|
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);
|
void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em);
|
||||||
struct extent_map *search_extent_mapping(struct extent_map_tree *tree,
|
struct extent_map *search_extent_mapping(struct extent_map_tree *tree,
|
||||||
u64 start, u64 len);
|
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
|
#endif
|
||||||
|
|
107
fs/btrfs/inode.c
107
fs/btrfs/inode.c
|
@ -6817,68 +6817,6 @@ out_fail_inode:
|
||||||
goto out_fail;
|
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,
|
static noinline int uncompress_inline(struct btrfs_path *path,
|
||||||
struct page *page,
|
struct page *page,
|
||||||
size_t pg_offset, u64 extent_offset,
|
size_t pg_offset, u64 extent_offset,
|
||||||
|
@ -6925,51 +6863,6 @@ static noinline int uncompress_inline(struct btrfs_path *path,
|
||||||
return ret;
|
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.
|
* 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
|
* the ugly parts come from merging extents from the disk with the in-ram
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue