Commit 4313b399 authored by Chris Mason's avatar Chris Mason

Btrfs: Reduce stack usage in the resizer, fix 32 bit compiles

Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 56b453c9
...@@ -386,6 +386,7 @@ struct btrfs_root { ...@@ -386,6 +386,7 @@ struct btrfs_root {
int defrag_running; int defrag_running;
int defrag_level; int defrag_level;
char *name; char *name;
int in_sysfs;
}; };
/* /*
......
...@@ -374,6 +374,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, ...@@ -374,6 +374,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
root->highest_inode = 0; root->highest_inode = 0;
root->last_inode_alloc = 0; root->last_inode_alloc = 0;
root->name = NULL; root->name = NULL;
root->in_sysfs = 0;
memset(&root->root_key, 0, sizeof(root->root_key)); memset(&root->root_key, 0, sizeof(root->root_key));
memset(&root->root_item, 0, sizeof(root->root_item)); memset(&root->root_item, 0, sizeof(root->root_item));
memset(&root->defrag_progress, 0, sizeof(root->defrag_progress)); memset(&root->defrag_progress, 0, sizeof(root->defrag_progress));
...@@ -516,6 +517,9 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, ...@@ -516,6 +517,9 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
if (!root) if (!root)
return NULL; return NULL;
if (root->in_sysfs)
return root;
ret = btrfs_set_root_name(root, name, namelen); ret = btrfs_set_root_name(root, name, namelen);
if (ret) { if (ret) {
free_extent_buffer(root->node); free_extent_buffer(root->node);
...@@ -530,6 +534,7 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, ...@@ -530,6 +534,7 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
kfree(root); kfree(root);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
root->in_sysfs = 1;
return root; return root;
} }
#if 0 #if 0
......
...@@ -751,7 +751,7 @@ u32 btrfs_count_snapshots_in_path(struct btrfs_root *root, ...@@ -751,7 +751,7 @@ u32 btrfs_count_snapshots_in_path(struct btrfs_root *root,
if (found_objectid != root_objectid) { if (found_objectid != root_objectid) {
total_count = 2; total_count = 2;
break; goto out;
} }
total_count = 1; total_count = 1;
path->slots[0]++; path->slots[0]++;
...@@ -760,8 +760,6 @@ u32 btrfs_count_snapshots_in_path(struct btrfs_root *root, ...@@ -760,8 +760,6 @@ u32 btrfs_count_snapshots_in_path(struct btrfs_root *root,
total_count = 0; total_count = 0;
goto out; goto out;
} }
if (total_count > 1)
goto out;
if (level >= 0 && root->node == count_path->nodes[level]) if (level >= 0 && root->node == count_path->nodes[level])
goto out; goto out;
level++; level++;
...@@ -2109,22 +2107,23 @@ static int relocate_inode_pages(struct inode *inode, u64 start, u64 len) ...@@ -2109,22 +2107,23 @@ static int relocate_inode_pages(struct inode *inode, u64 start, u64 len)
u64 delalloc_start; u64 delalloc_start;
u64 existing_delalloc; u64 existing_delalloc;
unsigned long last_index; unsigned long last_index;
unsigned long first_index;
unsigned long i; unsigned long i;
struct page *page; struct page *page;
struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root *root = BTRFS_I(inode)->root;
struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
struct file_ra_state ra; struct file_ra_state *ra;
ra = kzalloc(sizeof(*ra), GFP_NOFS);
mutex_lock(&inode->i_mutex); mutex_lock(&inode->i_mutex);
first_index = start >> PAGE_CACHE_SHIFT; i = start >> PAGE_CACHE_SHIFT;
last_index = (start + len - 1) >> PAGE_CACHE_SHIFT; last_index = (start + len - 1) >> PAGE_CACHE_SHIFT;
memset(&ra, 0, sizeof(ra)); file_ra_state_init(ra, inode->i_mapping);
file_ra_state_init(&ra, inode->i_mapping); btrfs_force_ra(inode->i_mapping, ra, NULL, i, last_index);
btrfs_force_ra(inode->i_mapping, &ra, NULL, first_index, last_index); kfree(ra);
for (i = first_index; i <= last_index; i++) { for (; i <= last_index; i++) {
page = grab_cache_page(inode->i_mapping, i); page = grab_cache_page(inode->i_mapping, i);
if (!page) if (!page)
goto out_unlock; goto out_unlock;
...@@ -2167,27 +2166,43 @@ static int relocate_inode_pages(struct inode *inode, u64 start, u64 len) ...@@ -2167,27 +2166,43 @@ static int relocate_inode_pages(struct inode *inode, u64 start, u64 len)
return 0; return 0;
} }
/*
* note, this releases the path
*/
static int relocate_one_reference(struct btrfs_root *extent_root, static int relocate_one_reference(struct btrfs_root *extent_root,
struct btrfs_path *path, struct btrfs_path *path,
struct btrfs_key *extent_key, struct btrfs_key *extent_key)
u64 ref_root, u64 ref_gen, u64 ref_objectid,
u64 ref_offset)
{ {
struct inode *inode; struct inode *inode;
struct btrfs_root *found_root; struct btrfs_root *found_root;
struct btrfs_key root_location; struct btrfs_key *root_location;
struct btrfs_extent_ref *ref;
u64 ref_root;
u64 ref_gen;
u64 ref_objectid;
u64 ref_offset;
int ret; int ret;
root_location.objectid = ref_root; ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
struct btrfs_extent_ref);
ref_root = btrfs_ref_root(path->nodes[0], ref);
ref_gen = btrfs_ref_generation(path->nodes[0], ref);
ref_objectid = btrfs_ref_objectid(path->nodes[0], ref);
ref_offset = btrfs_ref_offset(path->nodes[0], ref);
btrfs_release_path(extent_root, path);
root_location = kmalloc(sizeof(*root_location), GFP_NOFS);
root_location->objectid = ref_root;
if (ref_gen == 0) if (ref_gen == 0)
root_location.offset = 0; root_location->offset = 0;
else else
root_location.offset = (u64)-1; root_location->offset = (u64)-1;
root_location.type = BTRFS_ROOT_ITEM_KEY; root_location->type = BTRFS_ROOT_ITEM_KEY;
found_root = btrfs_read_fs_root_no_name(extent_root->fs_info, found_root = btrfs_read_fs_root_no_name(extent_root->fs_info,
&root_location); root_location);
BUG_ON(!found_root); BUG_ON(!found_root);
kfree(root_location);
if (ref_objectid >= BTRFS_FIRST_FREE_OBJECTID) { if (ref_objectid >= BTRFS_FIRST_FREE_OBJECTID) {
mutex_unlock(&extent_root->fs_info->fs_mutex); mutex_unlock(&extent_root->fs_info->fs_mutex);
...@@ -2259,12 +2274,7 @@ static int relocate_one_extent(struct btrfs_root *extent_root, ...@@ -2259,12 +2274,7 @@ static int relocate_one_extent(struct btrfs_root *extent_root,
{ {
struct btrfs_key key; struct btrfs_key key;
struct btrfs_key found_key; struct btrfs_key found_key;
struct btrfs_extent_ref *ref;
struct extent_buffer *leaf; struct extent_buffer *leaf;
u64 ref_root;
u64 ref_gen;
u64 ref_objectid;
u64 ref_offset;
u32 nritems; u32 nritems;
u32 item_size; u32 item_size;
int ret = 0; int ret = 0;
...@@ -2297,17 +2307,7 @@ static int relocate_one_extent(struct btrfs_root *extent_root, ...@@ -2297,17 +2307,7 @@ static int relocate_one_extent(struct btrfs_root *extent_root,
key.offset = found_key.offset + 1; key.offset = found_key.offset + 1;
item_size = btrfs_item_size_nr(leaf, path->slots[0]); item_size = btrfs_item_size_nr(leaf, path->slots[0]);
ref = btrfs_item_ptr(leaf, path->slots[0], ret = relocate_one_reference(extent_root, path, extent_key);
struct btrfs_extent_ref);
ref_root = btrfs_ref_root(leaf, ref);
ref_gen = btrfs_ref_generation(leaf, ref);
ref_objectid = btrfs_ref_objectid(leaf, ref);
ref_offset = btrfs_ref_offset(leaf, ref);
btrfs_release_path(extent_root, path);
ret = relocate_one_reference(extent_root, path,
extent_key, ref_root, ref_gen,
ref_objectid, ref_offset);
if (ret) if (ret)
goto out; goto out;
} }
...@@ -2354,7 +2354,6 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 new_size) ...@@ -2354,7 +2354,6 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 new_size)
struct btrfs_path *path; struct btrfs_path *path;
u64 cur_byte; u64 cur_byte;
u64 total_found; u64 total_found;
u64 ptr;
struct btrfs_fs_info *info = root->fs_info; struct btrfs_fs_info *info = root->fs_info;
struct extent_map_tree *block_group_cache; struct extent_map_tree *block_group_cache;
struct btrfs_key key; struct btrfs_key key;
...@@ -2377,6 +2376,7 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 new_size) ...@@ -2377,6 +2376,7 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 new_size)
key.offset = 0; key.offset = 0;
key.type = 0; key.type = 0;
while(1) { while(1) {
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
if (ret < 0) if (ret < 0)
goto out; goto out;
...@@ -2441,6 +2441,8 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 new_size) ...@@ -2441,6 +2441,8 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 new_size)
key.offset = 0; key.offset = 0;
key.type = 0; key.type = 0;
while(1) { while(1) {
u64 ptr;
ret = btrfs_search_slot(trans, root, &key, path, -1, 1); ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
if (ret < 0) if (ret < 0)
goto out; goto out;
......
...@@ -2108,7 +2108,8 @@ static void btrfs_truncate(struct inode *inode) ...@@ -2108,7 +2108,8 @@ static void btrfs_truncate(struct inode *inode)
btrfs_btree_balance_dirty(root, nr); btrfs_btree_balance_dirty(root, nr);
} }
static int create_subvol(struct btrfs_root *root, char *name, int namelen) static int noinline create_subvol(struct btrfs_root *root, char *name,
int namelen)
{ {
struct btrfs_trans_handle *trans; struct btrfs_trans_handle *trans;
struct btrfs_key key; struct btrfs_key key;
...@@ -2492,7 +2493,8 @@ printk("new size is %Lu\n", new_size); ...@@ -2492,7 +2493,8 @@ printk("new size is %Lu\n", new_size);
return ret; return ret;
} }
static int btrfs_ioctl_snap_create(struct btrfs_root *root, void __user *arg) static int noinline btrfs_ioctl_snap_create(struct btrfs_root *root,
void __user *arg)
{ {
struct btrfs_ioctl_vol_args *vol_args; struct btrfs_ioctl_vol_args *vol_args;
struct btrfs_dir_item *di; struct btrfs_dir_item *di;
......
...@@ -481,12 +481,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, ...@@ -481,12 +481,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
struct btrfs_transaction *cur_trans; struct btrfs_transaction *cur_trans;
struct btrfs_transaction *prev_trans = NULL; struct btrfs_transaction *prev_trans = NULL;
struct list_head dirty_fs_roots; struct list_head dirty_fs_roots;
struct extent_map_tree pinned_copy; struct extent_map_tree *pinned_copy;
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
int ret; int ret;
extent_map_tree_init(&pinned_copy,
root->fs_info->btree_inode->i_mapping, GFP_NOFS);
INIT_LIST_HEAD(&dirty_fs_roots); INIT_LIST_HEAD(&dirty_fs_roots);
mutex_lock(&root->fs_info->trans_mutex); mutex_lock(&root->fs_info->trans_mutex);
...@@ -507,6 +505,14 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, ...@@ -507,6 +505,14 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
mutex_lock(&root->fs_info->fs_mutex); mutex_lock(&root->fs_info->fs_mutex);
return 0; return 0;
} }
pinned_copy = kmalloc(sizeof(*pinned_copy), GFP_NOFS);
if (!pinned_copy)
return -ENOMEM;
extent_map_tree_init(pinned_copy,
root->fs_info->btree_inode->i_mapping, GFP_NOFS);
trans->transaction->in_commit = 1; trans->transaction->in_commit = 1;
cur_trans = trans->transaction; cur_trans = trans->transaction;
if (cur_trans->list.prev != &root->fs_info->trans_list) { if (cur_trans->list.prev != &root->fs_info->trans_list) {
...@@ -568,16 +574,20 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, ...@@ -568,16 +574,20 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
&root->fs_info->super_copy, 0, &root->fs_info->super_copy, 0,
sizeof(root->fs_info->super_copy)); sizeof(root->fs_info->super_copy));
btrfs_copy_pinned(root, &pinned_copy); btrfs_copy_pinned(root, pinned_copy);
mutex_unlock(&root->fs_info->trans_mutex); mutex_unlock(&root->fs_info->trans_mutex);
mutex_unlock(&root->fs_info->fs_mutex); mutex_unlock(&root->fs_info->fs_mutex);
ret = btrfs_write_and_wait_transaction(trans, root); ret = btrfs_write_and_wait_transaction(trans, root);
BUG_ON(ret); BUG_ON(ret);
write_ctree_super(trans, root); write_ctree_super(trans, root);
mutex_lock(&root->fs_info->fs_mutex); mutex_lock(&root->fs_info->fs_mutex);
btrfs_finish_extent_commit(trans, root, &pinned_copy); btrfs_finish_extent_commit(trans, root, pinned_copy);
mutex_lock(&root->fs_info->trans_mutex); mutex_lock(&root->fs_info->trans_mutex);
kfree(pinned_copy);
cur_trans->commit_done = 1; cur_trans->commit_done = 1;
root->fs_info->last_trans_committed = cur_trans->transid; root->fs_info->last_trans_committed = cur_trans->transid;
wake_up(&cur_trans->commit_wait); wake_up(&cur_trans->commit_wait);
......
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