diff options
-rw-r--r-- | fs/btrfs/ctree.h | 1 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 5 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 74 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 6 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 20 |
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 | */ | ||
2170 | static int relocate_one_reference(struct btrfs_root *extent_root, | 2172 | static 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 | ||
2111 | static int create_subvol(struct btrfs_root *root, char *name, int namelen) | 2111 | static 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 | ||
2495 | static int btrfs_ioctl_snap_create(struct btrfs_root *root, void __user *arg) | 2496 | static 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); |