Skip to content

Commit b971712

Browse files
committed
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
2 parents ca83a55 + b7f6705 commit b971712

11 files changed

Lines changed: 57 additions & 36 deletions

File tree

fs/btrfs/ctree.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1786,10 +1786,12 @@ static noinline int generic_bin_search(struct extent_buffer *eb,
17861786
if (!err) {
17871787
tmp = (struct btrfs_disk_key *)(kaddr + offset -
17881788
map_start);
1789-
} else {
1789+
} else if (err == 1) {
17901790
read_extent_buffer(eb, &unaligned,
17911791
offset, sizeof(unaligned));
17921792
tmp = &unaligned;
1793+
} else {
1794+
return err;
17931795
}
17941796

17951797
} else {
@@ -2830,6 +2832,8 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
28302832
}
28312833

28322834
ret = key_search(b, key, level, &prev_cmp, &slot);
2835+
if (ret < 0)
2836+
goto done;
28332837

28342838
if (level != 0) {
28352839
int dec = 0;

fs/btrfs/ctree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2518,7 +2518,7 @@ void btrfs_put_block_group(struct btrfs_block_group_cache *cache);
25182518
int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
25192519
struct btrfs_root *root, unsigned long count);
25202520
int btrfs_async_run_delayed_refs(struct btrfs_root *root,
2521-
unsigned long count, int wait);
2521+
unsigned long count, u64 transid, int wait);
25222522
int btrfs_lookup_data_extent(struct btrfs_root *root, u64 start, u64 len);
25232523
int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
25242524
struct btrfs_root *root, u64 bytenr,

