btrfs-progs: Pull free space tree related code from kernel
To help implement free space tree checker in user space some kernel function are necessary, namely iterating/deleting/adding freespace items, some internal search functions. Functions to populate a block group based on the extent tree. The code is largely copy/paste from the kernel with locking eliminated (i.e free_space_lock). It supports reading/writing of both bitmap and extent based FST trees. Signed-off-by: Nikolay Borisov <nborisov@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
a9ce9286f2
commit
8c028efe4a
74
ctree.c
74
ctree.c
|
@ -1225,6 +1225,80 @@ again:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper to use instead of search slot if no exact match is needed but
|
||||
* instead the next or previous item should be returned.
|
||||
* When find_higher is true, the next higher item is returned, the next lower
|
||||
* otherwise.
|
||||
* When return_any and find_higher are both true, and no higher item is found,
|
||||
* return the next lower instead.
|
||||
* When return_any is true and find_higher is false, and no lower item is found,
|
||||
* return the next higher instead.
|
||||
* It returns 0 if any item is found, 1 if none is found (tree empty), and
|
||||
* < 0 on error
|
||||
*/
|
||||
int btrfs_search_slot_for_read(struct btrfs_root *root,
|
||||
const struct btrfs_key *key,
|
||||
struct btrfs_path *p, int find_higher,
|
||||
int return_any)
|
||||
{
|
||||
int ret;
|
||||
struct extent_buffer *leaf;
|
||||
|
||||
again:
|
||||
ret = btrfs_search_slot(NULL, root, key, p, 0, 0);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
/*
|
||||
* A return value of 1 means the path is at the position where the item
|
||||
* should be inserted. Normally this is the next bigger item, but in
|
||||
* case the previous item is the last in a leaf, path points to the
|
||||
* first free slot in the previous leaf, i.e. at an invalid item.
|
||||
*/
|
||||
leaf = p->nodes[0];
|
||||
|
||||
if (find_higher) {
|
||||
if (p->slots[0] >= btrfs_header_nritems(leaf)) {
|
||||
ret = btrfs_next_leaf(root, p);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
if (!return_any)
|
||||
return 1;
|
||||
/*
|
||||
* No higher item found, return the next lower instead
|
||||
*/
|
||||
return_any = 0;
|
||||
find_higher = 0;
|
||||
btrfs_release_path(p);
|
||||
goto again;
|
||||
}
|
||||
} else {
|
||||
if (p->slots[0] == 0) {
|
||||
ret = btrfs_prev_leaf(root, p);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (!ret) {
|
||||
leaf = p->nodes[0];
|
||||
if (p->slots[0] == btrfs_header_nritems(leaf))
|
||||
p->slots[0]--;
|
||||
return 0;
|
||||
}
|
||||
if (!return_any)
|
||||
return 1;
|
||||
/*
|
||||
* No lower item found, return the next higher instead
|
||||
*/
|
||||
return_any = 0;
|
||||
find_higher = 1;
|
||||
btrfs_release_path(p);
|
||||
goto again;
|
||||
} else {
|
||||
--p->slots[0];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* adjust the pointers going up the tree, starting at level
|
||||
* making sure the right key of each node is points to 'key'.
|
||||
|
|
15
ctree.h
15
ctree.h
|
@ -1071,6 +1071,17 @@ struct btrfs_block_group_cache {
|
|||
u64 flags;
|
||||
int cached;
|
||||
int ro;
|
||||
/*
|
||||
* If the free space extent count exceeds this number, convert the block
|
||||
* group to bitmaps.
|
||||
*/
|
||||
u32 bitmap_high_thresh;
|
||||
/*
|
||||
* If the free space extent count drops below this number, convert the
|
||||
* block group back to extents.
|
||||
*/
|
||||
u32 bitmap_low_thresh;
|
||||
|
||||
};
|
||||
|
||||
struct btrfs_device;
|
||||
|
@ -2596,6 +2607,10 @@ int btrfs_split_item(struct btrfs_trans_handle *trans,
|
|||
int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
|
||||
*root, struct btrfs_key *key, struct btrfs_path *p, int
|
||||
ins_len, int cow);
|
||||
int btrfs_search_slot_for_read(struct btrfs_root *root,
|
||||
const struct btrfs_key *key,
|
||||
struct btrfs_path *p, int find_higher,
|
||||
int return_any);
|
||||
int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path,
|
||||
u64 iobjectid, u64 ioff, u8 key_type,
|
||||
struct btrfs_key *found_key);
|
||||
|
|
1249
free-space-tree.c
1249
free-space-tree.c
File diff suppressed because it is too large
Load Diff
|
@ -19,8 +19,20 @@
|
|||
#ifndef __BTRFS_FREE_SPACE_TREE_H__
|
||||
#define __BTRFS_FREE_SPACE_TREE_H__
|
||||
|
||||
#define BTRFS_FREE_SPACE_BITMAP_SIZE 256
|
||||
#define BTRFS_FREE_SPACE_BITMAP_BITS (BTRFS_FREE_SPACE_BITMAP_SIZE * BITS_PER_BYTE)
|
||||
|
||||
int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info);
|
||||
int load_free_space_tree(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_block_group_cache *block_group);
|
||||
int populate_free_space_tree(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_block_group_cache *block_group);
|
||||
int remove_block_group_free_space(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_block_group_cache *block_group);
|
||||
int add_to_free_space_tree(struct btrfs_trans_handle *trans, u64 start,
|
||||
u64 size);
|
||||
int remove_from_free_space_tree(struct btrfs_trans_handle *trans, u64 start,
|
||||
u64 size);
|
||||
int btrfs_create_free_space_tree(struct btrfs_fs_info *info);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -263,6 +263,8 @@ static inline int IS_ERR_OR_NULL(const void *ptr)
|
|||
return !ptr || IS_ERR(ptr);
|
||||
}
|
||||
|
||||
#define div_u64(x, y) ((x) / (y))
|
||||
|
||||
/**
|
||||
* swap - swap values of @a and @b
|
||||
* @a: first value
|
||||
|
@ -297,6 +299,10 @@ static inline int IS_ERR_OR_NULL(const void *ptr)
|
|||
#define kfree(x) free(x)
|
||||
#define vmalloc(x) malloc(x)
|
||||
#define vfree(x) free(x)
|
||||
#define kvzalloc(x, y) kzalloc(x,y)
|
||||
#define kvfree(x) free(x)
|
||||
#define memalloc_nofs_save() (0)
|
||||
#define memalloc_nofs_restore(x) ((void)(x))
|
||||
|
||||
#ifndef BTRFS_DISABLE_BACKTRACE
|
||||
static inline void assert_trace(const char *assertion, const char *filename,
|
||||
|
|
Loading…
Reference in New Issue