mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-17 09:43:59 +08:00
btrfs: Implement find_first_clear_extent_bit
This function is very similar to find_first_extent_bit except that it locates the first contiguous span of space which does not have bits set. It's intended use is in the freespace trimming code. Signed-off-by: Nikolay Borisov <nborisov@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
8811133d8a
commit
45bfcfc168
@ -1542,6 +1542,79 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find_first_clear_extent_bit - finds the first range that has @bits not set
|
||||||
|
* and that starts after @start
|
||||||
|
*
|
||||||
|
* @tree - the tree to search
|
||||||
|
* @start - the offset at/after which the found extent should start
|
||||||
|
* @start_ret - records the beginning of the range
|
||||||
|
* @end_ret - records the end of the range (inclusive)
|
||||||
|
* @bits - the set of bits which must be unset
|
||||||
|
*
|
||||||
|
* Since unallocated range is also considered one which doesn't have the bits
|
||||||
|
* set it's possible that @end_ret contains -1, this happens in case the range
|
||||||
|
* spans (last_range_end, end of device]. In this case it's up to the caller to
|
||||||
|
* trim @end_ret to the appropriate size.
|
||||||
|
*/
|
||||||
|
void find_first_clear_extent_bit(struct extent_io_tree *tree, u64 start,
|
||||||
|
u64 *start_ret, u64 *end_ret, unsigned bits)
|
||||||
|
{
|
||||||
|
struct extent_state *state;
|
||||||
|
struct rb_node *node, *prev = NULL, *next;
|
||||||
|
|
||||||
|
spin_lock(&tree->lock);
|
||||||
|
|
||||||
|
/* Find first extent with bits cleared */
|
||||||
|
while (1) {
|
||||||
|
node = __etree_search(tree, start, &next, &prev, NULL, NULL);
|
||||||
|
if (!node) {
|
||||||
|
node = next;
|
||||||
|
if (!node) {
|
||||||
|
/*
|
||||||
|
* We are past the last allocated chunk,
|
||||||
|
* set start at the end of the last extent. The
|
||||||
|
* device alloc tree should never be empty so
|
||||||
|
* prev is always set.
|
||||||
|
*/
|
||||||
|
ASSERT(prev);
|
||||||
|
state = rb_entry(prev, struct extent_state, rb_node);
|
||||||
|
*start_ret = state->end + 1;
|
||||||
|
*end_ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state = rb_entry(node, struct extent_state, rb_node);
|
||||||
|
if (in_range(start, state->start, state->end - state->start + 1) &&
|
||||||
|
(state->state & bits)) {
|
||||||
|
start = state->end + 1;
|
||||||
|
} else {
|
||||||
|
*start_ret = start;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the longest stretch from start until an entry which has the
|
||||||
|
* bits set
|
||||||
|
*/
|
||||||
|
while (1) {
|
||||||
|
state = rb_entry(node, struct extent_state, rb_node);
|
||||||
|
if (state->end >= start && !(state->state & bits)) {
|
||||||
|
*end_ret = state->end;
|
||||||
|
} else {
|
||||||
|
*end_ret = state->start - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = rb_next(node);
|
||||||
|
if (!node)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
spin_unlock(&tree->lock);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* find a contiguous range of bytes in the file marked as delalloc, not
|
* find a contiguous range of bytes in the file marked as delalloc, not
|
||||||
* more than 'max_bytes'. start and end are used to return the range,
|
* more than 'max_bytes'. start and end are used to return the range,
|
||||||
|
@ -403,6 +403,8 @@ static inline int set_extent_uptodate(struct extent_io_tree *tree, u64 start,
|
|||||||
int find_first_extent_bit(struct extent_io_tree *tree, u64 start,
|
int find_first_extent_bit(struct extent_io_tree *tree, u64 start,
|
||||||
u64 *start_ret, u64 *end_ret, unsigned bits,
|
u64 *start_ret, u64 *end_ret, unsigned bits,
|
||||||
struct extent_state **cached_state);
|
struct extent_state **cached_state);
|
||||||
|
void find_first_clear_extent_bit(struct extent_io_tree *tree, u64 start,
|
||||||
|
u64 *start_ret, u64 *end_ret, unsigned bits);
|
||||||
int extent_invalidatepage(struct extent_io_tree *tree,
|
int extent_invalidatepage(struct extent_io_tree *tree,
|
||||||
struct page *page, unsigned long offset);
|
struct page *page, unsigned long offset);
|
||||||
int extent_write_full_page(struct page *page, struct writeback_control *wbc);
|
int extent_write_full_page(struct page *page, struct writeback_control *wbc);
|
||||||
|
Loading…
Reference in New Issue
Block a user