summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ctree.h10
-rw-r--r--disk-io.c3
-rw-r--r--extent-tree.c23
3 files changed, 26 insertions, 10 deletions
diff --git a/ctree.h b/ctree.h
index 32b91906..1de24290 100644
--- a/ctree.h
+++ b/ctree.h
@@ -298,6 +298,12 @@ struct btrfs_block_group_cache {
int cached;
u64 pinned;
};
+struct btrfs_extent_ops {
+ int (*alloc_extent)(struct btrfs_root *root, u64 num_bytes,
+ u64 hint_byte, struct btrfs_key *ins);
+ int (*free_extent)(struct btrfs_root *root, u64 bytenr,
+ u64 num_bytes);
+};
struct btrfs_fs_info {
u8 fsid[BTRFS_FSID_SIZE];
@@ -322,8 +328,10 @@ struct btrfs_fs_info {
struct mutex fs_mutex;
int fp;
u64 total_pinned;
-};
+ struct btrfs_extent_ops *extent_ops;
+ void *priv_data;
+};
/*
* in ram representation of the tree. extent_root is used for all allocations
* and for the extent tree extent_root root.
diff --git a/disk-io.c b/disk-io.c
index fad099a3..96cafe6b 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -396,7 +396,8 @@ struct btrfs_root *open_ctree_fd(int fp, u64 sb_bytenr)
fs_info->fs_root = root;
fs_info->tree_root = tree_root;
fs_info->extent_root = extent_root;
-
+ fs_info->extent_ops = NULL;
+ fs_info->priv_data = NULL;
extent_map_tree_init(&fs_info->extent_cache);
extent_map_tree_init(&fs_info->free_space_cache);
extent_map_tree_init(&fs_info->pending_tree);
diff --git a/extent-tree.c b/extent-tree.c
index 33aa0557..c9b2a088 100644
--- a/extent-tree.c
+++ b/extent-tree.c
@@ -1209,6 +1209,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
struct btrfs_path *path;
struct btrfs_key key;
struct btrfs_fs_info *info = root->fs_info;
+ struct btrfs_extent_ops *ops = info->extent_ops;
struct btrfs_root *extent_root = info->extent_root;
struct extent_buffer *leaf;
int ret;
@@ -1272,11 +1273,13 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
root_used = btrfs_root_used(&root->root_item);
btrfs_set_root_used(&root->root_item,
root_used - num_bytes);
-
ret = btrfs_del_item(trans, extent_root, path);
- if (ret) {
+ if (ret)
return ret;
- }
+
+ if (ops && ops->free_extent)
+ ops->free_extent(root, bytenr, num_bytes);
+
ret = update_block_group(trans, root, bytenr, num_bytes, 0,
mark_free, 0);
BUG_ON(ret);
@@ -1626,6 +1629,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
u64 new_hint;
*/
struct btrfs_fs_info *info = root->fs_info;
+ struct btrfs_extent_ops *ops = info->extent_ops;
struct btrfs_root *extent_root = info->extent_root;
struct btrfs_extent_item extent_item;
struct btrfs_path *path;
@@ -1637,12 +1641,15 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
if (new_hint < btrfs_super_total_bytes(&info->super_copy))
hint_byte = new_hint;
*/
-
WARN_ON(num_bytes < root->sectorsize);
- ret = find_free_extent(trans, root, num_bytes, empty_size,
- search_start, search_end, hint_byte, ins,
- trans->alloc_exclude_start,
- trans->alloc_exclude_nr, data);
+ if (ops && ops->alloc_extent) {
+ ret = ops->alloc_extent(root, num_bytes, hint_byte, ins);
+ } else {
+ ret = find_free_extent(trans, root, num_bytes, empty_size,
+ search_start, search_end, hint_byte,
+ ins, trans->alloc_exclude_start,
+ trans->alloc_exclude_nr, data);
+ }
BUG_ON(ret);
if (ret)
return ret;