aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-06-25 11:42:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-06-25 11:42:31 -0400
commitb971712afc8dd0de38e943ea9d904fe8c8aff956 (patch)
tree7ee96a965438d82705d39e4c13d84468a92a9e40
parentca83a55c9fe20b45a26101853a772e08aff90dcb (diff)
parentb7f67055d2df9b8f68f02e49d256ee3973999bd2 (diff)
Merge branch 'for-linus-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason: "I have a two part pull this time because one of the patches Dave Sterba collected needed to be against v4.7-rc2 or higher (we used rc4). I try to make my for-linus-xx branch testable on top of the last major so we can hand fixes to people on the list more easily, so I've split this pull in two. This first part has some fixes and two performance improvements that we've been testing for some time. Josef's two performance fixes are most notable. The transid tracking patch makes a big improvement on pretty much every workload" * 'for-linus-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: Btrfs: Force stripesize to the value of sectorsize btrfs: fix disk_i_size update bug when fallocate() fails Btrfs: fix error handling in map_private_extent_buffer Btrfs: fix error return code in btrfs_init_test_fs() Btrfs: don't do nocow check unless we have to btrfs: fix deadlock in delayed_ref_async_start Btrfs: track transid for delayed ref flushing
-rw-r--r--fs/btrfs/ctree.c6
-rw-r--r--fs/btrfs/ctree.h2
-rw-r--r--fs/btrfs/disk-io.c6
-rw-r--r--fs/btrfs/extent-tree.c15
-rw-r--r--fs/btrfs/extent_io.c7
-rw-r--r--fs/btrfs/file.c44
-rw-r--r--fs/btrfs/inode.c1
-rw-r--r--fs/btrfs/ordered-data.c3
-rw-r--r--fs/btrfs/tests/btrfs-tests.c2
-rw-r--r--fs/btrfs/transaction.c3
-rw-r--r--fs/btrfs/volumes.c4
11 files changed, 57 insertions, 36 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 6276add8538a..a85cf7d23309 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1786,10 +1786,12 @@ static noinline int generic_bin_search(struct extent_buffer *eb,
1786 if (!err) { 1786 if (!err) {
1787 tmp = (struct btrfs_disk_key *)(kaddr + offset - 1787 tmp = (struct btrfs_disk_key *)(kaddr + offset -
1788 map_start); 1788 map_start);
1789 } else { 1789 } else if (err == 1) {
1790 read_extent_buffer(eb, &unaligned, 1790 read_extent_buffer(eb, &unaligned,
1791 offset, sizeof(unaligned)); 1791 offset, sizeof(unaligned));
1792 tmp = &unaligned; 1792 tmp = &unaligned;
1793 } else {
1794 return err;
1793 } 1795 }
1794 1796
1795 } else { 1797 } else {
@@ -2830,6 +2832,8 @@ cow_done:
2830 } 2832 }
2831 2833
2832 ret = key_search(b, key, level, &prev_cmp, &slot); 2834 ret = key_search(b, key, level, &prev_cmp, &slot);
2835 if (ret < 0)
2836 goto done;
2833 2837
2834 if (level != 0) { 2838 if (level != 0) {
2835 int dec = 0; 2839 int dec = 0;
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 101c3cfd3f7c..4274a7bfdaed 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2518,7 +2518,7 @@ void btrfs_put_block_group(struct btrfs_block_group_cache *cache);
2518int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, 2518int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
2519 struct btrfs_root *root, unsigned long count); 2519 struct btrfs_root *root, unsigned long count);
2520int btrfs_async_run_delayed_refs(struct btrfs_root *root, 2520int btrfs_async_run_delayed_refs(struct btrfs_root *root,
2521 unsigned long count, int wait); 2521 unsigned long count, u64 transid, int wait);
2522int btrfs_lookup_data_extent(struct btrfs_root *root, u64 start, u64 len); 2522int btrfs_lookup_data_extent(struct btrfs_root *root, u64 start, u64 len);
2523int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, 2523int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
2524 struct btrfs_root *root, u64 bytenr, 2524 struct btrfs_root *root, u64 bytenr,
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 54cca7a1572b..60ce1190307b 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2806,7 +2806,7 @@ int open_ctree(struct super_block *sb,
2806 2806
2807 nodesize = btrfs_super_nodesize(disk_super); 2807 nodesize = btrfs_super_nodesize(disk_super);
2808 sectorsize = btrfs_super_sectorsize(disk_super); 2808 sectorsize = btrfs_super_sectorsize(disk_super);
2809 stripesize = btrfs_super_stripesize(disk_super); 2809 stripesize = sectorsize;
2810 fs_info->dirty_metadata_batch = nodesize * (1 + ilog2(nr_cpu_ids)); 2810 fs_info->dirty_metadata_batch = nodesize * (1 + ilog2(nr_cpu_ids));
2811 fs_info->delalloc_batch = sectorsize * 512 * (1 + ilog2(nr_cpu_ids)); 2811 fs_info->delalloc_batch = sectorsize * 512 * (1 + ilog2(nr_cpu_ids));
2812 2812
@@ -4133,9 +4133,7 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
4133 btrfs_super_bytes_used(sb)); 4133 btrfs_super_bytes_used(sb));
4134 ret = -EINVAL; 4134 ret = -EINVAL;
4135 } 4135 }
4136 if (!is_power_of_2(btrfs_super_stripesize(sb)) || 4136 if (!is_power_of_2(btrfs_super_stripesize(sb))) {
4137 ((btrfs_super_stripesize(sb) != sectorsize) &&
4138 (btrfs_super_stripesize(sb) != 4096))) {
4139 btrfs_err(fs_info, "invalid stripesize %u", 4137 btrfs_err(fs_info, "invalid stripesize %u",
4140 btrfs_super_stripesize(sb)); 4138 btrfs_super_stripesize(sb));
4141 ret = -EINVAL; 4139 ret = -EINVAL;
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 29e5d000bbee..82b912a293ab 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2835,6 +2835,7 @@ int btrfs_should_throttle_delayed_refs(struct btrfs_trans_handle *trans,
2835 2835
2836struct async_delayed_refs { 2836struct async_delayed_refs {
2837 struct btrfs_root *root; 2837 struct btrfs_root *root;
2838 u64 transid;
2838 int count; 2839 int count;
2839 int error; 2840 int error;
2840 int sync; 2841 int sync;
@@ -2850,6 +2851,10 @@ static void delayed_ref_async_start(struct btrfs_work *work)
2850 2851
2851 async = container_of(work, struct async_delayed_refs, work); 2852 async = container_of(work, struct async_delayed_refs, work);
2852 2853
2854 /* if the commit is already started, we don't need to wait here */
2855 if (btrfs_transaction_blocked(async->root->fs_info))
2856 goto done;
2857
2853 trans = btrfs_join_transaction(async->root); 2858 trans = btrfs_join_transaction(async->root);
2854 if (IS_ERR(trans)) { 2859 if (IS_ERR(trans)) {
2855 async->error = PTR_ERR(trans); 2860 async->error = PTR_ERR(trans);
@@ -2861,10 +2866,15 @@ static void delayed_ref_async_start(struct btrfs_work *work)
2861 * wait on delayed refs 2866 * wait on delayed refs
2862 */ 2867 */
2863 trans->sync = true; 2868 trans->sync = true;
2869
2870 /* Don't bother flushing if we got into a different transaction */
2871 if (trans->transid > async->transid)
2872 goto end;
2873
2864 ret = btrfs_run_delayed_refs(trans, async->root, async->count); 2874 ret = btrfs_run_delayed_refs(trans, async->root, async->count);
2865 if (ret) 2875 if (ret)
2866 async->error = ret; 2876 async->error = ret;
2867 2877end:
2868 ret = btrfs_end_transaction(trans, async->root); 2878 ret = btrfs_end_transaction(trans, async->root);
2869 if (ret && !async->error) 2879 if (ret && !async->error)
2870 async->error = ret; 2880 async->error = ret;
@@ -2876,7 +2886,7 @@ done:
2876} 2886}
2877 2887
2878int btrfs_async_run_delayed_refs(struct btrfs_root *root, 2888int btrfs_async_run_delayed_refs(struct btrfs_root *root,
2879 unsigned long count, int wait) 2889 unsigned long count, u64 transid, int wait)
2880{ 2890{
2881 struct async_delayed_refs *async; 2891 struct async_delayed_refs *async;
2882 int ret; 2892 int ret;
@@ -2888,6 +2898,7 @@ int btrfs_async_run_delayed_refs(struct btrfs_root *root,
2888 async->root = root->fs_info->tree_root; 2898 async->root = root->fs_info->tree_root;
2889 async->count = count; 2899 async->count = count;
2890 async->error = 0; 2900 async->error = 0;
2901 async->transid = transid;
2891 if (wait) 2902 if (wait)
2892 async->sync = 1; 2903 async->sync = 1;
2893 else 2904 else
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index aaee3ef55ed8..75533adef998 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -5342,6 +5342,11 @@ int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dstv,
5342 return ret; 5342 return ret;
5343} 5343}
5344 5344
5345/*
5346 * return 0 if the item is found within a page.
5347 * return 1 if the item spans two pages.
5348 * return -EINVAL otherwise.
5349 */
5345int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, 5350int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start,
5346 unsigned long min_len, char **map, 5351 unsigned long min_len, char **map,
5347 unsigned long *map_start, 5352 unsigned long *map_start,
@@ -5356,7 +5361,7 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start,
5356 PAGE_SHIFT; 5361 PAGE_SHIFT;
5357 5362
5358 if (i != end_i) 5363 if (i != end_i)
5359 return -EINVAL; 5364 return 1;
5360 5365
5361 if (i == 0) { 5366 if (i == 0) {
5362 offset = start_offset; 5367 offset = start_offset;
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index e0c9bd3fb02d..2234e88cf674 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1534,30 +1534,30 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
1534 reserve_bytes = round_up(write_bytes + sector_offset, 1534 reserve_bytes = round_up(write_bytes + sector_offset,
1535 root->sectorsize); 1535 root->sectorsize);
1536 1536
1537 if ((BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
1538 BTRFS_INODE_PREALLOC)) &&
1539 check_can_nocow(inode, pos, &write_bytes) > 0) {
1540 /*
1541 * For nodata cow case, no need to reserve
1542 * data space.
1543 */
1544 only_release_metadata = true;
1545 /*
1546 * our prealloc extent may be smaller than
1547 * write_bytes, so scale down.
1548 */
1549 num_pages = DIV_ROUND_UP(write_bytes + offset,
1550 PAGE_SIZE);
1551 reserve_bytes = round_up(write_bytes + sector_offset,
1552 root->sectorsize);
1553 goto reserve_metadata;
1554 }
1555
1556 ret = btrfs_check_data_free_space(inode, pos, write_bytes); 1537 ret = btrfs_check_data_free_space(inode, pos, write_bytes);
1557 if (ret < 0) 1538 if (ret < 0) {
1558 break; 1539 if ((BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
1540 BTRFS_INODE_PREALLOC)) &&
1541 check_can_nocow(inode, pos, &write_bytes) > 0) {
1542 /*
1543 * For nodata cow case, no need to reserve
1544 * data space.
1545 */
1546 only_release_metadata = true;
1547 /*
1548 * our prealloc extent may be smaller than
1549 * write_bytes, so scale down.
1550 */
1551 num_pages = DIV_ROUND_UP(write_bytes + offset,
1552 PAGE_SIZE);
1553 reserve_bytes = round_up(write_bytes +
1554 sector_offset,
1555 root->sectorsize);
1556 } else {
1557 break;
1558 }
1559 }
1559 1560
1560reserve_metadata:
1561 ret = btrfs_delalloc_reserve_metadata(inode, reserve_bytes); 1561 ret = btrfs_delalloc_reserve_metadata(inode, reserve_bytes);
1562 if (ret) { 1562 if (ret) {
1563 if (!only_release_metadata) 1563 if (!only_release_metadata)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index d2be95cfb6d1..49d467d3e62e 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4558,6 +4558,7 @@ delete:
4558 BUG_ON(ret); 4558 BUG_ON(ret);
4559 if (btrfs_should_throttle_delayed_refs(trans, root)) 4559 if (btrfs_should_throttle_delayed_refs(trans, root))
4560 btrfs_async_run_delayed_refs(root, 4560 btrfs_async_run_delayed_refs(root,
4561 trans->transid,
4561 trans->delayed_ref_updates * 2, 0); 4562 trans->delayed_ref_updates * 2, 0);
4562 if (be_nice) { 4563 if (be_nice) {
4563 if (truncate_space_check(trans, root, 4564 if (truncate_space_check(trans, root,
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index e96634a725c3..aca8264f4a49 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -968,6 +968,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
968 struct rb_node *prev = NULL; 968 struct rb_node *prev = NULL;
969 struct btrfs_ordered_extent *test; 969 struct btrfs_ordered_extent *test;
970 int ret = 1; 970 int ret = 1;
971 u64 orig_offset = offset;
971 972
972 spin_lock_irq(&tree->lock); 973 spin_lock_irq(&tree->lock);
973 if (ordered) { 974 if (ordered) {
@@ -983,7 +984,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
983 984
984 /* truncate file */ 985 /* truncate file */
985 if (disk_i_size > i_size) { 986 if (disk_i_size > i_size) {
986 BTRFS_I(inode)->disk_i_size = i_size; 987 BTRFS_I(inode)->disk_i_size = orig_offset;
987 ret = 0; 988 ret = 0;
988 goto out; 989 goto out;
989 } 990 }
diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c
index 10eb249ef891..02223f3f78f4 100644
--- a/fs/btrfs/tests/btrfs-tests.c
+++ b/fs/btrfs/tests/btrfs-tests.c
@@ -68,7 +68,7 @@ int btrfs_init_test_fs(void)
68 if (IS_ERR(test_mnt)) { 68 if (IS_ERR(test_mnt)) {
69 printk(KERN_ERR "btrfs: cannot mount test file system\n"); 69 printk(KERN_ERR "btrfs: cannot mount test file system\n");
70 unregister_filesystem(&test_type); 70 unregister_filesystem(&test_type);
71 return ret; 71 return PTR_ERR(test_mnt);
72 } 72 }
73 return 0; 73 return 0;
74} 74}
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 765845742fde..948aa186b353 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -818,6 +818,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
818{ 818{
819 struct btrfs_transaction *cur_trans = trans->transaction; 819 struct btrfs_transaction *cur_trans = trans->transaction;
820 struct btrfs_fs_info *info = root->fs_info; 820 struct btrfs_fs_info *info = root->fs_info;
821 u64 transid = trans->transid;
821 unsigned long cur = trans->delayed_ref_updates; 822 unsigned long cur = trans->delayed_ref_updates;
822 int lock = (trans->type != TRANS_JOIN_NOLOCK); 823 int lock = (trans->type != TRANS_JOIN_NOLOCK);
823 int err = 0; 824 int err = 0;
@@ -905,7 +906,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
905 906
906 kmem_cache_free(btrfs_trans_handle_cachep, trans); 907 kmem_cache_free(btrfs_trans_handle_cachep, trans);
907 if (must_run_delayed_refs) { 908 if (must_run_delayed_refs) {
908 btrfs_async_run_delayed_refs(root, cur, 909 btrfs_async_run_delayed_refs(root, cur, transid,
909 must_run_delayed_refs == 1); 910 must_run_delayed_refs == 1);
910 } 911 }
911 return err; 912 return err;
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 2f631b58ae00..589f128173b1 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4694,12 +4694,12 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
4694 4694
4695 if (type & BTRFS_BLOCK_GROUP_RAID5) { 4695 if (type & BTRFS_BLOCK_GROUP_RAID5) {
4696 raid_stripe_len = find_raid56_stripe_len(ndevs - 1, 4696 raid_stripe_len = find_raid56_stripe_len(ndevs - 1,
4697 btrfs_super_stripesize(info->super_copy)); 4697 extent_root->stripesize);
4698 data_stripes = num_stripes - 1; 4698 data_stripes = num_stripes - 1;
4699 } 4699 }
4700 if (type & BTRFS_BLOCK_GROUP_RAID6) { 4700 if (type & BTRFS_BLOCK_GROUP_RAID6) {
4701 raid_stripe_len = find_raid56_stripe_len(ndevs - 2, 4701 raid_stripe_len = find_raid56_stripe_len(ndevs - 2,
4702 btrfs_super_stripesize(info->super_copy)); 4702 extent_root->stripesize);
4703 data_stripes = num_stripes - 2; 4703 data_stripes = num_stripes - 2;
4704 } 4704 }
4705 4705