aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <clm@fb.com>2016-12-13 12:14:42 -0500
committerChris Mason <clm@fb.com>2016-12-13 12:14:42 -0500
commit5f52a2c512a55500349aa261e469d099ede0f256 (patch)
treefc1d55c8f31f12e6eb0536de01a90bf7dfbb329a
parent7c4c71ac8a72aea595f4cc7e09c2bcc61929c4ac (diff)
parent2a7bf53f577e49c43de4ffa7776056de26db65d9 (diff)
Merge branch 'for-chris-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/fdmanana/linux into for-linus-4.10
Patches queued up by Filipe: The most important change is still the fix for the extent tree corruption that happens due to balance when qgroups are enabled (a regression introduced in 4.7 by a fix for a regression from the last qgroups rework). This has been hitting SLE and openSUSE users and QA very badly, where transactions keep getting aborted when running delayed references leaving the root filesystem in RO mode and nearly unusable. There are fixes here that allow us to run xfstests again with the integrity checker enabled, which has been impossible since 4.8 (apparently I'm the only one running xfstests with the integrity checker enabled, which is useful to validate dirtied leafs, like checking if there are keys out of order, etc). The rest are just some trivial fixes, most of them tagged for stable, and two cleanups. Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r--fs/btrfs/delayed-ref.h6
-rw-r--r--fs/btrfs/disk-io.c23
-rw-r--r--fs/btrfs/file.c4
-rw-r--r--fs/btrfs/qgroup.c5
-rw-r--r--fs/btrfs/relocation.c34
-rw-r--r--fs/btrfs/tree-log.c7
6 files changed, 37 insertions, 42 deletions
diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h
index dba97842b47a..50947b5a9152 100644
--- a/fs/btrfs/delayed-ref.h
+++ b/fs/btrfs/delayed-ref.h
@@ -34,12 +34,6 @@
34 * ref_head. Must clean this mess up later. 34 * ref_head. Must clean this mess up later.
35 */ 35 */
36struct btrfs_delayed_ref_node { 36struct btrfs_delayed_ref_node {
37 /*
38 * ref_head use rb tree, stored in ref_root->href.
39 * indexed by bytenr
40 */
41 struct rb_node rb_node;
42
43 /*data/tree ref use list, stored in ref_head->ref_list. */ 37 /*data/tree ref use list, stored in ref_head->ref_list. */
44 struct list_head list; 38 struct list_head list;
45 /* 39 /*
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 848d5e1c0585..066d9b929a0c 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -560,7 +560,15 @@ static noinline int check_leaf(struct btrfs_root *root,
560 u32 nritems = btrfs_header_nritems(leaf); 560 u32 nritems = btrfs_header_nritems(leaf);
561 int slot; 561 int slot;
562 562
563 if (nritems == 0) { 563 /*
564 * Extent buffers from a relocation tree have a owner field that
565 * corresponds to the subvolume tree they are based on. So just from an
566 * extent buffer alone we can not find out what is the id of the
567 * corresponding subvolume tree, so we can not figure out if the extent
568 * buffer corresponds to the root of the relocation tree or not. So skip
569 * this check for relocation trees.
570 */
571 if (nritems == 0 && !btrfs_header_flag(leaf, BTRFS_HEADER_FLAG_RELOC)) {
564 struct btrfs_root *check_root; 572 struct btrfs_root *check_root;
565 573
566 key.objectid = btrfs_header_owner(leaf); 574 key.objectid = btrfs_header_owner(leaf);
@@ -573,17 +581,24 @@ static noinline int check_leaf(struct btrfs_root *root,
573 * open_ctree() some roots has not yet been set up. 581 * open_ctree() some roots has not yet been set up.
574 */ 582 */
575 if (!IS_ERR_OR_NULL(check_root)) { 583 if (!IS_ERR_OR_NULL(check_root)) {
584 struct extent_buffer *eb;
585
586 eb = btrfs_root_node(check_root);
576 /* if leaf is the root, then it's fine */ 587 /* if leaf is the root, then it's fine */
577 if (leaf->start != 588 if (leaf != eb) {
578 btrfs_root_bytenr(&check_root->root_item)) {
579 CORRUPT("non-root leaf's nritems is 0", 589 CORRUPT("non-root leaf's nritems is 0",
580 leaf, root, 0); 590 leaf, check_root, 0);
591 free_extent_buffer(eb);
581 return -EIO; 592 return -EIO;
582 } 593 }
594 free_extent_buffer(eb);
583 } 595 }
584 return 0; 596 return 0;
585 } 597 }
586 598
599 if (nritems == 0)
600 return 0;
601
587 /* Check the 0 item */ 602 /* Check the 0 item */
588 if (btrfs_item_offset_nr(leaf, 0) + btrfs_item_size_nr(leaf, 0) != 603 if (btrfs_item_offset_nr(leaf, 0) + btrfs_item_size_nr(leaf, 0) !=
589 BTRFS_LEAF_DATA_SIZE(fs_info)) { 604 BTRFS_LEAF_DATA_SIZE(fs_info)) {
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 140271b1ea2e..448f57d108d1 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -2372,7 +2372,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
2372 u64 tail_len; 2372 u64 tail_len;
2373 u64 orig_start = offset; 2373 u64 orig_start = offset;
2374 u64 cur_offset; 2374 u64 cur_offset;
2375 u64 min_size = btrfs_calc_trunc_metadata_size(fs_info, 1); 2375 u64 min_size = btrfs_calc_trans_metadata_size(fs_info, 1);
2376 u64 drop_end; 2376 u64 drop_end;
2377 int ret = 0; 2377 int ret = 0;
2378 int err = 0; 2378 int err = 0;
@@ -2519,7 +2519,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
2519 ret = -ENOMEM; 2519 ret = -ENOMEM;
2520 goto out_free; 2520 goto out_free;
2521 } 2521 }
2522 rsv->size = btrfs_calc_trunc_metadata_size(fs_info, 1); 2522 rsv->size = btrfs_calc_trans_metadata_size(fs_info, 1);
2523 rsv->failfast = 1; 2523 rsv->failfast = 1;
2524 2524
2525 /* 2525 /*
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 3e473e9a4844..662821f1252c 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -2555,10 +2555,6 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
2555 int err = -ENOMEM; 2555 int err = -ENOMEM;
2556 int ret = 0; 2556 int ret = 0;
2557 2557
2558 mutex_lock(&fs_info->qgroup_rescan_lock);
2559 fs_info->qgroup_rescan_running = true;
2560 mutex_unlock(&fs_info->qgroup_rescan_lock);
2561
2562 path = btrfs_alloc_path(); 2558 path = btrfs_alloc_path();
2563 if (!path) 2559 if (!path)
2564 goto out; 2560 goto out;
@@ -2669,6 +2665,7 @@ qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
2669 sizeof(fs_info->qgroup_rescan_progress)); 2665 sizeof(fs_info->qgroup_rescan_progress));
2670 fs_info->qgroup_rescan_progress.objectid = progress_objectid; 2666 fs_info->qgroup_rescan_progress.objectid = progress_objectid;
2671 init_completion(&fs_info->qgroup_rescan_completion); 2667 init_completion(&fs_info->qgroup_rescan_completion);
2668 fs_info->qgroup_rescan_running = true;
2672 2669
2673 spin_unlock(&fs_info->qgroup_lock); 2670 spin_unlock(&fs_info->qgroup_lock);
2674 mutex_unlock(&fs_info->qgroup_rescan_lock); 2671 mutex_unlock(&fs_info->qgroup_rescan_lock);
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 5d222c8d2213..379711048fb0 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -1388,7 +1388,6 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
1388 struct extent_buffer *eb; 1388 struct extent_buffer *eb;
1389 struct btrfs_root_item *root_item; 1389 struct btrfs_root_item *root_item;
1390 struct btrfs_key root_key; 1390 struct btrfs_key root_key;
1391 u64 last_snap = 0;
1392 int ret; 1391 int ret;
1393 1392
1394 root_item = kmalloc(sizeof(*root_item), GFP_NOFS); 1393 root_item = kmalloc(sizeof(*root_item), GFP_NOFS);
@@ -1399,14 +1398,22 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
1399 root_key.offset = objectid; 1398 root_key.offset = objectid;
1400 1399
1401 if (root->root_key.objectid == objectid) { 1400 if (root->root_key.objectid == objectid) {
1401 u64 commit_root_gen;
1402
1402 /* called by btrfs_init_reloc_root */ 1403 /* called by btrfs_init_reloc_root */
1403 ret = btrfs_copy_root(trans, root, root->commit_root, &eb, 1404 ret = btrfs_copy_root(trans, root, root->commit_root, &eb,
1404 BTRFS_TREE_RELOC_OBJECTID); 1405 BTRFS_TREE_RELOC_OBJECTID);
1405 BUG_ON(ret); 1406 BUG_ON(ret);
1406 1407 /*
1407 last_snap = btrfs_root_last_snapshot(&root->root_item); 1408 * Set the last_snapshot field to the generation of the commit
1408 btrfs_set_root_last_snapshot(&root->root_item, 1409 * root - like this ctree.c:btrfs_block_can_be_shared() behaves
1409 trans->transid - 1); 1410 * correctly (returns true) when the relocation root is created
1411 * either inside the critical section of a transaction commit
1412 * (through transaction.c:qgroup_account_snapshot()) and when
1413 * it's created before the transaction commit is started.
1414 */
1415 commit_root_gen = btrfs_header_generation(root->commit_root);
1416 btrfs_set_root_last_snapshot(&root->root_item, commit_root_gen);
1410 } else { 1417 } else {
1411 /* 1418 /*
1412 * called by btrfs_reloc_post_snapshot_hook. 1419 * called by btrfs_reloc_post_snapshot_hook.
@@ -1430,12 +1437,6 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
1430 memset(&root_item->drop_progress, 0, 1437 memset(&root_item->drop_progress, 0,
1431 sizeof(struct btrfs_disk_key)); 1438 sizeof(struct btrfs_disk_key));
1432 root_item->drop_level = 0; 1439 root_item->drop_level = 0;
1433 /*
1434 * abuse rtransid, it is safe because it is impossible to
1435 * receive data into a relocation tree.
1436 */
1437 btrfs_set_root_rtransid(root_item, last_snap);
1438 btrfs_set_root_otransid(root_item, trans->transid);
1439 } 1440 }
1440 1441
1441 btrfs_tree_unlock(eb); 1442 btrfs_tree_unlock(eb);
@@ -2406,9 +2407,6 @@ void merge_reloc_roots(struct reloc_control *rc)
2406 struct btrfs_fs_info *fs_info = rc->extent_root->fs_info; 2407 struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
2407 struct btrfs_root *root; 2408 struct btrfs_root *root;
2408 struct btrfs_root *reloc_root; 2409 struct btrfs_root *reloc_root;
2409 u64 last_snap;
2410 u64 otransid;
2411 u64 objectid;
2412 LIST_HEAD(reloc_roots); 2410 LIST_HEAD(reloc_roots);
2413 int found = 0; 2411 int found = 0;
2414 int ret = 0; 2412 int ret = 0;
@@ -2447,14 +2445,6 @@ again:
2447 list_del_init(&reloc_root->root_list); 2445 list_del_init(&reloc_root->root_list);
2448 } 2446 }
2449 2447
2450 /*
2451 * we keep the old last snapshot transid in rtranid when we
2452 * created the relocation tree.
2453 */
2454 last_snap = btrfs_root_rtransid(&reloc_root->root_item);
2455 otransid = btrfs_root_otransid(&reloc_root->root_item);
2456 objectid = reloc_root->root_key.offset;
2457
2458 ret = btrfs_drop_snapshot(reloc_root, rc->block_rsv, 0, 1); 2448 ret = btrfs_drop_snapshot(reloc_root, rc->block_rsv, 0, 1);
2459 if (ret < 0) { 2449 if (ret < 0) {
2460 if (list_empty(&reloc_root->root_list)) 2450 if (list_empty(&reloc_root->root_list))
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index f7324189413c..f10bf5213ed8 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -1948,12 +1948,11 @@ static noinline int find_dir_range(struct btrfs_root *root,
1948next: 1948next:
1949 /* check the next slot in the tree to see if it is a valid item */ 1949 /* check the next slot in the tree to see if it is a valid item */
1950 nritems = btrfs_header_nritems(path->nodes[0]); 1950 nritems = btrfs_header_nritems(path->nodes[0]);
1951 path->slots[0]++;
1951 if (path->slots[0] >= nritems) { 1952 if (path->slots[0] >= nritems) {
1952 ret = btrfs_next_leaf(root, path); 1953 ret = btrfs_next_leaf(root, path);
1953 if (ret) 1954 if (ret)
1954 goto out; 1955 goto out;
1955 } else {
1956 path->slots[0]++;
1957 } 1956 }
1958 1957
1959 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); 1958 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
@@ -5224,6 +5223,7 @@ process_leaf:
5224 if (di_key.type == BTRFS_ROOT_ITEM_KEY) 5223 if (di_key.type == BTRFS_ROOT_ITEM_KEY)
5225 continue; 5224 continue;
5226 5225
5226 btrfs_release_path(path);
5227 di_inode = btrfs_iget(fs_info->sb, &di_key, root, NULL); 5227 di_inode = btrfs_iget(fs_info->sb, &di_key, root, NULL);
5228 if (IS_ERR(di_inode)) { 5228 if (IS_ERR(di_inode)) {
5229 ret = PTR_ERR(di_inode); 5229 ret = PTR_ERR(di_inode);
@@ -5232,13 +5232,12 @@ process_leaf:
5232 5232
5233 if (btrfs_inode_in_log(di_inode, trans->transid)) { 5233 if (btrfs_inode_in_log(di_inode, trans->transid)) {
5234 iput(di_inode); 5234 iput(di_inode);
5235 continue; 5235 break;
5236 } 5236 }
5237 5237
5238 ctx->log_new_dentries = false; 5238 ctx->log_new_dentries = false;
5239 if (type == BTRFS_FT_DIR || type == BTRFS_FT_SYMLINK) 5239 if (type == BTRFS_FT_DIR || type == BTRFS_FT_SYMLINK)
5240 log_mode = LOG_INODE_ALL; 5240 log_mode = LOG_INODE_ALL;
5241 btrfs_release_path(path);
5242 ret = btrfs_log_inode(trans, root, di_inode, 5241 ret = btrfs_log_inode(trans, root, di_inode,
5243 log_mode, 0, LLONG_MAX, ctx); 5242 log_mode, 0, LLONG_MAX, ctx);
5244 if (!ret && 5243 if (!ret &&