fs/btrfs/disk-io.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2806,7 +2806,7 @@ int open_ctree(struct super_block *sb,
28062806

28072807
nodesize = btrfs_super_nodesize(disk_super);
28082808
sectorsize = btrfs_super_sectorsize(disk_super);
2809-
stripesize = btrfs_super_stripesize(disk_super);
2809+
stripesize = sectorsize;
28102810
fs_info->dirty_metadata_batch = nodesize * (1 + ilog2(nr_cpu_ids));
28112811
fs_info->delalloc_batch = sectorsize * 512 * (1 + ilog2(nr_cpu_ids));
28122812

@@ -4133,9 +4133,7 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
41334133
btrfs_super_bytes_used(sb));
41344134
ret = -EINVAL;
41354135
}
4136-
if (!is_power_of_2(btrfs_super_stripesize(sb)) ||
4137-
((btrfs_super_stripesize(sb) != sectorsize) &&
4138-
(btrfs_super_stripesize(sb) != 4096))) {
4136+
if (!is_power_of_2(btrfs_super_stripesize(sb))) {
41394137
btrfs_err(fs_info, "invalid stripesize %u",
41404138
btrfs_super_stripesize(sb));
41414139
ret = -EINVAL;

fs/btrfs/extent-tree.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2835,6 +2835,7 @@ int btrfs_should_throttle_delayed_refs(struct btrfs_trans_handle *trans,
28352835

28362836
struct async_delayed_refs {
28372837
struct btrfs_root *root;
2838+
u64 transid;
28382839
int count;
28392840
int error;
28402841
int sync;
@@ -2850,6 +2851,10 @@ static void delayed_ref_async_start(struct btrfs_work *work)
28502851

28512852
async = container_of(work, struct async_delayed_refs, work);
28522853

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+
28532858
trans = btrfs_join_transaction(async->root);
28542859
if (IS_ERR(trans)) {
28552860
async->error = PTR_ERR(trans);
@@ -2861,10 +2866,15 @@ static void delayed_ref_async_start(struct btrfs_work *work)
28612866
* wait on delayed refs
28622867
*/
28632868
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+
28642874
ret = btrfs_run_delayed_refs(trans, async->root, async->count);
28652875
if (ret)
28662876
async->error = ret;
2867-
2877+
end:
28682878
ret = btrfs_end_transaction(trans, async->root);
28692879
if (ret && !async->error)
28702880
async->error = ret;
@@ -2876,7 +2886,7 @@ static void delayed_ref_async_start(struct btrfs_work *work)
28762886
}
28772887

28782888
int btrfs_async_run_delayed_refs(struct btrfs_root *root,
2879-
unsigned long count, int wait)
2889+
unsigned long count, u64 transid, int wait)
28802890
{
28812891
struct async_delayed_refs *async;
28822892
int ret;
@@ -2888,6 +2898,7 @@ int btrfs_async_run_delayed_refs(struct btrfs_root *root,
28882898
async->root = root->fs_info->tree_root;
28892899
async->count = count;
28902900
async->error = 0;
2901+
async->transid = transid;
28912902
if (wait)
28922903
async->sync = 1;
28932904
else

fs/btrfs/extent_io.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5342,6 +5342,11 @@ int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dstv,
53425342
return ret;
53435343
}
53445344

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+
*/
53455350
int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start,
53465351
unsigned long min_len, char **map,
53475352
unsigned long *map_start,
@@ -5356,7 +5361,7 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start,
53565361
PAGE_SHIFT;
53575362

53585363
if (i != end_i)
5359-
return -EINVAL;
5364+
return 1;
53605365

53615366
if (i == 0) {
53625367
offset = start_offset;

fs/btrfs/file.c

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,30 +1534,30 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
15341534
reserve_bytes = round_up(write_bytes + sector_offset,
15351535
root->sectorsize);
15361536

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-
15561537
ret = btrfs_check_data_free_space(inode, pos, write_bytes);
1557-
if (ret < 0)
1558-
break;
1538+
if (ret < 0) {
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+
}
15591560

1560-
reserve_metadata:
15611561
ret = btrfs_delalloc_reserve_metadata(inode, reserve_bytes);
15621562
if (ret) {
15631563
if (!only_release_metadata)

fs/btrfs/inode.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4558,6 +4558,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
45584558
BUG_ON(ret);
45594559
if (btrfs_should_throttle_delayed_refs(trans, root))
45604560
btrfs_async_run_delayed_refs(root,
4561+
trans->transid,
45614562
trans->delayed_ref_updates * 2, 0);
45624563
if (be_nice) {
45634564
if (truncate_space_check(trans, root,

fs/btrfs/ordered-data.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
968968
struct rb_node *prev = NULL;
969969
struct btrfs_ordered_extent *test;
970970
int ret = 1;
971+
u64 orig_offset = offset;
971972

972973
spin_lock_irq(&tree->lock);
973974
if (ordered) {
@@ -983,7 +984,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
983984

984985
/* truncate file */
985986
if (disk_i_size > i_size) {
986-
BTRFS_I(inode)->disk_i_size = i_size;
987+
BTRFS_I(inode)->disk_i_size = orig_offset;
987988
ret = 0;
988989
goto out;
989990
}

fs/btrfs/tests/btrfs-tests.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ int btrfs_init_test_fs(void)
6868
if (IS_ERR(test_mnt)) {
6969
printk(KERN_ERR "btrfs: cannot mount test file system\n");
7070
unregister_filesystem(&test_type);
71-
return ret;
71+
return PTR_ERR(test_mnt);
7272
}
7373
return 0;
7474
}

fs/btrfs/transaction.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
818818
{
819819
struct btrfs_transaction *cur_trans = trans->transaction;
820820
struct btrfs_fs_info *info = root->fs_info;
821+
u64 transid = trans->transid;
821822
unsigned long cur = trans->delayed_ref_updates;
822823
int lock = (trans->type != TRANS_JOIN_NOLOCK);
823824
int err = 0;
@@ -905,7 +906,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
905906

906907
kmem_cache_free(btrfs_trans_handle_cachep, trans);
907908
if (must_run_delayed_refs) {
908-
btrfs_async_run_delayed_refs(root, cur,
909+
btrfs_async_run_delayed_refs(root, cur, transid,
909910
must_run_delayed_refs == 1);
910911
}
911912
return err;

0 commit comments

Comments
 (0)