Ejemplo n.º 1
0
/*
 * 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
 */
static int merge_state(struct extent_io_tree *tree,
                       struct extent_state *state)
{
    struct extent_state *other;
    struct cache_extent *other_node;

    if (state->state & EXTENT_IOBITS)
        return 0;

    other_node = prev_cache_extent(&state->cache_node);
    if (other_node) {
        other = container_of(other_node, struct extent_state,
                             cache_node);
        if (other->end == state->start - 1 &&
                other->state == state->state) {
            state->start = other->start;
            update_extent_state(state);
            remove_cache_extent(&tree->state, &other->cache_node);
            btrfs_free_extent_state(other);
        }
    }
    other_node = next_cache_extent(&state->cache_node);
    if (other_node) {
        other = container_of(other_node, struct extent_state,
                             cache_node);
        if (other->start == state->end + 1 &&
                other->state == state->state) {
            other->start = state->start;
            update_extent_state(other);
            remove_cache_extent(&tree->state, &state->cache_node);
            btrfs_free_extent_state(state);
        }
    }
    return 0;
}
Ejemplo n.º 2
0
void extent_io_tree_cleanup(struct extent_io_tree *tree)
{
	struct extent_state *es;
	struct extent_buffer *eb;
	struct cache_extent *cache;

	while(!list_empty(&tree->lru)) {
		eb = list_entry(tree->lru.next, struct extent_buffer, lru);
		if (eb->refs != 1) {
			fprintf(stderr, "extent buffer leak: "
				"start %llu len %u\n",
				(unsigned long long)eb->start, eb->len);
			eb->refs = 1;
		}
		free_extent_buffer(eb);
	}
	while (1) {
		cache = find_first_cache_extent(&tree->state, 0);
		if (!cache)
			break;
		es = container_of(cache, struct extent_state, cache_node);
		remove_cache_extent(&tree->state, &es->cache_node);
		free_extent_state(es);
	}
}
Ejemplo n.º 3
0
/*
 * clear some bits on a range in the tree.
 */
static int clear_state_bit(struct extent_io_tree *tree,
                           struct extent_state *state, int bits)
{
    int ret = state->state & bits;

    state->state &= ~bits;
    if (state->state == 0) {
        remove_cache_extent(&tree->state, &state->cache_node);
        btrfs_free_extent_state(state);
    } else {
        merge_state(tree, state);
    }
    return ret;
}
Ejemplo n.º 4
0
static int free_fs_roots(struct btrfs_fs_info *fs_info)
{
	struct cache_extent *cache;
	struct btrfs_root *root;

	while (1) {
		cache = find_first_cache_extent(&fs_info->fs_root_cache, 0);
		if (!cache)
			break;
		root = container_of(cache, struct btrfs_root, cache);
		remove_cache_extent(&fs_info->fs_root_cache, cache);
		btrfs_free_fs_root(fs_info, root);
	}
	return 0;
}