diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-27 16:57:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-27 16:57:12 -0400 |
commit | a0c3061093c8b49facef95dc09a618c6e0d17cb5 (patch) | |
tree | 1d6ff7c06134b71a8bd0721395386e82e46e60c8 /fs/btrfs/relocation.c | |
parent | 10799db60cbc4f990dd69eb49883477095c66af7 (diff) | |
parent | 174ba50915b08dcfd07c8b5fb795b46a165fa09a (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: (58 commits)
Btrfs: use the device_list_mutex during write_dev_supers
Btrfs: setup free ino caching in a more asynchronous way
btrfs scrub: don't coalesce pages that are logically discontiguous
Btrfs: return -ENOMEM in clear_extent_bit
Btrfs: add mount -o auto_defrag
Btrfs: using rcu lock in the reader side of devices list
Btrfs: drop unnecessary device lock
Btrfs: fix the race between remove dev and alloc chunk
Btrfs: fix the race between reading and updating devices
Btrfs: fix bh leak on __btrfs_open_devices path
Btrfs: fix unsafe usage of merge_state
Btrfs: allocate extent state and check the result properly
fs/btrfs: Add missing btrfs_free_path
Btrfs: check return value of btrfs_inc_extent_ref()
Btrfs: return error to caller if read_one_inode() fails
Btrfs: BUG_ON is deleted from the caller of btrfs_truncate_item & btrfs_extend_item
Btrfs: return error code to caller when btrfs_del_item fails
Btrfs: return error code to caller when btrfs_previous_item fails
btrfs: fix typo 'testeing' -> 'testing'
btrfs: typo: 'btrfS' -> 'btrfs'
...
Diffstat (limited to 'fs/btrfs/relocation.c')
-rw-r--r-- | fs/btrfs/relocation.c | 67 |
1 files changed, 35 insertions, 32 deletions
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index f340f7c99d09..ca38eca70af0 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "btrfs_inode.h" | 30 | #include "btrfs_inode.h" |
31 | #include "async-thread.h" | 31 | #include "async-thread.h" |
32 | #include "free-space-cache.h" | 32 | #include "free-space-cache.h" |
33 | #include "inode-map.h" | ||
33 | 34 | ||
34 | /* | 35 | /* |
35 | * backref_node, mapping_node and tree_block start with this | 36 | * backref_node, mapping_node and tree_block start with this |
@@ -507,6 +508,7 @@ static int update_backref_cache(struct btrfs_trans_handle *trans, | |||
507 | return 1; | 508 | return 1; |
508 | } | 509 | } |
509 | 510 | ||
511 | |||
510 | static int should_ignore_root(struct btrfs_root *root) | 512 | static int should_ignore_root(struct btrfs_root *root) |
511 | { | 513 | { |
512 | struct btrfs_root *reloc_root; | 514 | struct btrfs_root *reloc_root; |
@@ -529,7 +531,6 @@ static int should_ignore_root(struct btrfs_root *root) | |||
529 | */ | 531 | */ |
530 | return 1; | 532 | return 1; |
531 | } | 533 | } |
532 | |||
533 | /* | 534 | /* |
534 | * find reloc tree by address of tree root | 535 | * find reloc tree by address of tree root |
535 | */ | 536 | */ |
@@ -961,7 +962,7 @@ again: | |||
961 | lower = upper; | 962 | lower = upper; |
962 | upper = NULL; | 963 | upper = NULL; |
963 | } | 964 | } |
964 | btrfs_release_path(root, path2); | 965 | btrfs_release_path(path2); |
965 | next: | 966 | next: |
966 | if (ptr < end) { | 967 | if (ptr < end) { |
967 | ptr += btrfs_extent_inline_ref_size(key.type); | 968 | ptr += btrfs_extent_inline_ref_size(key.type); |
@@ -974,7 +975,7 @@ next: | |||
974 | if (ptr >= end) | 975 | if (ptr >= end) |
975 | path1->slots[0]++; | 976 | path1->slots[0]++; |
976 | } | 977 | } |
977 | btrfs_release_path(rc->extent_root, path1); | 978 | btrfs_release_path(path1); |
978 | 979 | ||
979 | cur->checked = 1; | 980 | cur->checked = 1; |
980 | WARN_ON(exist); | 981 | WARN_ON(exist); |
@@ -1409,9 +1410,9 @@ again: | |||
1409 | prev = node; | 1410 | prev = node; |
1410 | entry = rb_entry(node, struct btrfs_inode, rb_node); | 1411 | entry = rb_entry(node, struct btrfs_inode, rb_node); |
1411 | 1412 | ||
1412 | if (objectid < entry->vfs_inode.i_ino) | 1413 | if (objectid < btrfs_ino(&entry->vfs_inode)) |
1413 | node = node->rb_left; | 1414 | node = node->rb_left; |
1414 | else if (objectid > entry->vfs_inode.i_ino) | 1415 | else if (objectid > btrfs_ino(&entry->vfs_inode)) |
1415 | node = node->rb_right; | 1416 | node = node->rb_right; |
1416 | else | 1417 | else |
1417 | break; | 1418 | break; |
@@ -1419,7 +1420,7 @@ again: | |||
1419 | if (!node) { | 1420 | if (!node) { |
1420 | while (prev) { | 1421 | while (prev) { |
1421 | entry = rb_entry(prev, struct btrfs_inode, rb_node); | 1422 | entry = rb_entry(prev, struct btrfs_inode, rb_node); |
1422 | if (objectid <= entry->vfs_inode.i_ino) { | 1423 | if (objectid <= btrfs_ino(&entry->vfs_inode)) { |
1423 | node = prev; | 1424 | node = prev; |
1424 | break; | 1425 | break; |
1425 | } | 1426 | } |
@@ -1434,7 +1435,7 @@ again: | |||
1434 | return inode; | 1435 | return inode; |
1435 | } | 1436 | } |
1436 | 1437 | ||
1437 | objectid = entry->vfs_inode.i_ino + 1; | 1438 | objectid = btrfs_ino(&entry->vfs_inode) + 1; |
1438 | if (cond_resched_lock(&root->inode_lock)) | 1439 | if (cond_resched_lock(&root->inode_lock)) |
1439 | goto again; | 1440 | goto again; |
1440 | 1441 | ||
@@ -1470,7 +1471,7 @@ static int get_new_location(struct inode *reloc_inode, u64 *new_bytenr, | |||
1470 | return -ENOMEM; | 1471 | return -ENOMEM; |
1471 | 1472 | ||
1472 | bytenr -= BTRFS_I(reloc_inode)->index_cnt; | 1473 | bytenr -= BTRFS_I(reloc_inode)->index_cnt; |
1473 | ret = btrfs_lookup_file_extent(NULL, root, path, reloc_inode->i_ino, | 1474 | ret = btrfs_lookup_file_extent(NULL, root, path, btrfs_ino(reloc_inode), |
1474 | bytenr, 0); | 1475 | bytenr, 0); |
1475 | if (ret < 0) | 1476 | if (ret < 0) |
1476 | goto out; | 1477 | goto out; |
@@ -1558,11 +1559,11 @@ int replace_file_extents(struct btrfs_trans_handle *trans, | |||
1558 | if (first) { | 1559 | if (first) { |
1559 | inode = find_next_inode(root, key.objectid); | 1560 | inode = find_next_inode(root, key.objectid); |
1560 | first = 0; | 1561 | first = 0; |
1561 | } else if (inode && inode->i_ino < key.objectid) { | 1562 | } else if (inode && btrfs_ino(inode) < key.objectid) { |
1562 | btrfs_add_delayed_iput(inode); | 1563 | btrfs_add_delayed_iput(inode); |
1563 | inode = find_next_inode(root, key.objectid); | 1564 | inode = find_next_inode(root, key.objectid); |
1564 | } | 1565 | } |
1565 | if (inode && inode->i_ino == key.objectid) { | 1566 | if (inode && btrfs_ino(inode) == key.objectid) { |
1566 | end = key.offset + | 1567 | end = key.offset + |
1567 | btrfs_file_extent_num_bytes(leaf, fi); | 1568 | btrfs_file_extent_num_bytes(leaf, fi); |
1568 | WARN_ON(!IS_ALIGNED(key.offset, | 1569 | WARN_ON(!IS_ALIGNED(key.offset, |
@@ -1749,7 +1750,7 @@ again: | |||
1749 | 1750 | ||
1750 | btrfs_node_key_to_cpu(path->nodes[level], &key, | 1751 | btrfs_node_key_to_cpu(path->nodes[level], &key, |
1751 | path->slots[level]); | 1752 | path->slots[level]); |
1752 | btrfs_release_path(src, path); | 1753 | btrfs_release_path(path); |
1753 | 1754 | ||
1754 | path->lowest_level = level; | 1755 | path->lowest_level = level; |
1755 | ret = btrfs_search_slot(trans, src, &key, path, 0, 1); | 1756 | ret = btrfs_search_slot(trans, src, &key, path, 0, 1); |
@@ -1893,6 +1894,7 @@ static int invalidate_extent_cache(struct btrfs_root *root, | |||
1893 | struct inode *inode = NULL; | 1894 | struct inode *inode = NULL; |
1894 | u64 objectid; | 1895 | u64 objectid; |
1895 | u64 start, end; | 1896 | u64 start, end; |
1897 | u64 ino; | ||
1896 | 1898 | ||
1897 | objectid = min_key->objectid; | 1899 | objectid = min_key->objectid; |
1898 | while (1) { | 1900 | while (1) { |
@@ -1905,17 +1907,18 @@ static int invalidate_extent_cache(struct btrfs_root *root, | |||
1905 | inode = find_next_inode(root, objectid); | 1907 | inode = find_next_inode(root, objectid); |
1906 | if (!inode) | 1908 | if (!inode) |
1907 | break; | 1909 | break; |
1910 | ino = btrfs_ino(inode); | ||
1908 | 1911 | ||
1909 | if (inode->i_ino > max_key->objectid) { | 1912 | if (ino > max_key->objectid) { |
1910 | iput(inode); | 1913 | iput(inode); |
1911 | break; | 1914 | break; |
1912 | } | 1915 | } |
1913 | 1916 | ||
1914 | objectid = inode->i_ino + 1; | 1917 | objectid = ino + 1; |
1915 | if (!S_ISREG(inode->i_mode)) | 1918 | if (!S_ISREG(inode->i_mode)) |
1916 | continue; | 1919 | continue; |
1917 | 1920 | ||
1918 | if (unlikely(min_key->objectid == inode->i_ino)) { | 1921 | if (unlikely(min_key->objectid == ino)) { |
1919 | if (min_key->type > BTRFS_EXTENT_DATA_KEY) | 1922 | if (min_key->type > BTRFS_EXTENT_DATA_KEY) |
1920 | continue; | 1923 | continue; |
1921 | if (min_key->type < BTRFS_EXTENT_DATA_KEY) | 1924 | if (min_key->type < BTRFS_EXTENT_DATA_KEY) |
@@ -1928,7 +1931,7 @@ static int invalidate_extent_cache(struct btrfs_root *root, | |||
1928 | start = 0; | 1931 | start = 0; |
1929 | } | 1932 | } |
1930 | 1933 | ||
1931 | if (unlikely(max_key->objectid == inode->i_ino)) { | 1934 | if (unlikely(max_key->objectid == ino)) { |
1932 | if (max_key->type < BTRFS_EXTENT_DATA_KEY) | 1935 | if (max_key->type < BTRFS_EXTENT_DATA_KEY) |
1933 | continue; | 1936 | continue; |
1934 | if (max_key->type > BTRFS_EXTENT_DATA_KEY) { | 1937 | if (max_key->type > BTRFS_EXTENT_DATA_KEY) { |
@@ -2496,7 +2499,7 @@ static int do_relocation(struct btrfs_trans_handle *trans, | |||
2496 | path->locks[upper->level] = 0; | 2499 | path->locks[upper->level] = 0; |
2497 | 2500 | ||
2498 | slot = path->slots[upper->level]; | 2501 | slot = path->slots[upper->level]; |
2499 | btrfs_release_path(NULL, path); | 2502 | btrfs_release_path(path); |
2500 | } else { | 2503 | } else { |
2501 | ret = btrfs_bin_search(upper->eb, key, upper->level, | 2504 | ret = btrfs_bin_search(upper->eb, key, upper->level, |
2502 | &slot); | 2505 | &slot); |
@@ -2737,7 +2740,7 @@ static int relocate_tree_block(struct btrfs_trans_handle *trans, | |||
2737 | } else { | 2740 | } else { |
2738 | path->lowest_level = node->level; | 2741 | path->lowest_level = node->level; |
2739 | ret = btrfs_search_slot(trans, root, key, path, 0, 1); | 2742 | ret = btrfs_search_slot(trans, root, key, path, 0, 1); |
2740 | btrfs_release_path(root, path); | 2743 | btrfs_release_path(path); |
2741 | if (ret > 0) | 2744 | if (ret > 0) |
2742 | ret = 0; | 2745 | ret = 0; |
2743 | } | 2746 | } |
@@ -2870,7 +2873,7 @@ int setup_extent_mapping(struct inode *inode, u64 start, u64 end, | |||
2870 | struct extent_map *em; | 2873 | struct extent_map *em; |
2871 | int ret = 0; | 2874 | int ret = 0; |
2872 | 2875 | ||
2873 | em = alloc_extent_map(GFP_NOFS); | 2876 | em = alloc_extent_map(); |
2874 | if (!em) | 2877 | if (!em) |
2875 | return -ENOMEM; | 2878 | return -ENOMEM; |
2876 | 2879 | ||
@@ -3119,7 +3122,7 @@ static int add_tree_block(struct reloc_control *rc, | |||
3119 | #endif | 3122 | #endif |
3120 | } | 3123 | } |
3121 | 3124 | ||
3122 | btrfs_release_path(rc->extent_root, path); | 3125 | btrfs_release_path(path); |
3123 | 3126 | ||
3124 | BUG_ON(level == -1); | 3127 | BUG_ON(level == -1); |
3125 | 3128 | ||
@@ -3220,7 +3223,7 @@ static int delete_block_group_cache(struct btrfs_fs_info *fs_info, | |||
3220 | key.offset = 0; | 3223 | key.offset = 0; |
3221 | 3224 | ||
3222 | inode = btrfs_iget(fs_info->sb, &key, root, NULL); | 3225 | inode = btrfs_iget(fs_info->sb, &key, root, NULL); |
3223 | if (!inode || IS_ERR(inode) || is_bad_inode(inode)) { | 3226 | if (IS_ERR_OR_NULL(inode) || is_bad_inode(inode)) { |
3224 | if (inode && !IS_ERR(inode)) | 3227 | if (inode && !IS_ERR(inode)) |
3225 | iput(inode); | 3228 | iput(inode); |
3226 | return -ENOENT; | 3229 | return -ENOENT; |
@@ -3505,7 +3508,7 @@ int add_data_references(struct reloc_control *rc, | |||
3505 | } | 3508 | } |
3506 | path->slots[0]++; | 3509 | path->slots[0]++; |
3507 | } | 3510 | } |
3508 | btrfs_release_path(rc->extent_root, path); | 3511 | btrfs_release_path(path); |
3509 | if (err) | 3512 | if (err) |
3510 | free_block_list(blocks); | 3513 | free_block_list(blocks); |
3511 | return err; | 3514 | return err; |
@@ -3568,7 +3571,7 @@ next: | |||
3568 | EXTENT_DIRTY); | 3571 | EXTENT_DIRTY); |
3569 | 3572 | ||
3570 | if (ret == 0 && start <= key.objectid) { | 3573 | if (ret == 0 && start <= key.objectid) { |
3571 | btrfs_release_path(rc->extent_root, path); | 3574 | btrfs_release_path(path); |
3572 | rc->search_start = end + 1; | 3575 | rc->search_start = end + 1; |
3573 | } else { | 3576 | } else { |
3574 | rc->search_start = key.objectid + key.offset; | 3577 | rc->search_start = key.objectid + key.offset; |
@@ -3576,7 +3579,7 @@ next: | |||
3576 | return 0; | 3579 | return 0; |
3577 | } | 3580 | } |
3578 | } | 3581 | } |
3579 | btrfs_release_path(rc->extent_root, path); | 3582 | btrfs_release_path(path); |
3580 | return ret; | 3583 | return ret; |
3581 | } | 3584 | } |
3582 | 3585 | ||
@@ -3713,7 +3716,7 @@ restart: | |||
3713 | flags = BTRFS_EXTENT_FLAG_DATA; | 3716 | flags = BTRFS_EXTENT_FLAG_DATA; |
3714 | 3717 | ||
3715 | if (path_change) { | 3718 | if (path_change) { |
3716 | btrfs_release_path(rc->extent_root, path); | 3719 | btrfs_release_path(path); |
3717 | 3720 | ||
3718 | path->search_commit_root = 1; | 3721 | path->search_commit_root = 1; |
3719 | path->skip_locking = 1; | 3722 | path->skip_locking = 1; |
@@ -3736,7 +3739,7 @@ restart: | |||
3736 | (flags & BTRFS_EXTENT_FLAG_DATA)) { | 3739 | (flags & BTRFS_EXTENT_FLAG_DATA)) { |
3737 | ret = add_data_references(rc, &key, path, &blocks); | 3740 | ret = add_data_references(rc, &key, path, &blocks); |
3738 | } else { | 3741 | } else { |
3739 | btrfs_release_path(rc->extent_root, path); | 3742 | btrfs_release_path(path); |
3740 | ret = 0; | 3743 | ret = 0; |
3741 | } | 3744 | } |
3742 | if (ret < 0) { | 3745 | if (ret < 0) { |
@@ -3799,7 +3802,7 @@ restart: | |||
3799 | } | 3802 | } |
3800 | } | 3803 | } |
3801 | 3804 | ||
3802 | btrfs_release_path(rc->extent_root, path); | 3805 | btrfs_release_path(path); |
3803 | clear_extent_bits(&rc->processed_blocks, 0, (u64)-1, EXTENT_DIRTY, | 3806 | clear_extent_bits(&rc->processed_blocks, 0, (u64)-1, EXTENT_DIRTY, |
3804 | GFP_NOFS); | 3807 | GFP_NOFS); |
3805 | 3808 | ||
@@ -3867,7 +3870,7 @@ static int __insert_orphan_inode(struct btrfs_trans_handle *trans, | |||
3867 | btrfs_set_inode_flags(leaf, item, BTRFS_INODE_NOCOMPRESS | | 3870 | btrfs_set_inode_flags(leaf, item, BTRFS_INODE_NOCOMPRESS | |
3868 | BTRFS_INODE_PREALLOC); | 3871 | BTRFS_INODE_PREALLOC); |
3869 | btrfs_mark_buffer_dirty(leaf); | 3872 | btrfs_mark_buffer_dirty(leaf); |
3870 | btrfs_release_path(root, path); | 3873 | btrfs_release_path(path); |
3871 | out: | 3874 | out: |
3872 | btrfs_free_path(path); | 3875 | btrfs_free_path(path); |
3873 | return ret; | 3876 | return ret; |
@@ -3897,7 +3900,7 @@ struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info, | |||
3897 | if (IS_ERR(trans)) | 3900 | if (IS_ERR(trans)) |
3898 | return ERR_CAST(trans); | 3901 | return ERR_CAST(trans); |
3899 | 3902 | ||
3900 | err = btrfs_find_free_objectid(trans, root, objectid, &objectid); | 3903 | err = btrfs_find_free_objectid(root, &objectid); |
3901 | if (err) | 3904 | if (err) |
3902 | goto out; | 3905 | goto out; |
3903 | 3906 | ||
@@ -3935,7 +3938,7 @@ static struct reloc_control *alloc_reloc_control(void) | |||
3935 | INIT_LIST_HEAD(&rc->reloc_roots); | 3938 | INIT_LIST_HEAD(&rc->reloc_roots); |
3936 | backref_cache_init(&rc->backref_cache); | 3939 | backref_cache_init(&rc->backref_cache); |
3937 | mapping_tree_init(&rc->reloc_root_tree); | 3940 | mapping_tree_init(&rc->reloc_root_tree); |
3938 | extent_io_tree_init(&rc->processed_blocks, NULL, GFP_NOFS); | 3941 | extent_io_tree_init(&rc->processed_blocks, NULL); |
3939 | return rc; | 3942 | return rc; |
3940 | } | 3943 | } |
3941 | 3944 | ||
@@ -4109,7 +4112,7 @@ int btrfs_recover_relocation(struct btrfs_root *root) | |||
4109 | } | 4112 | } |
4110 | leaf = path->nodes[0]; | 4113 | leaf = path->nodes[0]; |
4111 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); | 4114 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); |
4112 | btrfs_release_path(root->fs_info->tree_root, path); | 4115 | btrfs_release_path(path); |
4113 | 4116 | ||
4114 | if (key.objectid != BTRFS_TREE_RELOC_OBJECTID || | 4117 | if (key.objectid != BTRFS_TREE_RELOC_OBJECTID || |
4115 | key.type != BTRFS_ROOT_ITEM_KEY) | 4118 | key.type != BTRFS_ROOT_ITEM_KEY) |
@@ -4141,7 +4144,7 @@ int btrfs_recover_relocation(struct btrfs_root *root) | |||
4141 | 4144 | ||
4142 | key.offset--; | 4145 | key.offset--; |
4143 | } | 4146 | } |
4144 | btrfs_release_path(root->fs_info->tree_root, path); | 4147 | btrfs_release_path(path); |
4145 | 4148 | ||
4146 | if (list_empty(&reloc_roots)) | 4149 | if (list_empty(&reloc_roots)) |
4147 | goto out; | 4150 | goto out; |
@@ -4242,7 +4245,7 @@ int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len) | |||
4242 | 4245 | ||
4243 | disk_bytenr = file_pos + BTRFS_I(inode)->index_cnt; | 4246 | disk_bytenr = file_pos + BTRFS_I(inode)->index_cnt; |
4244 | ret = btrfs_lookup_csums_range(root->fs_info->csum_root, disk_bytenr, | 4247 | ret = btrfs_lookup_csums_range(root->fs_info->csum_root, disk_bytenr, |
4245 | disk_bytenr + len - 1, &list); | 4248 | disk_bytenr + len - 1, &list, 0); |
4246 | 4249 | ||
4247 | while (!list_empty(&list)) { | 4250 | while (!list_empty(&list)) { |
4248 | sums = list_entry(list.next, struct btrfs_ordered_sum, list); | 4251 | sums = list_entry(list.next, struct btrfs_ordered_sum, list); |