mirror of
https://github.com/kdave/btrfs-progs
synced 2025-03-25 04:16:32 +00:00
btrfs-progs: move extent cache code directly into btrfs_fs_info
We have some extra features in the btrfs-progs copy of the extent_io_tree that don't exist in the kernel. In order to make syncing easier simply move this functionality into btrfs_fs_info, that way we can sync in the new extent_io_tree code and not have to worry about breaking anything. Signed-off-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
412eea9e97
commit
20d88c17e7
kernel-shared
@ -1217,7 +1217,11 @@ struct btrfs_fs_info {
|
||||
/* the log root tree is a directory of all the other log roots */
|
||||
struct btrfs_root *log_root_tree;
|
||||
|
||||
struct extent_io_tree extent_cache;
|
||||
struct cache_tree extent_cache;
|
||||
u64 max_cache_size;
|
||||
u64 cache_size;
|
||||
struct list_head lru;
|
||||
|
||||
struct extent_io_tree dirty_buffers;
|
||||
struct extent_io_tree free_space_cache;
|
||||
struct extent_io_tree pinned_extents;
|
||||
|
@ -864,7 +864,7 @@ struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr)
|
||||
!fs_info->block_group_root || !fs_info->super_copy)
|
||||
goto free_all;
|
||||
|
||||
extent_io_tree_init(&fs_info->extent_cache);
|
||||
extent_buffer_init_cache(fs_info);
|
||||
extent_io_tree_init(&fs_info->dirty_buffers);
|
||||
extent_io_tree_init(&fs_info->free_space_cache);
|
||||
extent_io_tree_init(&fs_info->pinned_extents);
|
||||
@ -1350,7 +1350,7 @@ void btrfs_cleanup_all_caches(struct btrfs_fs_info *fs_info)
|
||||
}
|
||||
free_mapping_cache_tree(&fs_info->mapping_tree.cache_tree);
|
||||
extent_io_tree_cleanup(&fs_info->dirty_buffers);
|
||||
extent_io_tree_cleanup(&fs_info->extent_cache);
|
||||
extent_buffer_free_cache(fs_info);
|
||||
extent_io_tree_cleanup(&fs_info->free_space_cache);
|
||||
extent_io_tree_cleanup(&fs_info->pinned_extents);
|
||||
extent_io_tree_cleanup(&fs_info->extent_ins);
|
||||
|
@ -35,13 +35,45 @@
|
||||
#include "common/device-utils.h"
|
||||
#include "common/internal.h"
|
||||
|
||||
static void free_extent_buffer_final(struct extent_buffer *eb);
|
||||
|
||||
void extent_buffer_init_cache(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
fs_info->max_cache_size = total_memory() / 4;
|
||||
fs_info->cache_size = 0;
|
||||
INIT_LIST_HEAD(&fs_info->lru);
|
||||
}
|
||||
|
||||
void extent_buffer_free_cache(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
struct extent_buffer *eb;
|
||||
|
||||
while(!list_empty(&fs_info->lru)) {
|
||||
eb = list_entry(fs_info->lru.next, struct extent_buffer, lru);
|
||||
if (eb->refs) {
|
||||
/*
|
||||
* Reset extent buffer refs to 1, so the
|
||||
* free_extent_buffer_nocache() can free it for sure.
|
||||
*/
|
||||
eb->refs = 1;
|
||||
fprintf(stderr,
|
||||
"extent buffer leak: start %llu len %u\n",
|
||||
(unsigned long long)eb->start, eb->len);
|
||||
free_extent_buffer_nocache(eb);
|
||||
} else {
|
||||
free_extent_buffer_final(eb);
|
||||
}
|
||||
}
|
||||
|
||||
free_extent_cache_tree(&fs_info->extent_cache);
|
||||
fs_info->cache_size = 0;
|
||||
}
|
||||
|
||||
void extent_io_tree_init(struct extent_io_tree *tree)
|
||||
{
|
||||
cache_tree_init(&tree->state);
|
||||
cache_tree_init(&tree->cache);
|
||||
INIT_LIST_HEAD(&tree->lru);
|
||||
tree->cache_size = 0;
|
||||
tree->max_cache_size = (u64)total_memory() / 4;
|
||||
}
|
||||
|
||||
static struct extent_state *alloc_extent_state(void)
|
||||
@ -74,7 +106,6 @@ static void free_extent_state_func(struct cache_extent *cache)
|
||||
btrfs_free_extent_state(es);
|
||||
}
|
||||
|
||||
static void free_extent_buffer_final(struct extent_buffer *eb);
|
||||
void extent_io_tree_cleanup(struct extent_io_tree *tree)
|
||||
{
|
||||
struct extent_buffer *eb;
|
||||
@ -645,11 +676,9 @@ static void free_extent_buffer_final(struct extent_buffer *eb)
|
||||
BUG_ON(eb->refs);
|
||||
list_del_init(&eb->lru);
|
||||
if (!(eb->flags & EXTENT_BUFFER_DUMMY)) {
|
||||
struct extent_io_tree *tree = &eb->fs_info->extent_cache;
|
||||
|
||||
remove_cache_extent(&tree->cache, &eb->cache_node);
|
||||
BUG_ON(tree->cache_size < eb->len);
|
||||
tree->cache_size -= eb->len;
|
||||
remove_cache_extent(&eb->fs_info->extent_cache, &eb->cache_node);
|
||||
BUG_ON(eb->fs_info->cache_size < eb->len);
|
||||
eb->fs_info->cache_size -= eb->len;
|
||||
}
|
||||
free(eb);
|
||||
}
|
||||
@ -686,15 +715,14 @@ void free_extent_buffer_nocache(struct extent_buffer *eb)
|
||||
struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info,
|
||||
u64 bytenr, u32 blocksize)
|
||||
{
|
||||
struct extent_io_tree *tree = &fs_info->extent_cache;
|
||||
struct extent_buffer *eb = NULL;
|
||||
struct cache_extent *cache;
|
||||
|
||||
cache = lookup_cache_extent(&tree->cache, bytenr, blocksize);
|
||||
cache = lookup_cache_extent(&fs_info->extent_cache, bytenr, blocksize);
|
||||
if (cache && cache->start == bytenr &&
|
||||
cache->size == blocksize) {
|
||||
eb = container_of(cache, struct extent_buffer, cache_node);
|
||||
list_move_tail(&eb->lru, &tree->lru);
|
||||
list_move_tail(&eb->lru, &fs_info->lru);
|
||||
eb->refs++;
|
||||
}
|
||||
return eb;
|
||||
@ -703,27 +731,26 @@ struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info,
|
||||
struct extent_buffer *find_first_extent_buffer(struct btrfs_fs_info *fs_info,
|
||||
u64 start)
|
||||
{
|
||||
struct extent_io_tree *tree = &fs_info->extent_cache;
|
||||
struct extent_buffer *eb = NULL;
|
||||
struct cache_extent *cache;
|
||||
|
||||
cache = search_cache_extent(&tree->cache, start);
|
||||
cache = search_cache_extent(&fs_info->extent_cache, start);
|
||||
if (cache) {
|
||||
eb = container_of(cache, struct extent_buffer, cache_node);
|
||||
list_move_tail(&eb->lru, &tree->lru);
|
||||
list_move_tail(&eb->lru, &fs_info->lru);
|
||||
eb->refs++;
|
||||
}
|
||||
return eb;
|
||||
}
|
||||
|
||||
static void trim_extent_buffer_cache(struct extent_io_tree *tree)
|
||||
static void trim_extent_buffer_cache(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
struct extent_buffer *eb, *tmp;
|
||||
|
||||
list_for_each_entry_safe(eb, tmp, &tree->lru, lru) {
|
||||
list_for_each_entry_safe(eb, tmp, &fs_info->lru, lru) {
|
||||
if (eb->refs == 0)
|
||||
free_extent_buffer_final(eb);
|
||||
if (tree->cache_size <= ((tree->max_cache_size * 9) / 10))
|
||||
if (fs_info->cache_size <= ((fs_info->max_cache_size * 9) / 10))
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -732,14 +759,13 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
|
||||
u64 bytenr, u32 blocksize)
|
||||
{
|
||||
struct extent_buffer *eb;
|
||||
struct extent_io_tree *tree = &fs_info->extent_cache;
|
||||
struct cache_extent *cache;
|
||||
|
||||
cache = lookup_cache_extent(&tree->cache, bytenr, blocksize);
|
||||
cache = lookup_cache_extent(&fs_info->extent_cache, bytenr, blocksize);
|
||||
if (cache && cache->start == bytenr &&
|
||||
cache->size == blocksize) {
|
||||
eb = container_of(cache, struct extent_buffer, cache_node);
|
||||
list_move_tail(&eb->lru, &tree->lru);
|
||||
list_move_tail(&eb->lru, &fs_info->lru);
|
||||
eb->refs++;
|
||||
} else {
|
||||
int ret;
|
||||
@ -752,15 +778,15 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
|
||||
eb = __alloc_extent_buffer(fs_info, bytenr, blocksize);
|
||||
if (!eb)
|
||||
return NULL;
|
||||
ret = insert_cache_extent(&tree->cache, &eb->cache_node);
|
||||
ret = insert_cache_extent(&fs_info->extent_cache, &eb->cache_node);
|
||||
if (ret) {
|
||||
free(eb);
|
||||
return NULL;
|
||||
}
|
||||
list_add_tail(&eb->lru, &tree->lru);
|
||||
tree->cache_size += blocksize;
|
||||
if (tree->cache_size >= tree->max_cache_size)
|
||||
trim_extent_buffer_cache(tree);
|
||||
list_add_tail(&eb->lru, &fs_info->lru);
|
||||
fs_info->cache_size += blocksize;
|
||||
if (fs_info->cache_size >= fs_info->max_cache_size)
|
||||
trim_extent_buffer_cache(fs_info);
|
||||
}
|
||||
return eb;
|
||||
}
|
||||
|
@ -165,5 +165,7 @@ void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start,
|
||||
unsigned long pos, unsigned long len);
|
||||
void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,
|
||||
unsigned long pos, unsigned long len);
|
||||
void extent_buffer_init_cache(struct btrfs_fs_info *fs_info);
|
||||
void extent_buffer_free_cache(struct btrfs_fs_info *fs_info);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user