aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-12-18 16:25:45 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:58 -0400
commit4aec2b52327b3a3a20faa3f1af3102c0d97c7c92 (patch)
treef17d84355d64dd42c17462069b00f271f920e4a0 /fs/btrfs/ctree.c
parent6da6abae027e2dbc59bca5f4168b0760f25068c7 (diff)
kmalloc a few large stack objects in the btrfs_ioctl path
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 585f279d1112..7f764455f26e 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -80,10 +80,14 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
80 int ret = 0; 80 int ret = 0;
81 int level; 81 int level;
82 struct btrfs_key first_key; 82 struct btrfs_key first_key;
83 struct btrfs_root new_root; 83 struct btrfs_root *new_root;
84 84
85 memcpy(&new_root, root, sizeof(new_root)); 85 new_root = kmalloc(sizeof(*new_root), GFP_NOFS);
86 new_root.root_key.objectid = new_root_objectid; 86 if (!new_root)
87 return -ENOMEM;
88
89 memcpy(new_root, root, sizeof(*new_root));
90 new_root->root_key.objectid = new_root_objectid;
87 91
88 WARN_ON(root->ref_cows && trans->transid != 92 WARN_ON(root->ref_cows && trans->transid !=
89 root->fs_info->running_transaction->transid); 93 root->fs_info->running_transaction->transid);
@@ -99,12 +103,14 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
99 } else { 103 } else {
100 first_key.objectid = 0; 104 first_key.objectid = 0;
101 } 105 }
102 cow = __btrfs_alloc_free_block(trans, &new_root, buf->len, 106 cow = __btrfs_alloc_free_block(trans, new_root, buf->len,
103 new_root_objectid, 107 new_root_objectid,
104 trans->transid, first_key.objectid, 108 trans->transid, first_key.objectid,
105 level, buf->start, 0); 109 level, buf->start, 0);
106 if (IS_ERR(cow)) 110 if (IS_ERR(cow)) {
111 kfree(new_root);
107 return PTR_ERR(cow); 112 return PTR_ERR(cow);
113 }
108 114
109 copy_extent_buffer(cow, buf, 0, 0, cow->len); 115 copy_extent_buffer(cow, buf, 0, 0, cow->len);
110 btrfs_set_header_bytenr(cow, cow->start); 116 btrfs_set_header_bytenr(cow, cow->start);
@@ -112,7 +118,9 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
112 btrfs_set_header_owner(cow, new_root_objectid); 118 btrfs_set_header_owner(cow, new_root_objectid);
113 119
114 WARN_ON(btrfs_header_generation(buf) > trans->transid); 120 WARN_ON(btrfs_header_generation(buf) > trans->transid);
115 ret = btrfs_inc_ref(trans, &new_root, buf); 121 ret = btrfs_inc_ref(trans, new_root, buf);
122 kfree(new_root);
123
116 if (ret) 124 if (ret)
117 return ret; 125 return ret;
118 126