aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-01-03 09:08:48 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:58 -0400
commit4313b3994d719fcdeb7e661473019ca3d62e829b (patch)
tree1a18dca96a9f54e8444c4c06c9beda3694bc25d3
parent56b453c92fdf51fd3283a2dc2dfbedf36f516031 (diff)
Btrfs: Reduce stack usage in the resizer, fix 32 bit compiles
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/ctree.h1
-rw-r--r--fs/btrfs/disk-io.c5
-rw-r--r--fs/btrfs/extent-tree.c74
-rw-r--r--fs/btrfs/inode.c6
-rw-r--r--fs/btrfs/transaction.c20
5 files changed, 63 insertions, 43 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index d6e5c19969b0..9873975ce0ee 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -386,6 +386,7 @@ struct btrfs_root {
386 int defrag_running; 386 int defrag_running;
387 int defrag_level; 387 int defrag_level;
388 char *name; 388 char *name;
389 int in_sysfs;
389}; 390};
390 391
391/* 392/*
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index de026d9d9b2b..67d9fd728868 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -374,6 +374,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
374 root->highest_inode = 0; 374 root->highest_inode = 0;
375 root->last_inode_alloc = 0; 375 root->last_inode_alloc = 0;
376 root->name = NULL; 376 root->name = NULL;
377 root->in_sysfs = 0;
377 memset(&root->root_key, 0, sizeof(root->root_key)); 378 memset(&root->root_key, 0, sizeof(root->root_key));
378 memset(&root->root_item, 0, sizeof(root->root_item)); 379 memset(&root->root_item, 0, sizeof(root->root_item));
379 memset(&root->defrag_progress, 0, sizeof(root->defrag_progress)); 380 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 if (!root) 517 if (!root)
517 return NULL; 518 return NULL;
518 519
520 if (root->in_sysfs)
521 return root;
522
519 ret = btrfs_set_root_name(root, name, namelen); 523 ret = btrfs_set_root_name(root, name, namelen);
520 if (ret) { 524 if (ret) {
521 free_extent_buffer(root->node); 525 free_extent_buffer(root->node);
@@ -530,6 +534,7 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
530 kfree(root); 534 kfree(root);
531 return ERR_PTR(ret); 535 return ERR_PTR(ret);
532 } 536 }
537 root->in_sysfs = 1;
533 return root; 538 return root;
534} 539}
535#if 0 540#if 0
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 91c2b27d9689..6137f06091e8 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -751,7 +751,7 @@ again:
751 751
752 if (found_objectid != root_objectid) { 752 if (found_objectid != root_objectid) {
753 total_count = 2; 753 total_count = 2;
754 break; 754 goto out;
755 } 755 }
756 total_count = 1; 756 total_count = 1;
757 path->slots[0]++; 757 path->slots[0]++;
@@ -760,8 +760,6 @@ again:
760 total_count = 0; 760 total_count = 0;
761 goto out; 761 goto out;
762 } 762 }
763 if (total_count > 1)
764 goto out;
765 if (level >= 0 && root->node == count_path->nodes[level]) 763 if (level >= 0 && root->node == count_path->nodes[level])
766 goto out; 764 goto out;
767 level++; 765 level++;
@@ -2109,22 +2107,23 @@ static int relocate_inode_pages(struct inode *inode, u64 start, u64 len)
2109 u64 delalloc_start; 2107 u64 delalloc_start;
2110 u64 existing_delalloc; 2108 u64 existing_delalloc;
2111 unsigned long last_index; 2109 unsigned long last_index;
2112 unsigned long first_index;
2113 unsigned long i; 2110 unsigned long i;
2114 struct page *page; 2111 struct page *page;
2115 struct btrfs_root *root = BTRFS_I(inode)->root; 2112 struct btrfs_root *root = BTRFS_I(inode)->root;
2116 struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; 2113 struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
2117 struct file_ra_state ra; 2114 struct file_ra_state *ra;
2115
2116 ra = kzalloc(sizeof(*ra), GFP_NOFS);
2118 2117
2119 mutex_lock(&inode->i_mutex); 2118 mutex_lock(&inode->i_mutex);
2120 first_index = start >> PAGE_CACHE_SHIFT; 2119 i = start >> PAGE_CACHE_SHIFT;
2121 last_index = (start + len - 1) >> PAGE_CACHE_SHIFT; 2120 last_index = (start + len - 1) >> PAGE_CACHE_SHIFT;
2122 2121
2123 memset(&ra, 0, sizeof(ra)); 2122 file_ra_state_init(ra, inode->i_mapping);
2124 file_ra_state_init(&ra, inode->i_mapping); 2123 btrfs_force_ra(inode->i_mapping, ra, NULL, i, last_index);
2125 btrfs_force_ra(inode->i_mapping, &ra, NULL, first_index, last_index); 2124 kfree(ra);
2126 2125
2127 for (i = first_index; i <= last_index; i++) { 2126 for (; i <= last_index; i++) {
2128 page = grab_cache_page(inode->i_mapping, i); 2127 page = grab_cache_page(inode->i_mapping, i);
2129 if (!page) 2128 if (!page)
2130 goto out_unlock; 2129 goto out_unlock;
@@ -2167,27 +2166,43 @@ out_unlock:
2167 return 0; 2166 return 0;
2168} 2167}
2169 2168
2169/*
2170 * note, this releases the path
2171 */
2170static int relocate_one_reference(struct btrfs_root *extent_root, 2172static int relocate_one_reference(struct btrfs_root *extent_root,
2171 struct btrfs_path *path, 2173 struct btrfs_path *path,
2172 struct btrfs_key *extent_key, 2174 struct btrfs_key *extent_key)
2173 u64 ref_root, u64 ref_gen, u64 ref_objectid,
2174 u64 ref_offset)
2175{ 2175{
2176 struct inode *inode; 2176 struct inode *inode;
2177 struct btrfs_root *found_root; 2177 struct btrfs_root *found_root;
2178 struct btrfs_key root_location; 2178 struct btrfs_key *root_location;
2179 struct btrfs_extent_ref *ref;
2180 u64 ref_root;
2181 u64 ref_gen;
2182 u64 ref_objectid;
2183 u64 ref_offset;
2179 int ret; 2184 int ret;
2180 2185
2181 root_location.objectid = ref_root; 2186 ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
2187 struct btrfs_extent_ref);
2188 ref_root = btrfs_ref_root(path->nodes[0], ref);
2189 ref_gen = btrfs_ref_generation(path->nodes[0], ref);
2190 ref_objectid = btrfs_ref_objectid(path->nodes[0], ref);
2191 ref_offset = btrfs_ref_offset(path->nodes[0], ref);
2192 btrfs_release_path(extent_root, path);
2193
2194 root_location = kmalloc(sizeof(*root_location), GFP_NOFS);
2195 root_location->objectid = ref_root;
2182 if (ref_gen == 0) 2196 if (ref_gen == 0)
2183 root_location.offset = 0; 2197 root_location->offset = 0;
2184 else 2198 else
2185 root_location.offset = (u64)-1; 2199 root_location->offset = (u64)-1;
2186 root_location.type = BTRFS_ROOT_ITEM_KEY; 2200 root_location->type = BTRFS_ROOT_ITEM_KEY;
2187 2201
2188 found_root = btrfs_read_fs_root_no_name(extent_root->fs_info, 2202 found_root = btrfs_read_fs_root_no_name(extent_root->fs_info,
2189 &root_location); 2203 root_location);
2190 BUG_ON(!found_root); 2204 BUG_ON(!found_root);
2205 kfree(root_location);
2191 2206
2192 if (ref_objectid >= BTRFS_FIRST_FREE_OBJECTID) { 2207 if (ref_objectid >= BTRFS_FIRST_FREE_OBJECTID) {
2193 mutex_unlock(&extent_root->fs_info->fs_mutex); 2208 mutex_unlock(&extent_root->fs_info->fs_mutex);
@@ -2259,12 +2274,7 @@ static int relocate_one_extent(struct btrfs_root *extent_root,
2259{ 2274{
2260 struct btrfs_key key; 2275 struct btrfs_key key;
2261 struct btrfs_key found_key; 2276 struct btrfs_key found_key;
2262 struct btrfs_extent_ref *ref;
2263 struct extent_buffer *leaf; 2277 struct extent_buffer *leaf;
2264 u64 ref_root;
2265 u64 ref_gen;
2266 u64 ref_objectid;
2267 u64 ref_offset;
2268 u32 nritems; 2278 u32 nritems;
2269 u32 item_size; 2279 u32 item_size;
2270 int ret = 0; 2280 int ret = 0;
@@ -2297,17 +2307,7 @@ static int relocate_one_extent(struct btrfs_root *extent_root,
2297 key.offset = found_key.offset + 1; 2307 key.offset = found_key.offset + 1;
2298 item_size = btrfs_item_size_nr(leaf, path->slots[0]); 2308 item_size = btrfs_item_size_nr(leaf, path->slots[0]);
2299 2309
2300 ref = btrfs_item_ptr(leaf, path->slots[0], 2310 ret = relocate_one_reference(extent_root, path, extent_key);
2301 struct btrfs_extent_ref);
2302 ref_root = btrfs_ref_root(leaf, ref);
2303 ref_gen = btrfs_ref_generation(leaf, ref);
2304 ref_objectid = btrfs_ref_objectid(leaf, ref);
2305 ref_offset = btrfs_ref_offset(leaf, ref);
2306 btrfs_release_path(extent_root, path);
2307
2308 ret = relocate_one_reference(extent_root, path,
2309 extent_key, ref_root, ref_gen,
2310 ref_objectid, ref_offset);
2311 if (ret) 2311 if (ret)
2312 goto out; 2312 goto out;
2313 } 2313 }
@@ -2354,7 +2354,6 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 new_size)
2354 struct btrfs_path *path; 2354 struct btrfs_path *path;
2355 u64 cur_byte; 2355 u64 cur_byte;
2356 u64 total_found; 2356 u64 total_found;
2357 u64 ptr;
2358 struct btrfs_fs_info *info = root->fs_info; 2357 struct btrfs_fs_info *info = root->fs_info;
2359 struct extent_map_tree *block_group_cache; 2358 struct extent_map_tree *block_group_cache;
2360 struct btrfs_key key; 2359 struct btrfs_key key;
@@ -2377,6 +2376,7 @@ again:
2377 key.offset = 0; 2376 key.offset = 0;
2378 key.type = 0; 2377 key.type = 0;
2379 while(1) { 2378 while(1) {
2379
2380 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 2380 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
2381 if (ret < 0) 2381 if (ret < 0)
2382 goto out; 2382 goto out;
@@ -2441,6 +2441,8 @@ next:
2441 key.offset = 0; 2441 key.offset = 0;
2442 key.type = 0; 2442 key.type = 0;
2443 while(1) { 2443 while(1) {
2444 u64 ptr;
2445
2444 ret = btrfs_search_slot(trans, root, &key, path, -1, 1); 2446 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
2445 if (ret < 0) 2447 if (ret < 0)
2446 goto out; 2448 goto out;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 5003a86510a1..b62f35e862bd 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2108,7 +2108,8 @@ static void btrfs_truncate(struct inode *inode)
2108 btrfs_btree_balance_dirty(root, nr); 2108 btrfs_btree_balance_dirty(root, nr);
2109} 2109}
2110 2110
2111static int create_subvol(struct btrfs_root *root, char *name, int namelen) 2111static int noinline create_subvol(struct btrfs_root *root, char *name,
2112 int namelen)
2112{ 2113{
2113 struct btrfs_trans_handle *trans; 2114 struct btrfs_trans_handle *trans;
2114 struct btrfs_key key; 2115 struct btrfs_key key;
@@ -2492,7 +2493,8 @@ out:
2492 return ret; 2493 return ret;
2493} 2494}
2494 2495
2495static int btrfs_ioctl_snap_create(struct btrfs_root *root, void __user *arg) 2496static int noinline btrfs_ioctl_snap_create(struct btrfs_root *root,
2497 void __user *arg)
2496{ 2498{
2497 struct btrfs_ioctl_vol_args *vol_args; 2499 struct btrfs_ioctl_vol_args *vol_args;
2498 struct btrfs_dir_item *di; 2500 struct btrfs_dir_item *di;
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 1ad611b9f61b..02721eea9a7a 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -481,12 +481,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
481 struct btrfs_transaction *cur_trans; 481 struct btrfs_transaction *cur_trans;
482 struct btrfs_transaction *prev_trans = NULL; 482 struct btrfs_transaction *prev_trans = NULL;
483 struct list_head dirty_fs_roots; 483 struct list_head dirty_fs_roots;
484 struct extent_map_tree pinned_copy; 484 struct extent_map_tree *pinned_copy;
485 DEFINE_WAIT(wait); 485 DEFINE_WAIT(wait);
486 int ret; 486 int ret;
487 487
488 extent_map_tree_init(&pinned_copy,
489 root->fs_info->btree_inode->i_mapping, GFP_NOFS);
490 INIT_LIST_HEAD(&dirty_fs_roots); 488 INIT_LIST_HEAD(&dirty_fs_roots);
491 489
492 mutex_lock(&root->fs_info->trans_mutex); 490 mutex_lock(&root->fs_info->trans_mutex);
@@ -507,6 +505,14 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
507 mutex_lock(&root->fs_info->fs_mutex); 505 mutex_lock(&root->fs_info->fs_mutex);
508 return 0; 506 return 0;
509 } 507 }
508
509 pinned_copy = kmalloc(sizeof(*pinned_copy), GFP_NOFS);
510 if (!pinned_copy)
511 return -ENOMEM;
512
513 extent_map_tree_init(pinned_copy,
514 root->fs_info->btree_inode->i_mapping, GFP_NOFS);
515
510 trans->transaction->in_commit = 1; 516 trans->transaction->in_commit = 1;
511 cur_trans = trans->transaction; 517 cur_trans = trans->transaction;
512 if (cur_trans->list.prev != &root->fs_info->trans_list) { 518 if (cur_trans->list.prev != &root->fs_info->trans_list) {
@@ -568,16 +574,20 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
568 &root->fs_info->super_copy, 0, 574 &root->fs_info->super_copy, 0,
569 sizeof(root->fs_info->super_copy)); 575 sizeof(root->fs_info->super_copy));
570 576
571 btrfs_copy_pinned(root, &pinned_copy); 577 btrfs_copy_pinned(root, pinned_copy);
572 578
573 mutex_unlock(&root->fs_info->trans_mutex); 579 mutex_unlock(&root->fs_info->trans_mutex);
574 mutex_unlock(&root->fs_info->fs_mutex); 580 mutex_unlock(&root->fs_info->fs_mutex);
575 ret = btrfs_write_and_wait_transaction(trans, root); 581 ret = btrfs_write_and_wait_transaction(trans, root);
576 BUG_ON(ret); 582 BUG_ON(ret);
577 write_ctree_super(trans, root); 583 write_ctree_super(trans, root);
584
578 mutex_lock(&root->fs_info->fs_mutex); 585 mutex_lock(&root->fs_info->fs_mutex);
579 btrfs_finish_extent_commit(trans, root, &pinned_copy); 586 btrfs_finish_extent_commit(trans, root, pinned_copy);
580 mutex_lock(&root->fs_info->trans_mutex); 587 mutex_lock(&root->fs_info->trans_mutex);
588
589 kfree(pinned_copy);
590
581 cur_trans->commit_done = 1; 591 cur_trans->commit_done = 1;
582 root->fs_info->last_trans_committed = cur_trans->transid; 592 root->fs_info->last_trans_committed = cur_trans->transid;
583 wake_up(&cur_trans->commit_wait); 593 wake_up(&cur_trans->commit_wait);