while (!list_empty(&states)) {
state = list_first_entry(&states, struct extent_state, leak_list);
btrfs_err(NULL, "state leak: start %llu end %llu state %u in tree %d refs %d",
state->start, state->end, state->state,
extent_state_in_tree(state),
refcount_read(&state->refs));
list_del(&state->leak_list);
WARN_ON_ONCE(1);
kmem_cache_free(extent_state_cache, state);
}
}
/* * Empty an io tree, removing and freeing every extent state record from the * tree. This should be called once we are sure no other task can access the * tree anymore, so no tree updates happen after we empty the tree and there * aren't any waiters on any extent state record (EXTENT_LOCK_BITS are never * set on any extent state when calling this function).
*/ void btrfs_extent_io_tree_release(struct extent_io_tree *tree)
{ struct rb_root root; struct extent_state *state; struct extent_state *tmp;
spin_lock(&tree->lock);
root = tree->state;
tree->state = RB_ROOT;
rbtree_postorder_for_each_entry_safe(state, tmp, &root, rb_node) { /* Clear node to keep free_extent_state() happy. */
RB_CLEAR_NODE(&state->rb_node);
ASSERT(!(state->state & EXTENT_LOCK_BITS)); /* * No need for a memory barrier here, as we are holding the tree * lock and we only change the waitqueue while holding that lock * (see wait_extent_bit()).
*/
ASSERT(!waitqueue_active(&state->wq));
btrfs_free_extent_state(state);
cond_resched_lock(&tree->lock);
} /* * Should still be empty even after a reschedule, no other task should * be accessing the tree anymore.
*/
ASSERT(RB_EMPTY_ROOT(&tree->state));
spin_unlock(&tree->lock);
}
/* * The given mask might be not appropriate for the slab allocator, * drop the unsupported bits
*/
mask &= ~(__GFP_DMA32|__GFP_HIGHMEM);
state = kmem_cache_alloc(extent_state_cache, mask); if (!state) return state;
state->state = 0;
RB_CLEAR_NODE(&state->rb_node);
btrfs_leak_debug_add_state(state);
refcount_set(&state->refs, 1);
init_waitqueue_head(&state->wq);
trace_btrfs_alloc_extent_state(state, mask, _RET_IP_); return state;
}
/* * Search @tree for an entry that contains @offset or if none exists for the * first entry that starts and ends after that offset. * * @tree: the tree to search * @offset: search offset * @node_ret: pointer where new node should be anchored (used when inserting an * entry in the tree) * @parent_ret: points to entry which would have been the parent of the entry, * containing @offset * * Return a pointer to the entry that contains @offset byte address. * * If no such entry exists, return the first entry that starts and ends after * @offset if one exists, otherwise NULL. * * If the returned entry starts at @offset, then @node_ret and @parent_ret * aren't changed.
*/ staticinlinestruct extent_state *tree_search_for_insert(struct extent_io_tree *tree,
u64 offset, struct rb_node ***node_ret, struct rb_node **parent_ret)
{ struct rb_root *root = &tree->state; struct rb_node **node = &root->rb_node; struct rb_node *prev = NULL; struct extent_state *entry = NULL;
if (node_ret)
*node_ret = node; if (parent_ret)
*parent_ret = prev;
/* * Return either the current entry if it contains offset (it ends after * or at offset) or the first entry that starts and ends after offset if * one exists, or NULL.
*/ while (entry && offset > entry->end)
entry = next_state(entry);
return entry;
}
/* * Search offset in the tree or fill neighbor rbtree node pointers. * * @tree: the tree to search * @offset: offset that should fall within an entry in @tree * @next_ret: pointer to the first entry whose range ends after @offset * @prev_ret: pointer to the first entry whose range begins before @offset * * Return a pointer to the entry that contains @offset byte address. If no * such entry exists, then return NULL and fill @prev_ret and @next_ret. * Otherwise return the found entry and other pointers are left untouched.
*/ staticstruct extent_state *tree_search_prev_next(struct extent_io_tree *tree,
u64 offset, struct extent_state **prev_ret, struct extent_state **next_ret)
{ struct rb_root *root = &tree->state; struct rb_node **node = &root->rb_node; struct extent_state *orig_prev; struct extent_state *entry = NULL;
ASSERT(prev_ret);
ASSERT(next_ret);
while (*node) {
entry = rb_entry(*node, struct extent_state, rb_node);
/* * Inexact rb-tree search, return the next entry if @offset is not found
*/ staticinlinestruct extent_state *tree_search(struct extent_io_tree *tree, u64 offset)
{ return tree_search_for_insert(tree, offset, NULL, NULL);
}
staticvoid __cold extent_io_tree_panic(conststruct extent_io_tree *tree, conststruct extent_state *state, constchar *opname, int err)
{
btrfs_panic(btrfs_extent_io_tree_to_fs_info(tree), err, "extent io tree error on %s state start %llu end %llu",
opname, state->start, state->end);
}
/* * Utility function to look for merge candidates inside a given range. Any * extents with matching state are merged together into a single extent in the * tree. Extents with EXTENT_IO in their state field are not merged because * the end_io handlers need to be able to do operations on them without * sleeping (or doing allocations/splits). * * This should be called with the tree lock held.
*/ staticvoid merge_state(struct extent_io_tree *tree, struct extent_state *state)
{ if (state->state & (EXTENT_LOCK_BITS | EXTENT_BOUNDARY)) return;
/* * Insert an extent_state struct into the tree. 'bits' are set on the * struct before it is inserted. * * Returns a pointer to the struct extent_state record containing the range * requested for insertion, which may be the same as the given struct or it * may be an existing record in the tree that was expanded to accommodate the * requested range. In case of an extent_state different from the one that was * given, the later can be freed or reused by the caller. * * On error it returns an error pointer. * * The tree lock is not taken internally. This is a utility function and * probably isn't what you want to call (see set/clear_extent_bit).
*/ staticstruct extent_state *insert_state(struct extent_io_tree *tree, struct extent_state *state,
u32 bits, struct extent_changeset *changeset)
{ struct rb_node **node; struct rb_node *parent = NULL; const u64 start = state->start - 1; const u64 end = state->end + 1; constbool try_merge = !(bits & (EXTENT_LOCK_BITS | EXTENT_BOUNDARY));
set_state_bits(tree, state, bits, changeset);
node = &tree->state.rb_node; while (*node) { struct extent_state *entry;
/* * Insert state to @tree to the location given by @node and @parent.
*/ staticvoid insert_state_fast(struct extent_io_tree *tree, struct extent_state *state, struct rb_node **node, struct rb_node *parent, unsigned bits, struct extent_changeset *changeset)
{
set_state_bits(tree, state, bits, changeset);
rb_link_node(&state->rb_node, parent, node);
rb_insert_color(&state->rb_node, &tree->state);
merge_state(tree, state);
}
/* * Split a given extent state struct in two, inserting the preallocated * struct 'prealloc' as the newly created second half. 'split' indicates an * offset inside 'orig' where it should be split. * * Before calling, * the tree has 'orig' at [orig->start, orig->end]. After calling, there * are two extent state structs in the tree: * prealloc: [orig->start, split - 1] * orig: [ split, orig->end ] * * The tree locks are not taken by this function. They need to be held * by the caller.
*/ staticint split_state(struct extent_io_tree *tree, struct extent_state *orig, struct extent_state *prealloc, u64 split)
{ struct rb_node *parent = NULL; struct rb_node **node;
if (tree->owner == IO_TREE_INODE_IO)
btrfs_split_delalloc_extent(tree->inode, orig, split);
/* * Use this during tree iteration to avoid doing next node searches when it's * not needed (the current record ends at or after the target range's end).
*/ staticinlinestruct extent_state *next_search_state(struct extent_state *state, u64 end)
{ if (state->end < end) return next_state(state);
return NULL;
}
/* * Utility function to clear some bits in an extent state struct. It will * optionally wake up anyone waiting on this state (wake == 1). * * If no bits are set on the state struct after clearing things, the * struct is freed and removed from the tree
*/ staticstruct extent_state *clear_state_bit(struct extent_io_tree *tree, struct extent_state *state,
u32 bits, int wake, u64 end, struct extent_changeset *changeset)
{ struct extent_state *next;
u32 bits_to_clear = bits & ~EXTENT_CTLBITS; int ret;
if (tree->owner == IO_TREE_INODE_IO)
btrfs_clear_delalloc_extent(tree->inode, state, bits);
ret = add_extent_changeset(state, bits_to_clear, changeset, 0);
BUG_ON(ret < 0);
state->state &= ~bits_to_clear; if (wake)
wake_up(&state->wq); if (state->state == 0) {
next = next_search_state(state, end); if (extent_state_in_tree(state)) {
rb_erase(&state->rb_node, &tree->state);
RB_CLEAR_NODE(&state->rb_node);
btrfs_free_extent_state(state);
} else {
WARN_ON(1);
}
} else {
merge_state(tree, state);
next = next_search_state(state, end);
} return next;
}
/* * Detect if extent bits request NOWAIT semantics and set the gfp mask accordingly, * unset the EXTENT_NOWAIT bit.
*/ staticvoid set_gfp_mask_from_bits(u32 *bits, gfp_t *mask)
{
*mask = (*bits & EXTENT_NOWAIT ? GFP_NOWAIT : GFP_NOFS);
*bits &= EXTENT_NOWAIT - 1;
}
/* * Clear some bits on a range in the tree. This may require splitting or * inserting elements in the tree, so the gfp mask is used to indicate which * allocations or sleeping are allowed. * * The range [start, end] is inclusive. * * This takes the tree lock, and returns 0 on success and < 0 on error.
*/ int btrfs_clear_extent_bit_changeset(struct extent_io_tree *tree, u64 start, u64 end,
u32 bits, struct extent_state **cached_state, struct extent_changeset *changeset)
{ struct extent_state *state; struct extent_state *cached; struct extent_state *prealloc = NULL;
u64 last_end; int ret = 0; bool clear; bool wake; constbooldelete = (bits & EXTENT_CLEAR_ALL_BITS);
gfp_t mask;
if (bits & EXTENT_DELALLOC)
bits |= EXTENT_NORESERVE;
wake = (bits & EXTENT_LOCK_BITS);
clear = (bits & (EXTENT_LOCK_BITS | EXTENT_BOUNDARY));
again: if (!prealloc) { /* * Don't care for allocation failure here because we might end * up not needing the pre-allocated extent state at all, which * is the case if we only have in the tree extent states that * cover our input range and don't cover too any other range. * If we end up needing a new extent state we allocate it later.
*/
prealloc = alloc_extent_state(mask);
}
spin_lock(&tree->lock); if (cached_state) {
cached = *cached_state;
if (clear) {
*cached_state = NULL;
cached_state = NULL;
}
if (cached && extent_state_in_tree(cached) &&
cached->start <= start && cached->end > start) { if (clear)
refcount_dec(&cached->refs);
state = cached; goto hit_next;
} if (clear)
btrfs_free_extent_state(cached);
}
/* This search will find the extents that end after our range starts. */
state = tree_search(tree, start); if (!state) goto out;
hit_next: if (state->start > end) goto out;
WARN_ON(state->end < start);
last_end = state->end;
/* The state doesn't have the wanted bits, go ahead. */ if (!(state->state & bits)) {
state = next_search_state(state, end); goto next;
}
/* * | ---- desired range ---- | * | state | or * | ------------- state -------------- | * * We need to split the extent we found, and may flip bits on second * half. * * If the extent we found extends past our range, we just split and * search again. It'll get split again the next time though. * * If the extent we found is inside our range, we clear the desired bit * on it.
*/
if (state->start < start) {
prealloc = alloc_extent_state_atomic(prealloc); if (!prealloc) goto search_again;
ret = split_state(tree, state, prealloc, start);
prealloc = NULL; if (ret) {
extent_io_tree_panic(tree, state, "split", ret); goto out;
} if (state->end <= end) {
state = clear_state_bit(tree, state, bits, wake, end,
changeset); goto next;
} if (need_resched()) goto search_again; /* * Fallthrough and try atomic extent state allocation if needed. * If it fails we'll jump to 'search_again' retry the allocation * in non-atomic mode and start the search again.
*/
} /* * | ---- desired range ---- | * | state | * We need to split the extent, and clear the bit on the first half.
*/ if (state->start <= end && state->end > end) {
prealloc = alloc_extent_state_atomic(prealloc); if (!prealloc) goto search_again;
ret = split_state(tree, state, prealloc, end + 1); if (ret) {
extent_io_tree_panic(tree, state, "split", ret);
prealloc = NULL; goto out;
}
/* * Wait for one or more bits to clear on a range in the state tree. * The range [start, end] is inclusive. * The tree lock is taken by this function
*/ staticvoid wait_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
u32 bits, struct extent_state **cached_state)
{ struct extent_state *state;
spin_lock(&tree->lock);
again: /* * Maintain cached_state, as we may not remove it from the tree if there * are more bits than the bits we're waiting on set on this state.
*/ if (cached_state && *cached_state) {
state = *cached_state; if (extent_state_in_tree(state) &&
state->start <= start && start < state->end) goto process_node;
} while (1) { /* * This search will find all the extents that end after our * range starts.
*/
state = tree_search(tree, start);
process_node: if (!state) break; if (state->start > end) goto out;
if (!cond_resched_lock(&tree->lock)) {
state = next_state(state); goto process_node;
}
}
out: /* This state is no longer useful, clear it and free it up. */ if (cached_state && *cached_state) {
state = *cached_state;
*cached_state = NULL;
btrfs_free_extent_state(state);
}
spin_unlock(&tree->lock);
}
/* * Find the first state struct with 'bits' set after 'start', and return it. * tree->lock must be held. NULL will returned if nothing was found after * 'start'.
*/ staticstruct extent_state *find_first_extent_bit_state(struct extent_io_tree *tree,
u64 start, u32 bits)
{ struct extent_state *state;
/* * This search will find all the extents that end after our range * starts.
*/
state = tree_search(tree, start); while (state) { if (state->state & bits) return state;
state = next_state(state);
} return NULL;
}
/* * Find the first offset in the io tree with one or more @bits set. * * Note: If there are multiple bits set in @bits, any of them will match. * * Return true if we find something, and update @start_ret and @end_ret. * Return false if we found nothing.
*/ bool btrfs_find_first_extent_bit(struct extent_io_tree *tree, u64 start,
u64 *start_ret, u64 *end_ret, u32 bits, struct extent_state **cached_state)
{ struct extent_state *state; bool ret = false;
spin_lock(&tree->lock); if (cached_state && *cached_state) {
state = *cached_state; if (state->end == start - 1 && extent_state_in_tree(state)) { while ((state = next_state(state)) != NULL) { if (state->state & bits) break;
} /* * If we found the next extent state, clear cached_state * so that we can cache the next extent state below and * avoid future calls going over the same extent state * again. If we haven't found any, clear as well since * it's now useless.
*/
btrfs_free_extent_state(*cached_state);
*cached_state = NULL; if (state) goto got_it; goto out;
}
btrfs_free_extent_state(*cached_state);
*cached_state = NULL;
}
state = find_first_extent_bit_state(tree, start, bits);
got_it: if (state) {
cache_state_if_flags(state, cached_state, 0);
*start_ret = state->start;
*end_ret = state->end;
ret = true;
}
out:
spin_unlock(&tree->lock); return ret;
}
/* * Find a contiguous area of bits * * @tree: io tree to check * @start: offset to start the search from * @start_ret: the first offset we found with the bits set * @end_ret: the final contiguous range of the bits that were set * @bits: bits to look for * * set_extent_bit and clear_extent_bit can temporarily split contiguous ranges * to set bits appropriately, and then merge them again. During this time it * will drop the tree->lock, so use this helper if you want to find the actual * contiguous area for given bits. We will search to the first bit we find, and * then walk down the tree until we find a non-contiguous area. The area * returned will be the full contiguous area with the bits set. * * Returns true if we found a range with the given bits set, in which case * @start_ret and @end_ret are updated, or false if no range was found.
*/ bool btrfs_find_contiguous_extent_bit(struct extent_io_tree *tree, u64 start,
u64 *start_ret, u64 *end_ret, u32 bits)
{ struct extent_state *state; bool ret = false;
spin_lock(&tree->lock);
state = find_first_extent_bit_state(tree, start, bits); if (state) {
*start_ret = state->start;
*end_ret = state->end; while ((state = next_state(state)) != NULL) { if (state->start > (*end_ret + 1)) break;
*end_ret = state->end;
}
ret = true;
}
spin_unlock(&tree->lock); return ret;
}
/* * 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, * * True is returned if we find something, false if nothing was in the tree.
*/ bool btrfs_find_delalloc_range(struct extent_io_tree *tree, u64 *start,
u64 *end, u64 max_bytes, struct extent_state **cached_state)
{ struct extent_state *state;
u64 cur_start = *start; bool found = false;
u64 total_bytes = 0;
spin_lock(&tree->lock);
/* * This search will find all the extents that end after our range * starts.
*/
state = tree_search(tree, cur_start); if (!state) {
*end = (u64)-1; goto out;
}
while (state) { if (found && (state->start != cur_start ||
(state->state & EXTENT_BOUNDARY))) { goto out;
} if (!(state->state & EXTENT_DELALLOC)) { if (!found)
*end = state->end; goto out;
} if (!found) {
*start = state->start;
*cached_state = state;
refcount_inc(&state->refs);
}
found = true;
*end = state->end;
cur_start = state->end + 1;
total_bytes += state->end - state->start + 1; if (total_bytes >= max_bytes) break;
state = next_state(state);
}
out:
spin_unlock(&tree->lock); return found;
}
/* * Set some bits on a range in the tree. This may require allocations or * sleeping. By default all allocations use GFP_NOFS, use EXTENT_NOWAIT for * GFP_NOWAIT. * * If any of the exclusive bits are set, this will fail with -EEXIST if some * part of the range already has the desired bits set. The extent_state of the * existing range is returned in failed_state in this case, and the start of the * existing range is returned in failed_start. failed_state is used as an * optimization for wait_extent_bit, failed_start must be used as the source of * truth as failed_state may have changed since we returned. * * [start, end] is inclusive This takes the tree lock.
*/ staticint set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
u32 bits, u64 *failed_start, struct extent_state **failed_state, struct extent_state **cached_state, struct extent_changeset *changeset)
{ struct extent_state *state; struct extent_state *prealloc = NULL; struct rb_node **p = NULL; struct rb_node *parent = NULL; int ret = 0;
u64 last_start;
u64 last_end;
u32 exclusive_bits = (bits & EXTENT_LOCK_BITS);
gfp_t mask;
if (exclusive_bits)
ASSERT(failed_start); else
ASSERT(failed_start == NULL && failed_state == NULL);
again: if (!prealloc) { /* * Don't care for allocation failure here because we might end * up not needing the pre-allocated extent state at all, which * is the case if we only have in the tree extent states that * cover our input range and don't cover too any other range. * If we end up needing a new extent state we allocate it later.
*/
prealloc = alloc_extent_state(mask);
} /* Optimistically preallocate the extent changeset ulist node. */ if (changeset)
extent_changeset_prealloc(changeset, mask);
spin_lock(&tree->lock); if (cached_state && *cached_state) {
state = *cached_state; if (state->start <= start && state->end > start &&
extent_state_in_tree(state)) goto hit_next;
} /* * This search will find all the extents that end after our range * starts.
*/
state = tree_search_for_insert(tree, start, &p, &parent); if (!state) {
prealloc = alloc_extent_state_atomic(prealloc); if (!prealloc) goto search_again;
prealloc->start = start;
prealloc->end = end;
insert_state_fast(tree, prealloc, p, parent, bits, changeset);
cache_state(prealloc, cached_state);
prealloc = NULL; goto out;
}
hit_next:
last_start = state->start;
last_end = state->end;
/* * | ---- desired range ---- | * | state | * * Just lock what we found and keep going
*/ if (state->start == start && state->end <= end) { if (state->state & exclusive_bits) {
*failed_start = state->start;
cache_state(state, failed_state);
ret = -EEXIST; goto out;
}
/* * | ---- desired range ---- | * | state | * or * | ------------- state -------------- | * * We need to split the extent we found, and may flip bits on second * half. * * If the extent we found extends past our range, we just split and * search again. It'll get split again the next time though. * * If the extent we found is inside our range, we set the desired bit * on it.
*/ if (state->start < start) { if (state->state & exclusive_bits) {
*failed_start = start;
cache_state(state, failed_state);
ret = -EEXIST; goto out;
}
/* * If this extent already has all the bits we want set, then * skip it, not necessary to split it or do anything with it.
*/ if ((state->state & bits) == bits) {
start = state->end + 1;
cache_state(state, cached_state); goto search_again;
}
prealloc = alloc_extent_state_atomic(prealloc); if (!prealloc) goto search_again;
ret = split_state(tree, state, prealloc, start); if (ret)
extent_io_tree_panic(tree, state, "split", ret);
prealloc = NULL; if (ret) goto out; if (state->end <= end) {
set_state_bits(tree, state, bits, changeset);
cache_state(state, cached_state);
merge_state(tree, state); if (last_end >= end) goto out;
start = last_end + 1;
state = next_state(state); if (state && state->start == start && !need_resched()) goto hit_next;
} goto search_again;
} /* * | ---- desired range ---- | * | state | or | state | * * There's a hole, we need to insert something in it and ignore the * extent we found.
*/ if (state->start > start) { struct extent_state *inserted_state;
prealloc = alloc_extent_state_atomic(prealloc); if (!prealloc) goto search_again;
/* * Avoid to free 'prealloc' if it can be merged with the later * extent.
*/
prealloc->start = start; if (end < last_start)
prealloc->end = end; else
prealloc->end = last_start - 1;
inserted_state = insert_state(tree, prealloc, bits, changeset); if (IS_ERR(inserted_state)) {
ret = PTR_ERR(inserted_state);
extent_io_tree_panic(tree, prealloc, "insert", ret); goto out;
}
state = next_search_state(inserted_state, end); /* * If there's a next state, whether contiguous or not, we don't * need to unlock and start search agian. If it's not contiguous * we will end up here and try to allocate a prealloc state and insert.
*/ if (state) goto hit_next; goto search_again;
} /* * | ---- desired range ---- | * | state | * * We need to split the extent, and set the bit on the first half
*/ if (state->start <= end && state->end > end) { if (state->state & exclusive_bits) {
*failed_start = start;
cache_state(state, failed_state);
ret = -EEXIST; goto out;
}
prealloc = alloc_extent_state_atomic(prealloc); if (!prealloc) goto search_again;
ret = split_state(tree, state, prealloc, end + 1); if (ret) {
extent_io_tree_panic(tree, state, "split", ret);
prealloc = NULL; goto out;
}
/* * Convert all bits in a given range from one bit to another * * @tree: the io tree to search * @start: the start offset in bytes * @end: the end offset in bytes (inclusive) * @bits: the bits to set in this range * @clear_bits: the bits to clear in this range * @cached_state: state that we're going to cache * * This will go through and set bits for the given range. If any states exist * already in this range they are set with the given bit and cleared of the * clear_bits. This is only meant to be used by things that are mergeable, ie. * converting from say DELALLOC to DIRTY. This is not meant to be used with * boundary bits like LOCK. * * All allocations are done with GFP_NOFS.
*/ int btrfs_convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
u32 bits, u32 clear_bits, struct extent_state **cached_state)
{ struct extent_state *state; struct extent_state *prealloc = NULL; struct rb_node **p = NULL; struct rb_node *parent = NULL; int ret = 0;
u64 last_start;
u64 last_end; bool first_iteration = true;
again: if (!prealloc) { /* * Best effort, don't worry if extent state allocation fails * here for the first iteration. We might have a cached state * that matches exactly the target range, in which case no * extent state allocations are needed. We'll only know this * after locking the tree.
*/
prealloc = alloc_extent_state(GFP_NOFS); if (!prealloc && !first_iteration) return -ENOMEM;
}
spin_lock(&tree->lock); if (cached_state && *cached_state) {
state = *cached_state; if (state->start <= start && state->end > start &&
extent_state_in_tree(state)) goto hit_next;
}
/* * This search will find all the extents that end after our range * starts.
*/
state = tree_search_for_insert(tree, start, &p, &parent); if (!state) {
prealloc = alloc_extent_state_atomic(prealloc); if (!prealloc) {
ret = -ENOMEM; goto out;
}
prealloc->start = start;
prealloc->end = end;
insert_state_fast(tree, prealloc, p, parent, bits, NULL);
cache_state(prealloc, cached_state);
prealloc = NULL; goto out;
}
hit_next:
last_start = state->start;
last_end = state->end;
/* * | ---- desired range ---- | * | state | * * Just lock what we found and keep going.
*/ if (state->start == start && state->end <= end) {
set_state_bits(tree, state, bits, NULL);
cache_state(state, cached_state);
state = clear_state_bit(tree, state, clear_bits, 0, end, NULL); if (last_end >= end) goto out;
start = last_end + 1; if (state && state->start == start && !need_resched()) goto hit_next; goto search_again;
}
/* * | ---- desired range ---- | * | state | * or * | ------------- state -------------- | * * We need to split the extent we found, and may flip bits on second * half. * * If the extent we found extends past our range, we just split and * search again. It'll get split again the next time though. * * If the extent we found is inside our range, we set the desired bit * on it.
*/ if (state->start < start) {
prealloc = alloc_extent_state_atomic(prealloc); if (!prealloc) {
ret = -ENOMEM; goto out;
}
ret = split_state(tree, state, prealloc, start);
prealloc = NULL; if (ret) {
extent_io_tree_panic(tree, state, "split", ret); goto out;
} if (state->end <= end) {
set_state_bits(tree, state, bits, NULL);
cache_state(state, cached_state);
state = clear_state_bit(tree, state, clear_bits, 0, end, NULL); if (last_end >= end) goto out;
start = last_end + 1; if (state && state->start == start && !need_resched()) goto hit_next;
} goto search_again;
} /* * | ---- desired range ---- | * | state | or | state | * * There's a hole, we need to insert something in it and ignore the * extent we found.
*/ if (state->start > start) { struct extent_state *inserted_state;
prealloc = alloc_extent_state_atomic(prealloc); if (!prealloc) {
ret = -ENOMEM; goto out;
}
/* * Avoid to free 'prealloc' if it can be merged with the later * extent.
*/
prealloc->start = start; if (end < last_start)
prealloc->end = end; else
prealloc->end = last_start - 1;
state = next_search_state(inserted_state, end); /* * If there's a next state, whether contiguous or not, we don't * need to unlock and start search again. If it's not contiguous * we will end up here and try to allocate a prealloc state and insert.
*/ if (state) goto hit_next; goto search_again;
} /* * | ---- desired range ---- | * | state | * * We need to split the extent, and set the bit on the first half.
*/ if (state->start <= end && state->end > end) {
prealloc = alloc_extent_state_atomic(prealloc); if (!prealloc) {
ret = -ENOMEM; goto out;
}
ret = split_state(tree, state, prealloc, end + 1); if (ret) {
extent_io_tree_panic(tree, state, "split", ret);
prealloc = NULL; goto out;
}
/* * Find the first range that has @bits not set. This range could start before * @start. * * @tree: the tree to search * @start: 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 btrfs_find_first_clear_extent_bit(struct extent_io_tree *tree, u64 start,
u64 *start_ret, u64 *end_ret, u32 bits)
{ struct extent_state *state; struct extent_state *prev = NULL, *next = NULL;
spin_lock(&tree->lock);
/* Find first extent with bits cleared */ while (1) {
state = tree_search_prev_next(tree, start, &prev, &next); if (!state && !next && !prev) { /* * Tree is completely empty, send full range and let * caller deal with it
*/
*start_ret = 0;
*end_ret = -1; goto out;
} elseif (!state && !next) { /* * We are past the last allocated chunk, set start at * the end of the last extent.
*/
*start_ret = prev->end + 1;
*end_ret = -1; goto out;
} elseif (!state) {
state = next;
}
/* * At this point 'state' either contains 'start' or start is * before 'state'
*/ if (in_range(start, state->start, state->end - state->start + 1)) { if (state->state & bits) { /* * |--range with bits sets--| * | * start
*/
start = state->end + 1;
} else { /* * 'start' falls within a range that doesn't * have the bits set, so take its start as the * beginning of the desired range * * |--range with bits cleared----| * | * start
*/
*start_ret = state->start; break;
}
} else { /* * |---prev range---|---hole/unset---|---node range---| * | * start * * or * * |---hole/unset--||--first node--| * 0 | * start
*/ if (prev)
*start_ret = prev->end + 1; else
*start_ret = 0; break;
}
}
/* * Find the longest stretch from start until an entry which has the * bits set
*/ while (state) { if (state->end >= start && !(state->state & bits)) {
*end_ret = state->end;
} else {
*end_ret = state->start - 1; break;
}
state = next_state(state);
}
out:
spin_unlock(&tree->lock);
}
/* * Count the number of bytes in the tree that have a given bit(s) set for a * given range. * * @tree: The io tree to search. * @start: The start offset of the range. This value is updated to the * offset of the first byte found with the given bit(s), so it * can end up being bigger than the initial value. * @search_end: The end offset (inclusive value) of the search range. * @max_bytes: The maximum byte count we are interested. The search stops * once it reaches this count. * @bits: The bits the range must have in order to be accounted for. * If multiple bits are set, then only subranges that have all * the bits set are accounted for. * @contig: Indicate if we should ignore holes in the range or not. If * this is true, then stop once we find a hole. * @cached_state: A cached state to be used across multiple calls to this * function in order to speedup searches. Use NULL if this is * called only once or if each call does not start where the * previous one ended. * * Returns the total number of bytes found within the given range that have * all given bits set. If the returned number of bytes is greater than zero * then @start is updated with the offset of the first byte with the bits set.
*/
u64 btrfs_count_range_bits(struct extent_io_tree *tree,
u64 *start, u64 search_end, u64 max_bytes,
u32 bits, int contig, struct extent_state **cached_state)
{ struct extent_state *state = NULL; struct extent_state *cached;
u64 cur_start = *start;
u64 total_bytes = 0;
u64 last = 0; int found = 0;
/* * The cached state starts after our search range's start. Check * if the previous state record starts at or before the range we * are looking for, and if so, use it - this is a common case * when there are holes between records in the tree. If there is * no previous state record, we can start from our cached state.
*/
prev = prev_state(cached); if (!prev)
state = cached; elseif (prev->start <= cur_start && cur_start <= prev->end)
state = prev;
}
/* * This search will find all the extents that end after our range * starts.
*/
search: if (!state)
state = tree_search(tree, cur_start);
while (state) { if (state->start > search_end) break; if (contig && found && state->start > last + 1) break; if (state->end >= cur_start && (state->state & bits) == bits) {
total_bytes += min(search_end, state->end) + 1 -
max(cur_start, state->start); if (total_bytes >= max_bytes) break; if (!found) {
*start = max(cur_start, state->start);
found = 1;
}
last = state->end;
} elseif (contig && found) { break;
}
state = next_state(state);
}
if (cached_state) {
btrfs_free_extent_state(*cached_state);
*cached_state = state; if (state)
refcount_inc(&state->refs);
}
spin_unlock(&tree->lock);
return total_bytes;
}
/* * Check if the single @bit exists in the given range.
*/ bool btrfs_test_range_bit_exists(struct extent_io_tree *tree, u64 start, u64 end, u32 bit)
{ struct extent_state *state; bool bitset = false;
ASSERT(is_power_of_2(bit));
spin_lock(&tree->lock);
state = tree_search(tree, start); while (state) { if (state->start > end) break;
if (state->state & bit) {
bitset = true; break;
}
if (state->end >= end) break;
state = next_state(state);
}
spin_unlock(&tree->lock); return bitset;
}
/* * The cached state is currently mandatory and not used to start the * search, only to cache the first state record found in the range.
*/
ASSERT(cached_state != NULL);
ASSERT(*cached_state == NULL);
*bits = 0;
spin_lock(&tree->lock);
state = tree_search(tree, start); if (state && state->start < end) {
*cached_state = state;
refcount_inc(&state->refs);
} while (state) { if (state->start > end) break;
*bits |= state->state;
if (state->end >= end) break;
state = next_state(state);
}
spin_unlock(&tree->lock);
}
/* * Check if the whole range [@start,@end) contains the single @bit set.
*/ bool btrfs_test_range_bit(struct extent_io_tree *tree, u64 start, u64 end, u32 bit, struct extent_state *cached)
{ struct extent_state *state; bool bitset = true;
ASSERT(is_power_of_2(bit));
ASSERT(start < end);
spin_lock(&tree->lock); if (cached && extent_state_in_tree(cached) && cached->start <= start &&
cached->end > start)
state = cached; else
state = tree_search(tree, start); while (state) { if (state->start > start) {
bitset = false; break;
}
/* Next state must start where this one ends. */
start = state->end + 1;
state = next_state(state);
}
/* We ran out of states and were still inside of our range. */ if (!state)
bitset = false;
spin_unlock(&tree->lock); return bitset;
}
/* Wrappers around set/clear extent bit */ int btrfs_set_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
u32 bits, struct extent_changeset *changeset)
{ /* * We don't support EXTENT_LOCK_BITS yet, as current changeset will * record any bits changed, so for EXTENT_LOCK_BITS case, it will either * fail with -EEXIST or changeset will record the whole range.
*/
ASSERT(!(bits & EXTENT_LOCK_BITS));
/* * Either insert or lock state struct between start and end use mask to tell * us if waiting is desired.
*/ int btrfs_lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, u32 bits, struct extent_state **cached_state)
{ struct extent_state *failed_state = NULL; int ret;
u64 failed_start;
ret = set_extent_bit(tree, start, end, bits, &failed_start,
&failed_state, cached_state, NULL); while (ret == -EEXIST) { if (failed_start != start)
btrfs_clear_extent_bit(tree, start, failed_start - 1,
bits, cached_state);
/* * Get the extent state that follows the given extent state. * This is meant to be used in a context where we know no other tasks can * concurrently modify the tree.
*/ struct extent_state *btrfs_next_extent_state(struct extent_io_tree *tree, struct extent_state *state)
{ struct extent_state *next;
spin_lock(&tree->lock);
ASSERT(extent_state_in_tree(state));
next = next_state(state); if (next)
refcount_inc(&next->refs);
spin_unlock(&tree->lock);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.