diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-02-01 16:35:04 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:00 -0400 |
commit | 80b6794d1153ed91a040d873396efb9bd60969fd (patch) | |
tree | 7e0d6d3eb92c08c494c8fb1438cc4dec7a115e18 /fs | |
parent | ae9d12853b44f4e0c06732166e8e3399ec01a680 (diff) |
Btrfs: Lower stack usage in transaction.c
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/transaction.c | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 3f64d0c7ddb9..e9a0983897f3 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -33,7 +33,7 @@ static struct workqueue_struct *trans_wq; | |||
33 | #define BTRFS_ROOT_TRANS_TAG 0 | 33 | #define BTRFS_ROOT_TRANS_TAG 0 |
34 | #define BTRFS_ROOT_DEFRAG_TAG 1 | 34 | #define BTRFS_ROOT_DEFRAG_TAG 1 |
35 | 35 | ||
36 | static void put_transaction(struct btrfs_transaction *transaction) | 36 | static noinline void put_transaction(struct btrfs_transaction *transaction) |
37 | { | 37 | { |
38 | WARN_ON(transaction->use_count == 0); | 38 | WARN_ON(transaction->use_count == 0); |
39 | transaction->use_count--; | 39 | transaction->use_count--; |
@@ -46,7 +46,7 @@ static void put_transaction(struct btrfs_transaction *transaction) | |||
46 | } | 46 | } |
47 | } | 47 | } |
48 | 48 | ||
49 | static int join_transaction(struct btrfs_root *root) | 49 | static noinline int join_transaction(struct btrfs_root *root) |
50 | { | 50 | { |
51 | struct btrfs_transaction *cur_trans; | 51 | struct btrfs_transaction *cur_trans; |
52 | cur_trans = root->fs_info->running_transaction; | 52 | cur_trans = root->fs_info->running_transaction; |
@@ -82,7 +82,7 @@ static int join_transaction(struct btrfs_root *root) | |||
82 | return 0; | 82 | return 0; |
83 | } | 83 | } |
84 | 84 | ||
85 | static int record_root_in_trans(struct btrfs_root *root) | 85 | static noinline int record_root_in_trans(struct btrfs_root *root) |
86 | { | 86 | { |
87 | u64 running_trans_id = root->fs_info->running_transaction->transid; | 87 | u64 running_trans_id = root->fs_info->running_transaction->transid; |
88 | if (root->ref_cows && root->last_trans < running_trans_id) { | 88 | if (root->ref_cows && root->last_trans < running_trans_id) { |
@@ -225,8 +225,8 @@ int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, | |||
225 | return 0; | 225 | return 0; |
226 | } | 226 | } |
227 | 227 | ||
228 | static int wait_for_commit(struct btrfs_root *root, | 228 | static noinline int wait_for_commit(struct btrfs_root *root, |
229 | struct btrfs_transaction *commit) | 229 | struct btrfs_transaction *commit) |
230 | { | 230 | { |
231 | DEFINE_WAIT(wait); | 231 | DEFINE_WAIT(wait); |
232 | mutex_lock(&root->fs_info->trans_mutex); | 232 | mutex_lock(&root->fs_info->trans_mutex); |
@@ -265,9 +265,9 @@ int btrfs_add_dead_root(struct btrfs_root *root, | |||
265 | return 0; | 265 | return 0; |
266 | } | 266 | } |
267 | 267 | ||
268 | static int add_dirty_roots(struct btrfs_trans_handle *trans, | 268 | static noinline int add_dirty_roots(struct btrfs_trans_handle *trans, |
269 | struct radix_tree_root *radix, | 269 | struct radix_tree_root *radix, |
270 | struct list_head *list) | 270 | struct list_head *list) |
271 | { | 271 | { |
272 | struct dirty_root *dirty; | 272 | struct dirty_root *dirty; |
273 | struct btrfs_root *gang[8]; | 273 | struct btrfs_root *gang[8]; |
@@ -406,8 +406,8 @@ int btrfs_defrag_dirty_roots(struct btrfs_fs_info *info) | |||
406 | return err; | 406 | return err; |
407 | } | 407 | } |
408 | 408 | ||
409 | static int drop_dirty_roots(struct btrfs_root *tree_root, | 409 | static noinline int drop_dirty_roots(struct btrfs_root *tree_root, |
410 | struct list_head *list) | 410 | struct list_head *list) |
411 | { | 411 | { |
412 | struct dirty_root *dirty; | 412 | struct dirty_root *dirty; |
413 | struct btrfs_trans_handle *trans; | 413 | struct btrfs_trans_handle *trans; |
@@ -529,23 +529,28 @@ int btrfs_write_ordered_inodes(struct btrfs_trans_handle *trans, | |||
529 | return 0; | 529 | return 0; |
530 | } | 530 | } |
531 | 531 | ||
532 | static int create_pending_snapshot(struct btrfs_trans_handle *trans, | 532 | static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, |
533 | struct btrfs_fs_info *fs_info, | 533 | struct btrfs_fs_info *fs_info, |
534 | struct btrfs_pending_snapshot *pending) | 534 | struct btrfs_pending_snapshot *pending) |
535 | { | 535 | { |
536 | struct btrfs_key key; | 536 | struct btrfs_key key; |
537 | struct btrfs_root_item new_root_item; | 537 | struct btrfs_root_item *new_root_item; |
538 | struct btrfs_root *tree_root = fs_info->tree_root; | 538 | struct btrfs_root *tree_root = fs_info->tree_root; |
539 | struct btrfs_root *root = pending->root; | 539 | struct btrfs_root *root = pending->root; |
540 | struct extent_buffer *tmp; | 540 | struct extent_buffer *tmp; |
541 | int ret; | 541 | int ret; |
542 | u64 objectid; | 542 | u64 objectid; |
543 | 543 | ||
544 | new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); | ||
545 | if (!new_root_item) { | ||
546 | ret = -ENOMEM; | ||
547 | goto fail; | ||
548 | } | ||
544 | ret = btrfs_find_free_objectid(trans, tree_root, 0, &objectid); | 549 | ret = btrfs_find_free_objectid(trans, tree_root, 0, &objectid); |
545 | if (ret) | 550 | if (ret) |
546 | goto fail; | 551 | goto fail; |
547 | 552 | ||
548 | memcpy(&new_root_item, &root->root_item, sizeof(new_root_item)); | 553 | memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); |
549 | 554 | ||
550 | key.objectid = objectid; | 555 | key.objectid = objectid; |
551 | key.offset = 1; | 556 | key.offset = 1; |
@@ -557,10 +562,10 @@ static int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
557 | 562 | ||
558 | btrfs_copy_root(trans, root, root->node, &tmp, objectid); | 563 | btrfs_copy_root(trans, root, root->node, &tmp, objectid); |
559 | 564 | ||
560 | btrfs_set_root_bytenr(&new_root_item, tmp->start); | 565 | btrfs_set_root_bytenr(new_root_item, tmp->start); |
561 | btrfs_set_root_level(&new_root_item, btrfs_header_level(tmp)); | 566 | btrfs_set_root_level(new_root_item, btrfs_header_level(tmp)); |
562 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, | 567 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, |
563 | &new_root_item); | 568 | new_root_item); |
564 | free_extent_buffer(tmp); | 569 | free_extent_buffer(tmp); |
565 | if (ret) | 570 | if (ret) |
566 | goto fail; | 571 | goto fail; |
@@ -581,11 +586,12 @@ static int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
581 | pending->name, strlen(pending->name), objectid, | 586 | pending->name, strlen(pending->name), objectid, |
582 | root->fs_info->sb->s_root->d_inode->i_ino); | 587 | root->fs_info->sb->s_root->d_inode->i_ino); |
583 | fail: | 588 | fail: |
589 | kfree(new_root_item); | ||
584 | return ret; | 590 | return ret; |
585 | } | 591 | } |
586 | 592 | ||
587 | static int create_pending_snapshots(struct btrfs_trans_handle *trans, | 593 | static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans, |
588 | struct btrfs_fs_info *fs_info) | 594 | struct btrfs_fs_info *fs_info) |
589 | { | 595 | { |
590 | struct btrfs_pending_snapshot *pending; | 596 | struct btrfs_pending_snapshot *pending; |
591 | struct list_head *head = &trans->transaction->pending_snapshots; | 597 | struct list_head *head = &trans->transaction->pending_snapshots; |