diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-05 16:21:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-05 16:21:15 -0400 |
commit | 795d580baec0d5386b83a8b557df47c20810e86b (patch) | |
tree | d0387c37562e9e27a4f43cf7ae425319cbdad359 /fs/btrfs | |
parent | 449cedf099b23a250e7d61982e35555ccb871182 (diff) | |
parent | 109f6aef5fc436f355ad027f4d97bd696df2049a (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
* git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable:
Btrfs: add check for changed leaves in setup_leaf_for_split
Btrfs: create snapshot references in same commit as snapshot
Btrfs: fix small race with delalloc flushing waitqueue's
Btrfs: use add_to_page_cache_lru, use __page_cache_alloc
Btrfs: fix chunk allocate size calculation
Btrfs: kill max_extent mount option
Btrfs: fail to mount if we have problems reading the block groups
Btrfs: check btrfs_get_extent return for IS_ERR()
Btrfs: handle kmalloc() failure in inode lookup ioctl
Btrfs: dereferencing freed memory
Btrfs: Simplify num_stripes's calculation logical for __btrfs_alloc_chunk()
Btrfs: Add error handle for btrfs_search_slot() in btrfs_read_chunk_tree()
Btrfs: Remove unnecessary finish_wait() in wait_current_trans()
Btrfs: add NULL check for do_walk_down()
Btrfs: remove duplicate include in ioctl.c
Fix trivial conflict in fs/btrfs/compression.c due to slab.h include
cleanups.
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/compression.c | 22 | ||||
-rw-r--r-- | fs/btrfs/ctree.c | 4 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 1 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 12 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 23 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 15 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 59 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 7 | ||||
-rw-r--r-- | fs/btrfs/ordered-data.c | 6 | ||||
-rw-r--r-- | fs/btrfs/super.c | 23 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 112 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 10 |
12 files changed, 90 insertions, 204 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 629880ec8ac4..396039b3a8a2 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/swap.h> | 31 | #include <linux/swap.h> |
32 | #include <linux/writeback.h> | 32 | #include <linux/writeback.h> |
33 | #include <linux/bit_spinlock.h> | 33 | #include <linux/bit_spinlock.h> |
34 | #include <linux/pagevec.h> | ||
35 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
36 | #include "compat.h" | 35 | #include "compat.h" |
37 | #include "ctree.h" | 36 | #include "ctree.h" |
@@ -446,7 +445,6 @@ static noinline int add_ra_bio_pages(struct inode *inode, | |||
446 | unsigned long nr_pages = 0; | 445 | unsigned long nr_pages = 0; |
447 | struct extent_map *em; | 446 | struct extent_map *em; |
448 | struct address_space *mapping = inode->i_mapping; | 447 | struct address_space *mapping = inode->i_mapping; |
449 | struct pagevec pvec; | ||
450 | struct extent_map_tree *em_tree; | 448 | struct extent_map_tree *em_tree; |
451 | struct extent_io_tree *tree; | 449 | struct extent_io_tree *tree; |
452 | u64 end; | 450 | u64 end; |
@@ -462,7 +460,6 @@ static noinline int add_ra_bio_pages(struct inode *inode, | |||
462 | 460 | ||
463 | end_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT; | 461 | end_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT; |
464 | 462 | ||
465 | pagevec_init(&pvec, 0); | ||
466 | while (last_offset < compressed_end) { | 463 | while (last_offset < compressed_end) { |
467 | page_index = last_offset >> PAGE_CACHE_SHIFT; | 464 | page_index = last_offset >> PAGE_CACHE_SHIFT; |
468 | 465 | ||
@@ -479,26 +476,17 @@ static noinline int add_ra_bio_pages(struct inode *inode, | |||
479 | goto next; | 476 | goto next; |
480 | } | 477 | } |
481 | 478 | ||
482 | page = alloc_page(mapping_gfp_mask(mapping) & ~__GFP_FS); | 479 | page = __page_cache_alloc(mapping_gfp_mask(mapping) & |
480 | ~__GFP_FS); | ||
483 | if (!page) | 481 | if (!page) |
484 | break; | 482 | break; |
485 | 483 | ||
486 | page->index = page_index; | 484 | if (add_to_page_cache_lru(page, mapping, page_index, |
487 | /* | 485 | GFP_NOFS)) { |
488 | * what we want to do here is call add_to_page_cache_lru, | ||
489 | * but that isn't exported, so we reproduce it here | ||
490 | */ | ||
491 | if (add_to_page_cache(page, mapping, | ||
492 | page->index, GFP_NOFS)) { | ||
493 | page_cache_release(page); | 486 | page_cache_release(page); |
494 | goto next; | 487 | goto next; |
495 | } | 488 | } |
496 | 489 | ||
497 | /* open coding of lru_cache_add, also not exported */ | ||
498 | page_cache_get(page); | ||
499 | if (!pagevec_add(&pvec, page)) | ||
500 | __pagevec_lru_add_file(&pvec); | ||
501 | |||
502 | end = last_offset + PAGE_CACHE_SIZE - 1; | 490 | end = last_offset + PAGE_CACHE_SIZE - 1; |
503 | /* | 491 | /* |
504 | * at this point, we have a locked page in the page cache | 492 | * at this point, we have a locked page in the page cache |
@@ -552,8 +540,6 @@ static noinline int add_ra_bio_pages(struct inode *inode, | |||
552 | next: | 540 | next: |
553 | last_offset += PAGE_CACHE_SIZE; | 541 | last_offset += PAGE_CACHE_SIZE; |
554 | } | 542 | } |
555 | if (pagevec_count(&pvec)) | ||
556 | __pagevec_lru_add_file(&pvec); | ||
557 | return 0; | 543 | return 0; |
558 | } | 544 | } |
559 | 545 | ||
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 8e29260cd0bb..6795a713b205 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -3041,6 +3041,10 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans, | |||
3041 | if (ret > 0 || item_size != btrfs_item_size_nr(leaf, path->slots[0])) | 3041 | if (ret > 0 || item_size != btrfs_item_size_nr(leaf, path->slots[0])) |
3042 | goto err; | 3042 | goto err; |
3043 | 3043 | ||
3044 | /* the leaf has changed, it now has room. return now */ | ||
3045 | if (btrfs_leaf_free_space(root, path->nodes[0]) >= ins_len) | ||
3046 | goto err; | ||
3047 | |||
3044 | if (key.type == BTRFS_EXTENT_DATA_KEY) { | 3048 | if (key.type == BTRFS_EXTENT_DATA_KEY) { |
3045 | fi = btrfs_item_ptr(leaf, path->slots[0], | 3049 | fi = btrfs_item_ptr(leaf, path->slots[0], |
3046 | struct btrfs_file_extent_item); | 3050 | struct btrfs_file_extent_item); |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 8a6518a3f041..746a7248678e 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -835,7 +835,6 @@ struct btrfs_fs_info { | |||
835 | u64 last_trans_log_full_commit; | 835 | u64 last_trans_log_full_commit; |
836 | u64 open_ioctl_trans; | 836 | u64 open_ioctl_trans; |
837 | unsigned long mount_opt; | 837 | unsigned long mount_opt; |
838 | u64 max_extent; | ||
839 | u64 max_inline; | 838 | u64 max_inline; |
840 | u64 alloc_start; | 839 | u64 alloc_start; |
841 | struct btrfs_transaction *running_transaction; | 840 | struct btrfs_transaction *running_transaction; |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index e57ded75d910..e7b8f2c89ccb 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1635,7 +1635,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1635 | atomic_set(&fs_info->async_submit_draining, 0); | 1635 | atomic_set(&fs_info->async_submit_draining, 0); |
1636 | atomic_set(&fs_info->nr_async_bios, 0); | 1636 | atomic_set(&fs_info->nr_async_bios, 0); |
1637 | fs_info->sb = sb; | 1637 | fs_info->sb = sb; |
1638 | fs_info->max_extent = (u64)-1; | ||
1639 | fs_info->max_inline = 8192 * 1024; | 1638 | fs_info->max_inline = 8192 * 1024; |
1640 | fs_info->metadata_ratio = 0; | 1639 | fs_info->metadata_ratio = 0; |
1641 | 1640 | ||
@@ -1923,7 +1922,11 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1923 | 1922 | ||
1924 | csum_root->track_dirty = 1; | 1923 | csum_root->track_dirty = 1; |
1925 | 1924 | ||
1926 | btrfs_read_block_groups(extent_root); | 1925 | ret = btrfs_read_block_groups(extent_root); |
1926 | if (ret) { | ||
1927 | printk(KERN_ERR "Failed to read block groups: %d\n", ret); | ||
1928 | goto fail_block_groups; | ||
1929 | } | ||
1927 | 1930 | ||
1928 | fs_info->generation = generation; | 1931 | fs_info->generation = generation; |
1929 | fs_info->last_trans_committed = generation; | 1932 | fs_info->last_trans_committed = generation; |
@@ -1933,7 +1936,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1933 | fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, | 1936 | fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, |
1934 | "btrfs-cleaner"); | 1937 | "btrfs-cleaner"); |
1935 | if (IS_ERR(fs_info->cleaner_kthread)) | 1938 | if (IS_ERR(fs_info->cleaner_kthread)) |
1936 | goto fail_csum_root; | 1939 | goto fail_block_groups; |
1937 | 1940 | ||
1938 | fs_info->transaction_kthread = kthread_run(transaction_kthread, | 1941 | fs_info->transaction_kthread = kthread_run(transaction_kthread, |
1939 | tree_root, | 1942 | tree_root, |
@@ -2021,7 +2024,8 @@ fail_cleaner: | |||
2021 | filemap_write_and_wait(fs_info->btree_inode->i_mapping); | 2024 | filemap_write_and_wait(fs_info->btree_inode->i_mapping); |
2022 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); | 2025 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); |
2023 | 2026 | ||
2024 | fail_csum_root: | 2027 | fail_block_groups: |
2028 | btrfs_free_block_groups(fs_info); | ||
2025 | free_extent_buffer(csum_root->node); | 2029 | free_extent_buffer(csum_root->node); |
2026 | free_extent_buffer(csum_root->commit_root); | 2030 | free_extent_buffer(csum_root->commit_root); |
2027 | fail_dev_root: | 2031 | fail_dev_root: |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index fa2907d531a2..9e23ffea7f54 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -2677,6 +2677,8 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, | |||
2677 | 2677 | ||
2678 | INIT_LIST_HEAD(&found->block_groups); | 2678 | INIT_LIST_HEAD(&found->block_groups); |
2679 | init_rwsem(&found->groups_sem); | 2679 | init_rwsem(&found->groups_sem); |
2680 | init_waitqueue_head(&found->flush_wait); | ||
2681 | init_waitqueue_head(&found->allocate_wait); | ||
2680 | spin_lock_init(&found->lock); | 2682 | spin_lock_init(&found->lock); |
2681 | found->flags = flags; | 2683 | found->flags = flags; |
2682 | found->total_bytes = total_bytes; | 2684 | found->total_bytes = total_bytes; |
@@ -2847,7 +2849,7 @@ int btrfs_unreserve_metadata_for_delalloc(struct btrfs_root *root, | |||
2847 | } | 2849 | } |
2848 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | 2850 | spin_unlock(&BTRFS_I(inode)->accounting_lock); |
2849 | 2851 | ||
2850 | BTRFS_I(inode)->reserved_extents--; | 2852 | BTRFS_I(inode)->reserved_extents -= num_items; |
2851 | BUG_ON(BTRFS_I(inode)->reserved_extents < 0); | 2853 | BUG_ON(BTRFS_I(inode)->reserved_extents < 0); |
2852 | 2854 | ||
2853 | if (meta_sinfo->bytes_delalloc < num_bytes) { | 2855 | if (meta_sinfo->bytes_delalloc < num_bytes) { |
@@ -2945,12 +2947,10 @@ static void flush_delalloc(struct btrfs_root *root, | |||
2945 | 2947 | ||
2946 | spin_lock(&info->lock); | 2948 | spin_lock(&info->lock); |
2947 | 2949 | ||
2948 | if (!info->flushing) { | 2950 | if (!info->flushing) |
2949 | info->flushing = 1; | 2951 | info->flushing = 1; |
2950 | init_waitqueue_head(&info->flush_wait); | 2952 | else |
2951 | } else { | ||
2952 | wait = true; | 2953 | wait = true; |
2953 | } | ||
2954 | 2954 | ||
2955 | spin_unlock(&info->lock); | 2955 | spin_unlock(&info->lock); |
2956 | 2956 | ||
@@ -3012,7 +3012,6 @@ static int maybe_allocate_chunk(struct btrfs_root *root, | |||
3012 | if (!info->allocating_chunk) { | 3012 | if (!info->allocating_chunk) { |
3013 | info->force_alloc = 1; | 3013 | info->force_alloc = 1; |
3014 | info->allocating_chunk = 1; | 3014 | info->allocating_chunk = 1; |
3015 | init_waitqueue_head(&info->allocate_wait); | ||
3016 | } else { | 3015 | } else { |
3017 | wait = true; | 3016 | wait = true; |
3018 | } | 3017 | } |
@@ -3112,7 +3111,7 @@ again: | |||
3112 | return -ENOSPC; | 3111 | return -ENOSPC; |
3113 | } | 3112 | } |
3114 | 3113 | ||
3115 | BTRFS_I(inode)->reserved_extents++; | 3114 | BTRFS_I(inode)->reserved_extents += num_items; |
3116 | check_force_delalloc(meta_sinfo); | 3115 | check_force_delalloc(meta_sinfo); |
3117 | spin_unlock(&meta_sinfo->lock); | 3116 | spin_unlock(&meta_sinfo->lock); |
3118 | 3117 | ||
@@ -4171,6 +4170,10 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
4171 | ins->offset = 0; | 4170 | ins->offset = 0; |
4172 | 4171 | ||
4173 | space_info = __find_space_info(root->fs_info, data); | 4172 | space_info = __find_space_info(root->fs_info, data); |
4173 | if (!space_info) { | ||
4174 | printk(KERN_ERR "No space info for %d\n", data); | ||
4175 | return -ENOSPC; | ||
4176 | } | ||
4174 | 4177 | ||
4175 | if (orig_root->ref_cows || empty_size) | 4178 | if (orig_root->ref_cows || empty_size) |
4176 | allowed_chunk_alloc = 1; | 4179 | allowed_chunk_alloc = 1; |
@@ -5206,6 +5209,8 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, | |||
5206 | next = btrfs_find_tree_block(root, bytenr, blocksize); | 5209 | next = btrfs_find_tree_block(root, bytenr, blocksize); |
5207 | if (!next) { | 5210 | if (!next) { |
5208 | next = btrfs_find_create_tree_block(root, bytenr, blocksize); | 5211 | next = btrfs_find_create_tree_block(root, bytenr, blocksize); |
5212 | if (!next) | ||
5213 | return -ENOMEM; | ||
5209 | reada = 1; | 5214 | reada = 1; |
5210 | } | 5215 | } |
5211 | btrfs_tree_lock(next); | 5216 | btrfs_tree_lock(next); |
@@ -5418,7 +5423,8 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans, | |||
5418 | if (ret > 0) { | 5423 | if (ret > 0) { |
5419 | path->slots[level]++; | 5424 | path->slots[level]++; |
5420 | continue; | 5425 | continue; |
5421 | } | 5426 | } else if (ret < 0) |
5427 | return ret; | ||
5422 | level = wc->level; | 5428 | level = wc->level; |
5423 | } | 5429 | } |
5424 | return 0; | 5430 | return 0; |
@@ -7370,7 +7376,6 @@ static int find_first_block_group(struct btrfs_root *root, | |||
7370 | } | 7376 | } |
7371 | path->slots[0]++; | 7377 | path->slots[0]++; |
7372 | } | 7378 | } |
7373 | ret = -ENOENT; | ||
7374 | out: | 7379 | out: |
7375 | return ret; | 7380 | return ret; |
7376 | } | 7381 | } |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 0adceb525167..d2d03684fab2 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -2678,33 +2678,20 @@ int extent_readpages(struct extent_io_tree *tree, | |||
2678 | { | 2678 | { |
2679 | struct bio *bio = NULL; | 2679 | struct bio *bio = NULL; |
2680 | unsigned page_idx; | 2680 | unsigned page_idx; |
2681 | struct pagevec pvec; | ||
2682 | unsigned long bio_flags = 0; | 2681 | unsigned long bio_flags = 0; |
2683 | 2682 | ||
2684 | pagevec_init(&pvec, 0); | ||
2685 | for (page_idx = 0; page_idx < nr_pages; page_idx++) { | 2683 | for (page_idx = 0; page_idx < nr_pages; page_idx++) { |
2686 | struct page *page = list_entry(pages->prev, struct page, lru); | 2684 | struct page *page = list_entry(pages->prev, struct page, lru); |
2687 | 2685 | ||
2688 | prefetchw(&page->flags); | 2686 | prefetchw(&page->flags); |
2689 | list_del(&page->lru); | 2687 | list_del(&page->lru); |
2690 | /* | 2688 | if (!add_to_page_cache_lru(page, mapping, |
2691 | * what we want to do here is call add_to_page_cache_lru, | ||
2692 | * but that isn't exported, so we reproduce it here | ||
2693 | */ | ||
2694 | if (!add_to_page_cache(page, mapping, | ||
2695 | page->index, GFP_KERNEL)) { | 2689 | page->index, GFP_KERNEL)) { |
2696 | |||
2697 | /* open coding of lru_cache_add, also not exported */ | ||
2698 | page_cache_get(page); | ||
2699 | if (!pagevec_add(&pvec, page)) | ||
2700 | __pagevec_lru_add_file(&pvec); | ||
2701 | __extent_read_full_page(tree, page, get_extent, | 2690 | __extent_read_full_page(tree, page, get_extent, |
2702 | &bio, 0, &bio_flags); | 2691 | &bio, 0, &bio_flags); |
2703 | } | 2692 | } |
2704 | page_cache_release(page); | 2693 | page_cache_release(page); |
2705 | } | 2694 | } |
2706 | if (pagevec_count(&pvec)) | ||
2707 | __pagevec_lru_add_file(&pvec); | ||
2708 | BUG_ON(!list_empty(pages)); | 2695 | BUG_ON(!list_empty(pages)); |
2709 | if (bio) | 2696 | if (bio) |
2710 | submit_one_bio(READ, bio, 0, bio_flags); | 2697 | submit_one_bio(READ, bio, 0, bio_flags); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 2fe494c84e60..2bfdc641d4e3 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -797,7 +797,7 @@ static noinline int cow_file_range(struct inode *inode, | |||
797 | while (disk_num_bytes > 0) { | 797 | while (disk_num_bytes > 0) { |
798 | unsigned long op; | 798 | unsigned long op; |
799 | 799 | ||
800 | cur_alloc_size = min(disk_num_bytes, root->fs_info->max_extent); | 800 | cur_alloc_size = disk_num_bytes; |
801 | ret = btrfs_reserve_extent(trans, root, cur_alloc_size, | 801 | ret = btrfs_reserve_extent(trans, root, cur_alloc_size, |
802 | root->sectorsize, 0, alloc_hint, | 802 | root->sectorsize, 0, alloc_hint, |
803 | (u64)-1, &ins, 1); | 803 | (u64)-1, &ins, 1); |
@@ -1228,30 +1228,9 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page, | |||
1228 | static int btrfs_split_extent_hook(struct inode *inode, | 1228 | static int btrfs_split_extent_hook(struct inode *inode, |
1229 | struct extent_state *orig, u64 split) | 1229 | struct extent_state *orig, u64 split) |
1230 | { | 1230 | { |
1231 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
1232 | u64 size; | ||
1233 | |||
1234 | if (!(orig->state & EXTENT_DELALLOC)) | 1231 | if (!(orig->state & EXTENT_DELALLOC)) |
1235 | return 0; | 1232 | return 0; |
1236 | 1233 | ||
1237 | size = orig->end - orig->start + 1; | ||
1238 | if (size > root->fs_info->max_extent) { | ||
1239 | u64 num_extents; | ||
1240 | u64 new_size; | ||
1241 | |||
1242 | new_size = orig->end - split + 1; | ||
1243 | num_extents = div64_u64(size + root->fs_info->max_extent - 1, | ||
1244 | root->fs_info->max_extent); | ||
1245 | |||
1246 | /* | ||
1247 | * if we break a large extent up then leave oustanding_extents | ||
1248 | * be, since we've already accounted for the large extent. | ||
1249 | */ | ||
1250 | if (div64_u64(new_size + root->fs_info->max_extent - 1, | ||
1251 | root->fs_info->max_extent) < num_extents) | ||
1252 | return 0; | ||
1253 | } | ||
1254 | |||
1255 | spin_lock(&BTRFS_I(inode)->accounting_lock); | 1234 | spin_lock(&BTRFS_I(inode)->accounting_lock); |
1256 | BTRFS_I(inode)->outstanding_extents++; | 1235 | BTRFS_I(inode)->outstanding_extents++; |
1257 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | 1236 | spin_unlock(&BTRFS_I(inode)->accounting_lock); |
@@ -1269,38 +1248,10 @@ static int btrfs_merge_extent_hook(struct inode *inode, | |||
1269 | struct extent_state *new, | 1248 | struct extent_state *new, |
1270 | struct extent_state *other) | 1249 | struct extent_state *other) |
1271 | { | 1250 | { |
1272 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
1273 | u64 new_size, old_size; | ||
1274 | u64 num_extents; | ||
1275 | |||
1276 | /* not delalloc, ignore it */ | 1251 | /* not delalloc, ignore it */ |
1277 | if (!(other->state & EXTENT_DELALLOC)) | 1252 | if (!(other->state & EXTENT_DELALLOC)) |
1278 | return 0; | 1253 | return 0; |
1279 | 1254 | ||
1280 | old_size = other->end - other->start + 1; | ||
1281 | if (new->start < other->start) | ||
1282 | new_size = other->end - new->start + 1; | ||
1283 | else | ||
1284 | new_size = new->end - other->start + 1; | ||
1285 | |||
1286 | /* we're not bigger than the max, unreserve the space and go */ | ||
1287 | if (new_size <= root->fs_info->max_extent) { | ||
1288 | spin_lock(&BTRFS_I(inode)->accounting_lock); | ||
1289 | BTRFS_I(inode)->outstanding_extents--; | ||
1290 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | ||
1291 | return 0; | ||
1292 | } | ||
1293 | |||
1294 | /* | ||
1295 | * If we grew by another max_extent, just return, we want to keep that | ||
1296 | * reserved amount. | ||
1297 | */ | ||
1298 | num_extents = div64_u64(old_size + root->fs_info->max_extent - 1, | ||
1299 | root->fs_info->max_extent); | ||
1300 | if (div64_u64(new_size + root->fs_info->max_extent - 1, | ||
1301 | root->fs_info->max_extent) > num_extents) | ||
1302 | return 0; | ||
1303 | |||
1304 | spin_lock(&BTRFS_I(inode)->accounting_lock); | 1255 | spin_lock(&BTRFS_I(inode)->accounting_lock); |
1305 | BTRFS_I(inode)->outstanding_extents--; | 1256 | BTRFS_I(inode)->outstanding_extents--; |
1306 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | 1257 | spin_unlock(&BTRFS_I(inode)->accounting_lock); |
@@ -1329,6 +1280,7 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end, | |||
1329 | BTRFS_I(inode)->outstanding_extents++; | 1280 | BTRFS_I(inode)->outstanding_extents++; |
1330 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | 1281 | spin_unlock(&BTRFS_I(inode)->accounting_lock); |
1331 | btrfs_delalloc_reserve_space(root, inode, end - start + 1); | 1282 | btrfs_delalloc_reserve_space(root, inode, end - start + 1); |
1283 | |||
1332 | spin_lock(&root->fs_info->delalloc_lock); | 1284 | spin_lock(&root->fs_info->delalloc_lock); |
1333 | BTRFS_I(inode)->delalloc_bytes += end - start + 1; | 1285 | BTRFS_I(inode)->delalloc_bytes += end - start + 1; |
1334 | root->fs_info->delalloc_bytes += end - start + 1; | 1286 | root->fs_info->delalloc_bytes += end - start + 1; |
@@ -1357,6 +1309,7 @@ static int btrfs_clear_bit_hook(struct inode *inode, | |||
1357 | 1309 | ||
1358 | if (bits & EXTENT_DO_ACCOUNTING) { | 1310 | if (bits & EXTENT_DO_ACCOUNTING) { |
1359 | spin_lock(&BTRFS_I(inode)->accounting_lock); | 1311 | spin_lock(&BTRFS_I(inode)->accounting_lock); |
1312 | WARN_ON(!BTRFS_I(inode)->outstanding_extents); | ||
1360 | BTRFS_I(inode)->outstanding_extents--; | 1313 | BTRFS_I(inode)->outstanding_extents--; |
1361 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | 1314 | spin_unlock(&BTRFS_I(inode)->accounting_lock); |
1362 | btrfs_unreserve_metadata_for_delalloc(root, inode, 1); | 1315 | btrfs_unreserve_metadata_for_delalloc(root, inode, 1); |
@@ -5385,7 +5338,6 @@ free: | |||
5385 | void btrfs_drop_inode(struct inode *inode) | 5338 | void btrfs_drop_inode(struct inode *inode) |
5386 | { | 5339 | { |
5387 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5340 | struct btrfs_root *root = BTRFS_I(inode)->root; |
5388 | |||
5389 | if (inode->i_nlink > 0 && btrfs_root_refs(&root->root_item) == 0) | 5341 | if (inode->i_nlink > 0 && btrfs_root_refs(&root->root_item) == 0) |
5390 | generic_delete_inode(inode); | 5342 | generic_delete_inode(inode); |
5391 | else | 5343 | else |
@@ -5789,18 +5741,15 @@ static int prealloc_file_range(struct inode *inode, u64 start, u64 end, | |||
5789 | struct btrfs_trans_handle *trans; | 5741 | struct btrfs_trans_handle *trans; |
5790 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5742 | struct btrfs_root *root = BTRFS_I(inode)->root; |
5791 | struct btrfs_key ins; | 5743 | struct btrfs_key ins; |
5792 | u64 alloc_size; | ||
5793 | u64 cur_offset = start; | 5744 | u64 cur_offset = start; |
5794 | u64 num_bytes = end - start; | 5745 | u64 num_bytes = end - start; |
5795 | int ret = 0; | 5746 | int ret = 0; |
5796 | u64 i_size; | 5747 | u64 i_size; |
5797 | 5748 | ||
5798 | while (num_bytes > 0) { | 5749 | while (num_bytes > 0) { |
5799 | alloc_size = min(num_bytes, root->fs_info->max_extent); | ||
5800 | |||
5801 | trans = btrfs_start_transaction(root, 1); | 5750 | trans = btrfs_start_transaction(root, 1); |
5802 | 5751 | ||
5803 | ret = btrfs_reserve_extent(trans, root, alloc_size, | 5752 | ret = btrfs_reserve_extent(trans, root, num_bytes, |
5804 | root->sectorsize, 0, alloc_hint, | 5753 | root->sectorsize, 0, alloc_hint, |
5805 | (u64)-1, &ins, 1); | 5754 | (u64)-1, &ins, 1); |
5806 | if (ret) { | 5755 | if (ret) { |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 9b3d73a0fdc8..e84ef60ffe35 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #include "print-tree.h" | 49 | #include "print-tree.h" |
50 | #include "volumes.h" | 50 | #include "volumes.h" |
51 | #include "locking.h" | 51 | #include "locking.h" |
52 | #include "ctree.h" | ||
53 | 52 | ||
54 | /* Mask out flags that are inappropriate for the given type of inode. */ | 53 | /* Mask out flags that are inappropriate for the given type of inode. */ |
55 | static inline __u32 btrfs_mask_flags(umode_t mode, __u32 flags) | 54 | static inline __u32 btrfs_mask_flags(umode_t mode, __u32 flags) |
@@ -512,7 +511,7 @@ static int should_defrag_range(struct inode *inode, u64 start, u64 len, | |||
512 | em = btrfs_get_extent(inode, NULL, 0, start, len, 0); | 511 | em = btrfs_get_extent(inode, NULL, 0, start, len, 0); |
513 | unlock_extent(io_tree, start, start + len - 1, GFP_NOFS); | 512 | unlock_extent(io_tree, start, start + len - 1, GFP_NOFS); |
514 | 513 | ||
515 | if (!em) | 514 | if (IS_ERR(em)) |
516 | return 0; | 515 | return 0; |
517 | } | 516 | } |
518 | 517 | ||
@@ -1213,6 +1212,9 @@ static noinline int btrfs_ioctl_ino_lookup(struct file *file, | |||
1213 | return -EPERM; | 1212 | return -EPERM; |
1214 | 1213 | ||
1215 | args = kmalloc(sizeof(*args), GFP_KERNEL); | 1214 | args = kmalloc(sizeof(*args), GFP_KERNEL); |
1215 | if (!args) | ||
1216 | return -ENOMEM; | ||
1217 | |||
1216 | if (copy_from_user(args, argp, sizeof(*args))) { | 1218 | if (copy_from_user(args, argp, sizeof(*args))) { |
1217 | kfree(args); | 1219 | kfree(args); |
1218 | return -EFAULT; | 1220 | return -EFAULT; |
@@ -1376,6 +1378,7 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp) | |||
1376 | sizeof(*range))) { | 1378 | sizeof(*range))) { |
1377 | ret = -EFAULT; | 1379 | ret = -EFAULT; |
1378 | kfree(range); | 1380 | kfree(range); |
1381 | goto out; | ||
1379 | } | 1382 | } |
1380 | /* compression requires us to start the IO */ | 1383 | /* compression requires us to start the IO */ |
1381 | if ((range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)) { | 1384 | if ((range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)) { |
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index ecb22ff7d1fd..a127c0ebb2dc 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
@@ -302,6 +302,7 @@ static int __btrfs_remove_ordered_extent(struct inode *inode, | |||
302 | struct btrfs_ordered_extent *entry) | 302 | struct btrfs_ordered_extent *entry) |
303 | { | 303 | { |
304 | struct btrfs_ordered_inode_tree *tree; | 304 | struct btrfs_ordered_inode_tree *tree; |
305 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
305 | struct rb_node *node; | 306 | struct rb_node *node; |
306 | 307 | ||
307 | tree = &BTRFS_I(inode)->ordered_tree; | 308 | tree = &BTRFS_I(inode)->ordered_tree; |
@@ -311,12 +312,13 @@ static int __btrfs_remove_ordered_extent(struct inode *inode, | |||
311 | set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags); | 312 | set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags); |
312 | 313 | ||
313 | spin_lock(&BTRFS_I(inode)->accounting_lock); | 314 | spin_lock(&BTRFS_I(inode)->accounting_lock); |
315 | WARN_ON(!BTRFS_I(inode)->outstanding_extents); | ||
314 | BTRFS_I(inode)->outstanding_extents--; | 316 | BTRFS_I(inode)->outstanding_extents--; |
315 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | 317 | spin_unlock(&BTRFS_I(inode)->accounting_lock); |
316 | btrfs_unreserve_metadata_for_delalloc(BTRFS_I(inode)->root, | 318 | btrfs_unreserve_metadata_for_delalloc(BTRFS_I(inode)->root, |
317 | inode, 1); | 319 | inode, 1); |
318 | 320 | ||
319 | spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); | 321 | spin_lock(&root->fs_info->ordered_extent_lock); |
320 | list_del_init(&entry->root_extent_list); | 322 | list_del_init(&entry->root_extent_list); |
321 | 323 | ||
322 | /* | 324 | /* |
@@ -328,7 +330,7 @@ static int __btrfs_remove_ordered_extent(struct inode *inode, | |||
328 | !mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY)) { | 330 | !mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY)) { |
329 | list_del_init(&BTRFS_I(inode)->ordered_operations); | 331 | list_del_init(&BTRFS_I(inode)->ordered_operations); |
330 | } | 332 | } |
331 | spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); | 333 | spin_unlock(&root->fs_info->ordered_extent_lock); |
332 | 334 | ||
333 | return 0; | 335 | return 0; |
334 | } | 336 | } |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 693a664318fe..1866dff0538e 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -65,10 +65,9 @@ static void btrfs_put_super(struct super_block *sb) | |||
65 | 65 | ||
66 | enum { | 66 | enum { |
67 | Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum, | 67 | Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum, |
68 | Opt_nodatacow, Opt_max_extent, Opt_max_inline, Opt_alloc_start, | 68 | Opt_nodatacow, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, Opt_ssd, |
69 | Opt_nobarrier, Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, | 69 | Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress, |
70 | Opt_noacl, Opt_compress, Opt_compress_force, Opt_notreelog, Opt_ratio, | 70 | Opt_compress_force, Opt_notreelog, Opt_ratio, Opt_flushoncommit, |
71 | Opt_flushoncommit, | ||
72 | Opt_discard, Opt_err, | 71 | Opt_discard, Opt_err, |
73 | }; | 72 | }; |
74 | 73 | ||
@@ -80,7 +79,6 @@ static match_table_t tokens = { | |||
80 | {Opt_nodatasum, "nodatasum"}, | 79 | {Opt_nodatasum, "nodatasum"}, |
81 | {Opt_nodatacow, "nodatacow"}, | 80 | {Opt_nodatacow, "nodatacow"}, |
82 | {Opt_nobarrier, "nobarrier"}, | 81 | {Opt_nobarrier, "nobarrier"}, |
83 | {Opt_max_extent, "max_extent=%s"}, | ||
84 | {Opt_max_inline, "max_inline=%s"}, | 82 | {Opt_max_inline, "max_inline=%s"}, |
85 | {Opt_alloc_start, "alloc_start=%s"}, | 83 | {Opt_alloc_start, "alloc_start=%s"}, |
86 | {Opt_thread_pool, "thread_pool=%d"}, | 84 | {Opt_thread_pool, "thread_pool=%d"}, |
@@ -189,18 +187,6 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
189 | info->thread_pool_size); | 187 | info->thread_pool_size); |
190 | } | 188 | } |
191 | break; | 189 | break; |
192 | case Opt_max_extent: | ||
193 | num = match_strdup(&args[0]); | ||
194 | if (num) { | ||
195 | info->max_extent = memparse(num, NULL); | ||
196 | kfree(num); | ||
197 | |||
198 | info->max_extent = max_t(u64, | ||
199 | info->max_extent, root->sectorsize); | ||
200 | printk(KERN_INFO "btrfs: max_extent at %llu\n", | ||
201 | (unsigned long long)info->max_extent); | ||
202 | } | ||
203 | break; | ||
204 | case Opt_max_inline: | 190 | case Opt_max_inline: |
205 | num = match_strdup(&args[0]); | 191 | num = match_strdup(&args[0]); |
206 | if (num) { | 192 | if (num) { |
@@ -530,9 +516,6 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
530 | seq_puts(seq, ",nodatacow"); | 516 | seq_puts(seq, ",nodatacow"); |
531 | if (btrfs_test_opt(root, NOBARRIER)) | 517 | if (btrfs_test_opt(root, NOBARRIER)) |
532 | seq_puts(seq, ",nobarrier"); | 518 | seq_puts(seq, ",nobarrier"); |
533 | if (info->max_extent != (u64)-1) | ||
534 | seq_printf(seq, ",max_extent=%llu", | ||
535 | (unsigned long long)info->max_extent); | ||
536 | if (info->max_inline != 8192 * 1024) | 519 | if (info->max_inline != 8192 * 1024) |
537 | seq_printf(seq, ",max_inline=%llu", | 520 | seq_printf(seq, ",max_inline=%llu", |
538 | (unsigned long long)info->max_inline); | 521 | (unsigned long long)info->max_inline); |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index c0d0e3e7bc63..2cb116099b90 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -148,18 +148,13 @@ static void wait_current_trans(struct btrfs_root *root) | |||
148 | while (1) { | 148 | while (1) { |
149 | prepare_to_wait(&root->fs_info->transaction_wait, &wait, | 149 | prepare_to_wait(&root->fs_info->transaction_wait, &wait, |
150 | TASK_UNINTERRUPTIBLE); | 150 | TASK_UNINTERRUPTIBLE); |
151 | if (cur_trans->blocked) { | 151 | if (!cur_trans->blocked) |
152 | mutex_unlock(&root->fs_info->trans_mutex); | ||
153 | schedule(); | ||
154 | mutex_lock(&root->fs_info->trans_mutex); | ||
155 | finish_wait(&root->fs_info->transaction_wait, | ||
156 | &wait); | ||
157 | } else { | ||
158 | finish_wait(&root->fs_info->transaction_wait, | ||
159 | &wait); | ||
160 | break; | 152 | break; |
161 | } | 153 | mutex_unlock(&root->fs_info->trans_mutex); |
154 | schedule(); | ||
155 | mutex_lock(&root->fs_info->trans_mutex); | ||
162 | } | 156 | } |
157 | finish_wait(&root->fs_info->transaction_wait, &wait); | ||
163 | put_transaction(cur_trans); | 158 | put_transaction(cur_trans); |
164 | } | 159 | } |
165 | } | 160 | } |
@@ -761,10 +756,17 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
761 | struct btrfs_root_item *new_root_item; | 756 | struct btrfs_root_item *new_root_item; |
762 | struct btrfs_root *tree_root = fs_info->tree_root; | 757 | struct btrfs_root *tree_root = fs_info->tree_root; |
763 | struct btrfs_root *root = pending->root; | 758 | struct btrfs_root *root = pending->root; |
759 | struct btrfs_root *parent_root; | ||
760 | struct inode *parent_inode; | ||
764 | struct extent_buffer *tmp; | 761 | struct extent_buffer *tmp; |
765 | struct extent_buffer *old; | 762 | struct extent_buffer *old; |
766 | int ret; | 763 | int ret; |
767 | u64 objectid; | 764 | u64 objectid; |
765 | int namelen; | ||
766 | u64 index = 0; | ||
767 | |||
768 | parent_inode = pending->dentry->d_parent->d_inode; | ||
769 | parent_root = BTRFS_I(parent_inode)->root; | ||
768 | 770 | ||
769 | new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); | 771 | new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); |
770 | if (!new_root_item) { | 772 | if (!new_root_item) { |
@@ -775,79 +777,59 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
775 | if (ret) | 777 | if (ret) |
776 | goto fail; | 778 | goto fail; |
777 | 779 | ||
778 | record_root_in_trans(trans, root); | ||
779 | btrfs_set_root_last_snapshot(&root->root_item, trans->transid); | ||
780 | memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); | ||
781 | |||
782 | key.objectid = objectid; | 780 | key.objectid = objectid; |
783 | /* record when the snapshot was created in key.offset */ | 781 | /* record when the snapshot was created in key.offset */ |
784 | key.offset = trans->transid; | 782 | key.offset = trans->transid; |
785 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); | 783 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); |
786 | 784 | ||
787 | old = btrfs_lock_root_node(root); | ||
788 | btrfs_cow_block(trans, root, old, NULL, 0, &old); | ||
789 | btrfs_set_lock_blocking(old); | ||
790 | |||
791 | btrfs_copy_root(trans, root, old, &tmp, objectid); | ||
792 | btrfs_tree_unlock(old); | ||
793 | free_extent_buffer(old); | ||
794 | |||
795 | btrfs_set_root_node(new_root_item, tmp); | ||
796 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, | ||
797 | new_root_item); | ||
798 | btrfs_tree_unlock(tmp); | ||
799 | free_extent_buffer(tmp); | ||
800 | if (ret) | ||
801 | goto fail; | ||
802 | |||
803 | key.offset = (u64)-1; | ||
804 | memcpy(&pending->root_key, &key, sizeof(key)); | 785 | memcpy(&pending->root_key, &key, sizeof(key)); |
805 | fail: | 786 | pending->root_key.offset = (u64)-1; |
806 | kfree(new_root_item); | ||
807 | return ret; | ||
808 | } | ||
809 | |||
810 | static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info, | ||
811 | struct btrfs_pending_snapshot *pending) | ||
812 | { | ||
813 | int ret; | ||
814 | int namelen; | ||
815 | u64 index = 0; | ||
816 | struct btrfs_trans_handle *trans; | ||
817 | struct inode *parent_inode; | ||
818 | struct btrfs_root *parent_root; | ||
819 | |||
820 | parent_inode = pending->dentry->d_parent->d_inode; | ||
821 | parent_root = BTRFS_I(parent_inode)->root; | ||
822 | trans = btrfs_join_transaction(parent_root, 1); | ||
823 | 787 | ||
788 | record_root_in_trans(trans, parent_root); | ||
824 | /* | 789 | /* |
825 | * insert the directory item | 790 | * insert the directory item |
826 | */ | 791 | */ |
827 | namelen = strlen(pending->name); | 792 | namelen = strlen(pending->name); |
828 | ret = btrfs_set_inode_index(parent_inode, &index); | 793 | ret = btrfs_set_inode_index(parent_inode, &index); |
794 | BUG_ON(ret); | ||
829 | ret = btrfs_insert_dir_item(trans, parent_root, | 795 | ret = btrfs_insert_dir_item(trans, parent_root, |
830 | pending->name, namelen, | 796 | pending->name, namelen, |
831 | parent_inode->i_ino, | 797 | parent_inode->i_ino, |
832 | &pending->root_key, BTRFS_FT_DIR, index); | 798 | &pending->root_key, BTRFS_FT_DIR, index); |
833 | 799 | BUG_ON(ret); | |
834 | if (ret) | ||
835 | goto fail; | ||
836 | 800 | ||
837 | btrfs_i_size_write(parent_inode, parent_inode->i_size + namelen * 2); | 801 | btrfs_i_size_write(parent_inode, parent_inode->i_size + namelen * 2); |
838 | ret = btrfs_update_inode(trans, parent_root, parent_inode); | 802 | ret = btrfs_update_inode(trans, parent_root, parent_inode); |
839 | BUG_ON(ret); | 803 | BUG_ON(ret); |
840 | 804 | ||
805 | record_root_in_trans(trans, root); | ||
806 | btrfs_set_root_last_snapshot(&root->root_item, trans->transid); | ||
807 | memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); | ||
808 | |||
809 | old = btrfs_lock_root_node(root); | ||
810 | btrfs_cow_block(trans, root, old, NULL, 0, &old); | ||
811 | btrfs_set_lock_blocking(old); | ||
812 | |||
813 | btrfs_copy_root(trans, root, old, &tmp, objectid); | ||
814 | btrfs_tree_unlock(old); | ||
815 | free_extent_buffer(old); | ||
816 | |||
817 | btrfs_set_root_node(new_root_item, tmp); | ||
818 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, | ||
819 | new_root_item); | ||
820 | BUG_ON(ret); | ||
821 | btrfs_tree_unlock(tmp); | ||
822 | free_extent_buffer(tmp); | ||
823 | |||
841 | ret = btrfs_add_root_ref(trans, parent_root->fs_info->tree_root, | 824 | ret = btrfs_add_root_ref(trans, parent_root->fs_info->tree_root, |
842 | pending->root_key.objectid, | 825 | pending->root_key.objectid, |
843 | parent_root->root_key.objectid, | 826 | parent_root->root_key.objectid, |
844 | parent_inode->i_ino, index, pending->name, | 827 | parent_inode->i_ino, index, pending->name, |
845 | namelen); | 828 | namelen); |
846 | |||
847 | BUG_ON(ret); | 829 | BUG_ON(ret); |
848 | 830 | ||
849 | fail: | 831 | fail: |
850 | btrfs_end_transaction(trans, fs_info->fs_root); | 832 | kfree(new_root_item); |
851 | return ret; | 833 | return ret; |
852 | } | 834 | } |
853 | 835 | ||
@@ -868,25 +850,6 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans, | |||
868 | return 0; | 850 | return 0; |
869 | } | 851 | } |
870 | 852 | ||
871 | static noinline int finish_pending_snapshots(struct btrfs_trans_handle *trans, | ||
872 | struct btrfs_fs_info *fs_info) | ||
873 | { | ||
874 | struct btrfs_pending_snapshot *pending; | ||
875 | struct list_head *head = &trans->transaction->pending_snapshots; | ||
876 | int ret; | ||
877 | |||
878 | while (!list_empty(head)) { | ||
879 | pending = list_entry(head->next, | ||
880 | struct btrfs_pending_snapshot, list); | ||
881 | ret = finish_pending_snapshot(fs_info, pending); | ||
882 | BUG_ON(ret); | ||
883 | list_del(&pending->list); | ||
884 | kfree(pending->name); | ||
885 | kfree(pending); | ||
886 | } | ||
887 | return 0; | ||
888 | } | ||
889 | |||
890 | static void update_super_roots(struct btrfs_root *root) | 853 | static void update_super_roots(struct btrfs_root *root) |
891 | { | 854 | { |
892 | struct btrfs_root_item *root_item; | 855 | struct btrfs_root_item *root_item; |
@@ -1098,9 +1061,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1098 | 1061 | ||
1099 | btrfs_finish_extent_commit(trans, root); | 1062 | btrfs_finish_extent_commit(trans, root); |
1100 | 1063 | ||
1101 | /* do the directory inserts of any pending snapshot creations */ | ||
1102 | finish_pending_snapshots(trans, root->fs_info); | ||
1103 | |||
1104 | mutex_lock(&root->fs_info->trans_mutex); | 1064 | mutex_lock(&root->fs_info->trans_mutex); |
1105 | 1065 | ||
1106 | cur_trans->commit_done = 1; | 1066 | cur_trans->commit_done = 1; |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 1692ec9cd7b0..aa7dc36dac78 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -2199,9 +2199,9 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, | |||
2199 | min_stripes = 2; | 2199 | min_stripes = 2; |
2200 | } | 2200 | } |
2201 | if (type & (BTRFS_BLOCK_GROUP_RAID1)) { | 2201 | if (type & (BTRFS_BLOCK_GROUP_RAID1)) { |
2202 | num_stripes = min_t(u64, 2, fs_devices->rw_devices); | 2202 | if (fs_devices->rw_devices < 2) |
2203 | if (num_stripes < 2) | ||
2204 | return -ENOSPC; | 2203 | return -ENOSPC; |
2204 | num_stripes = 2; | ||
2205 | min_stripes = 2; | 2205 | min_stripes = 2; |
2206 | } | 2206 | } |
2207 | if (type & (BTRFS_BLOCK_GROUP_RAID10)) { | 2207 | if (type & (BTRFS_BLOCK_GROUP_RAID10)) { |
@@ -2245,8 +2245,10 @@ again: | |||
2245 | do_div(calc_size, stripe_len); | 2245 | do_div(calc_size, stripe_len); |
2246 | calc_size *= stripe_len; | 2246 | calc_size *= stripe_len; |
2247 | } | 2247 | } |
2248 | |||
2248 | /* we don't want tiny stripes */ | 2249 | /* we don't want tiny stripes */ |
2249 | calc_size = max_t(u64, min_stripe_size, calc_size); | 2250 | if (!looped) |
2251 | calc_size = max_t(u64, min_stripe_size, calc_size); | ||
2250 | 2252 | ||
2251 | do_div(calc_size, stripe_len); | 2253 | do_div(calc_size, stripe_len); |
2252 | calc_size *= stripe_len; | 2254 | calc_size *= stripe_len; |
@@ -3390,6 +3392,8 @@ int btrfs_read_chunk_tree(struct btrfs_root *root) | |||
3390 | key.type = 0; | 3392 | key.type = 0; |
3391 | again: | 3393 | again: |
3392 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 3394 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
3395 | if (ret < 0) | ||
3396 | goto error; | ||
3393 | while (1) { | 3397 | while (1) { |
3394 | leaf = path->nodes[0]; | 3398 | leaf = path->nodes[0]; |
3395 | slot = path->slots[0]; | 3399 | slot = path->slots[0]; |