diff options
author | liubo <liubo2009@cn.fujitsu.com> | 2011-01-26 01:22:08 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2011-01-28 16:40:36 -0500 |
commit | 2a29edc6b60a5248ccab588e7ba7dad38cef0235 (patch) | |
tree | 45a7939e9e061cb2f06b09ae5f48aa79853e1250 /fs/btrfs/tree-log.c | |
parent | 6b82ce8d824bd46053e46a895876cde39d9026e4 (diff) |
btrfs: fix several uncheck memory allocations
To make btrfs more stable, add several missing necessary memory allocation
checks, and when no memory, return proper errno.
We've checked that some of those -ENOMEM errors will be returned to
userspace, and some will be catched by BUG_ON() in the upper callers,
and none will be ignored silently.
Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r-- | fs/btrfs/tree-log.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 054744ac5719..c25a41d86118 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -338,6 +338,12 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans, | |||
338 | } | 338 | } |
339 | dst_copy = kmalloc(item_size, GFP_NOFS); | 339 | dst_copy = kmalloc(item_size, GFP_NOFS); |
340 | src_copy = kmalloc(item_size, GFP_NOFS); | 340 | src_copy = kmalloc(item_size, GFP_NOFS); |
341 | if (!dst_copy || !src_copy) { | ||
342 | btrfs_release_path(root, path); | ||
343 | kfree(dst_copy); | ||
344 | kfree(src_copy); | ||
345 | return -ENOMEM; | ||
346 | } | ||
341 | 347 | ||
342 | read_extent_buffer(eb, src_copy, src_ptr, item_size); | 348 | read_extent_buffer(eb, src_copy, src_ptr, item_size); |
343 | 349 | ||
@@ -665,6 +671,9 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans, | |||
665 | btrfs_dir_item_key_to_cpu(leaf, di, &location); | 671 | btrfs_dir_item_key_to_cpu(leaf, di, &location); |
666 | name_len = btrfs_dir_name_len(leaf, di); | 672 | name_len = btrfs_dir_name_len(leaf, di); |
667 | name = kmalloc(name_len, GFP_NOFS); | 673 | name = kmalloc(name_len, GFP_NOFS); |
674 | if (!name) | ||
675 | return -ENOMEM; | ||
676 | |||
668 | read_extent_buffer(leaf, name, (unsigned long)(di + 1), name_len); | 677 | read_extent_buffer(leaf, name, (unsigned long)(di + 1), name_len); |
669 | btrfs_release_path(root, path); | 678 | btrfs_release_path(root, path); |
670 | 679 | ||
@@ -744,6 +753,9 @@ static noinline int backref_in_log(struct btrfs_root *log, | |||
744 | int match = 0; | 753 | int match = 0; |
745 | 754 | ||
746 | path = btrfs_alloc_path(); | 755 | path = btrfs_alloc_path(); |
756 | if (!path) | ||
757 | return -ENOMEM; | ||
758 | |||
747 | ret = btrfs_search_slot(NULL, log, key, path, 0, 0); | 759 | ret = btrfs_search_slot(NULL, log, key, path, 0, 0); |
748 | if (ret != 0) | 760 | if (ret != 0) |
749 | goto out; | 761 | goto out; |
@@ -967,6 +979,8 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans, | |||
967 | key.offset = (u64)-1; | 979 | key.offset = (u64)-1; |
968 | 980 | ||
969 | path = btrfs_alloc_path(); | 981 | path = btrfs_alloc_path(); |
982 | if (!path) | ||
983 | return -ENOMEM; | ||
970 | 984 | ||
971 | while (1) { | 985 | while (1) { |
972 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 986 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
@@ -1178,6 +1192,9 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, | |||
1178 | 1192 | ||
1179 | name_len = btrfs_dir_name_len(eb, di); | 1193 | name_len = btrfs_dir_name_len(eb, di); |
1180 | name = kmalloc(name_len, GFP_NOFS); | 1194 | name = kmalloc(name_len, GFP_NOFS); |
1195 | if (!name) | ||
1196 | return -ENOMEM; | ||
1197 | |||
1181 | log_type = btrfs_dir_type(eb, di); | 1198 | log_type = btrfs_dir_type(eb, di); |
1182 | read_extent_buffer(eb, name, (unsigned long)(di + 1), | 1199 | read_extent_buffer(eb, name, (unsigned long)(di + 1), |
1183 | name_len); | 1200 | name_len); |
@@ -1692,6 +1709,8 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, | |||
1692 | root_owner = btrfs_header_owner(parent); | 1709 | root_owner = btrfs_header_owner(parent); |
1693 | 1710 | ||
1694 | next = btrfs_find_create_tree_block(root, bytenr, blocksize); | 1711 | next = btrfs_find_create_tree_block(root, bytenr, blocksize); |
1712 | if (!next) | ||
1713 | return -ENOMEM; | ||
1695 | 1714 | ||
1696 | if (*level == 1) { | 1715 | if (*level == 1) { |
1697 | wc->process_func(root, next, wc, ptr_gen); | 1716 | wc->process_func(root, next, wc, ptr_gen); |
@@ -2194,6 +2213,9 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, | |||
2194 | 2213 | ||
2195 | log = root->log_root; | 2214 | log = root->log_root; |
2196 | path = btrfs_alloc_path(); | 2215 | path = btrfs_alloc_path(); |
2216 | if (!path) | ||
2217 | return -ENOMEM; | ||
2218 | |||
2197 | di = btrfs_lookup_dir_item(trans, log, path, dir->i_ino, | 2219 | di = btrfs_lookup_dir_item(trans, log, path, dir->i_ino, |
2198 | name, name_len, -1); | 2220 | name, name_len, -1); |
2199 | if (IS_ERR(di)) { | 2221 | if (IS_ERR(di)) { |
@@ -2594,6 +2616,9 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, | |||
2594 | 2616 | ||
2595 | ins_data = kmalloc(nr * sizeof(struct btrfs_key) + | 2617 | ins_data = kmalloc(nr * sizeof(struct btrfs_key) + |
2596 | nr * sizeof(u32), GFP_NOFS); | 2618 | nr * sizeof(u32), GFP_NOFS); |
2619 | if (!ins_data) | ||
2620 | return -ENOMEM; | ||
2621 | |||
2597 | ins_sizes = (u32 *)ins_data; | 2622 | ins_sizes = (u32 *)ins_data; |
2598 | ins_keys = (struct btrfs_key *)(ins_data + nr * sizeof(u32)); | 2623 | ins_keys = (struct btrfs_key *)(ins_data + nr * sizeof(u32)); |
2599 | 2624 | ||