Commit e37c9e69 authored by Chris Mason's avatar Chris Mason Committed by David Woodhouse

Btrfs: many allocator fixes, pretty solid

Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 3e1ad54f
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* Get rid of struct ctree_path, limiting tree levels held at one time * Get rid of struct ctree_path, limiting tree levels held at one time
* Add generation number to key pointer in nodes * Add generation number to key pointer in nodes
* Add generation number to inode * Add generation number to inode
* Add ability to switch a block group from data to metadata or vice versa
* Release * Release
* Do real tree locking * Do real tree locking
* Add extent mirroring (backup copies of blocks) * Add extent mirroring (backup copies of blocks)
......
...@@ -77,7 +77,7 @@ int clear_radix_bit(struct radix_tree_root *radix, unsigned long bit) ...@@ -77,7 +77,7 @@ int clear_radix_bit(struct radix_tree_root *radix, unsigned long bit)
} }
int find_first_radix_bit(struct radix_tree_root *radix, unsigned long *retbits, int find_first_radix_bit(struct radix_tree_root *radix, unsigned long *retbits,
int nr) unsigned long start, int nr)
{ {
unsigned long *bits; unsigned long *bits;
unsigned long *gang[4]; unsigned long *gang[4];
...@@ -85,10 +85,13 @@ int find_first_radix_bit(struct radix_tree_root *radix, unsigned long *retbits, ...@@ -85,10 +85,13 @@ int find_first_radix_bit(struct radix_tree_root *radix, unsigned long *retbits,
int ret; int ret;
int i; int i;
int total_found = 0; int total_found = 0;
unsigned long slot;
ret = radix_tree_gang_lookup(radix, (void **)gang, 0, ARRAY_SIZE(gang)); slot = start / BIT_RADIX_BITS_PER_ARRAY;
ret = radix_tree_gang_lookup(radix, (void **)gang, slot,
ARRAY_SIZE(gang));
found = start % BIT_RADIX_BITS_PER_ARRAY;
for (i = 0; i < ret && nr > 0; i++) { for (i = 0; i < ret && nr > 0; i++) {
found = 0;
bits = gang[i]; bits = gang[i];
while(nr > 0) { while(nr > 0) {
found = find_next_bit(bits + 1, found = find_next_bit(bits + 1,
...@@ -104,6 +107,7 @@ int find_first_radix_bit(struct radix_tree_root *radix, unsigned long *retbits, ...@@ -104,6 +107,7 @@ int find_first_radix_bit(struct radix_tree_root *radix, unsigned long *retbits,
} else } else
break; break;
} }
found = 0;
} }
return total_found; return total_found;
} }
...@@ -6,7 +6,7 @@ int set_radix_bit(struct radix_tree_root *radix, unsigned long bit); ...@@ -6,7 +6,7 @@ int set_radix_bit(struct radix_tree_root *radix, unsigned long bit);
int test_radix_bit(struct radix_tree_root *radix, unsigned long bit); int test_radix_bit(struct radix_tree_root *radix, unsigned long bit);
int clear_radix_bit(struct radix_tree_root *radix, unsigned long bit); int clear_radix_bit(struct radix_tree_root *radix, unsigned long bit);
int find_first_radix_bit(struct radix_tree_root *radix, unsigned long *retbits, int find_first_radix_bit(struct radix_tree_root *radix, unsigned long *retbits,
int nr); unsigned long start, int nr);
static inline void init_bit_radix(struct radix_tree_root *radix) static inline void init_bit_radix(struct radix_tree_root *radix)
{ {
......
...@@ -259,7 +259,9 @@ struct btrfs_block_group_cache { ...@@ -259,7 +259,9 @@ struct btrfs_block_group_cache {
u64 first_free; u64 first_free;
u64 last_alloc; u64 last_alloc;
u64 pinned; u64 pinned;
u64 last_prealloc;
int data; int data;
int cached;
}; };
struct crypto_hash; struct crypto_hash;
...@@ -273,6 +275,7 @@ struct btrfs_fs_info { ...@@ -273,6 +275,7 @@ struct btrfs_fs_info {
struct radix_tree_root dev_radix; struct radix_tree_root dev_radix;
struct radix_tree_root block_group_radix; struct radix_tree_root block_group_radix;
struct radix_tree_root block_group_data_radix; struct radix_tree_root block_group_data_radix;
struct radix_tree_root extent_map_radix;
u64 extent_tree_insert[BTRFS_MAX_LEVEL * 3]; u64 extent_tree_insert[BTRFS_MAX_LEVEL * 3];
int extent_tree_insert_nr; int extent_tree_insert_nr;
......
...@@ -551,6 +551,7 @@ struct btrfs_root *open_ctree(struct super_block *sb) ...@@ -551,6 +551,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
init_bit_radix(&fs_info->pinned_radix); init_bit_radix(&fs_info->pinned_radix);
init_bit_radix(&fs_info->pending_del_radix); init_bit_radix(&fs_info->pending_del_radix);
init_bit_radix(&fs_info->extent_map_radix);
INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_NOFS); INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_NOFS);
INIT_RADIX_TREE(&fs_info->dev_radix, GFP_NOFS); INIT_RADIX_TREE(&fs_info->dev_radix, GFP_NOFS);
INIT_RADIX_TREE(&fs_info->block_group_radix, GFP_KERNEL); INIT_RADIX_TREE(&fs_info->block_group_radix, GFP_KERNEL);
......
This diff is collapsed.
...@@ -1539,7 +1539,7 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans, ...@@ -1539,7 +1539,7 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
kunmap(pages[i]); kunmap(pages[i]);
} }
SetPageChecked(pages[i]); SetPageChecked(pages[i]);
btrfs_update_inode_block_group(trans, inode); // btrfs_update_inode_block_group(trans, inode);
ret = btrfs_end_transaction(trans, root); ret = btrfs_end_transaction(trans, root);
BUG_ON(ret); BUG_ON(ret);
mutex_unlock(&root->fs_info->fs_mutex); mutex_unlock(&root->fs_info->fs_mutex);
...@@ -1914,7 +1914,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, ...@@ -1914,7 +1914,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
} }
BUG_ON(ret); BUG_ON(ret);
alloc_extent_start = ins.objectid; alloc_extent_start = ins.objectid;
btrfs_update_inode_block_group(trans, inode); // btrfs_update_inode_block_group(trans, inode);
ret = btrfs_end_transaction(trans, root); ret = btrfs_end_transaction(trans, root);
mutex_unlock(&root->fs_info->fs_mutex); mutex_unlock(&root->fs_info->fs_mutex);
......
...@@ -122,7 +122,8 @@ int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, ...@@ -122,7 +122,8 @@ int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
} }
dirty_pages = &trans->transaction->dirty_pages; dirty_pages = &trans->transaction->dirty_pages;
while(1) { while(1) {
ret = find_first_radix_bit(dirty_pages, gang, ARRAY_SIZE(gang)); ret = find_first_radix_bit(dirty_pages, gang,
0, ARRAY_SIZE(gang));
if (!ret) if (!ret)
break; break;
for (i = 0; i < ret; i++) { for (i = 0; i < ret; i++) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment