Commit Graph

88 Commits

Author SHA1 Message Date
David Sterba 4dca0ccf3d btrfs-progs: check: reorder options to sections
Signed-off-by: David Sterba <dsterba@suse.com>
2018-08-06 15:06:24 +02:00
Qu Wenruo 21d1109168 btrfs-progs: check/original: Don't overwrite return value when we failed to repair
In check_inode_recs(), for repair mode we always reset @ret to 0.  It
makes no sense and later we check @ret to determine if the repair is
successful.

Fix it by removing the offending overwrite.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Gu Jinxiang <gujx@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-08-06 15:06:22 +02:00
Qu Wenruo 159f177cf9 btrfs-progs: check/original: Avoid infinite loop when failed to repair inode
Exposed by fuzz-tests/003-multi-check-unmounted/ on fuzzed image
bko-161811.raw.xz.

It's caused by the fact when check_fs_roots() finds tree root is
modified, it re-search tree root by goto again: label.
However again: label. will also reset root objectid to 0.
If we failed to repair one fs root but still modified tree root, we will
go into such infinite loop.

Fix it by recording which root we should skip for repair mode.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Gu Jinxiang <gujx@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-08-06 15:06:20 +02:00
Qu Wenruo 5f594c3ce3 btrfs-progs: check: Remove the ability to rebuild root overwriting existing tree blocks
We have function btrfs_fsck_reinit_root() to reinit csum or extent tree.
However this function allows us to let it overwrite existing tree blocks
using @overwrite parameter.

Such behavior is pretty dangerous while no caller is using this feature
explicitly.

So just remove @overwrite parameter and allow btrfs_fsck_reinit_root()
to error out when it fails to allocate tree block.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Gu Jinxiang <gujx@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-08-06 15:04:58 +02:00
Stéphane Lesimple 078e9a1cc9 btrfs-progs: check: enhanced progress indicator
We reuse the task_position enum and task_ctx struct of the original progress
indicator, adding more values and fields for our needs.

Then add hooks in all steps of the check to properly record progress.

Here's how the output looks like on a 22 Tb 5-disk RAID1 FS:

Opening filesystem to check...
Checking filesystem on /dev/mapper/luks-ST10000VN0004-XXXXXXXX
UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
[1/7] checking extents           (0:20:21 elapsed, 950958 items checked)
[2/7] checking root items        (0:01:29 elapsed, 15121 items checked)
[3/7] checking free space cache  (0:00:11 elapsed, 4928 items checked)
[4/7] checking fs roots          (0:51:31 elapsed, 600892 items checked)
[5/7] checking csums             (0:14:35 elapsed, 754522 items checked)
[6/7] checking root refs         (0:00:00 elapsed, 232 items checked)
[7/7] checking quota groups skipped (not enabled on this FS)
found 5286458060800 bytes used, no error found

Signed-off-by: Stéphane Lesimple <stephane_btrfs@lesimple.fr>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-08-06 15:03:23 +02:00
Su Yue d53d42fa21 btrfs-progs: lowmem: fix false alerts of referencer count mismatch for blocks relocated
Btrfs lowmem check reports such false alerts:
=========
ERROR: extent[1419709677568, 1703936] referencer count mismatch (root: 2192, owner: 327635, offset: 0) wanted: 9, have: 13
=========

While in extent tree, the extent has:
=========
        item 98 key (1419709677568 EXTENT_ITEM 1703936) itemoff 10745 itemsize 92
                refs 35 gen 16921 flags DATA
                extent data backref root 2192 objectid 327635 offset 0 count 9
                shared data backref parent 1232784752640 count 4
                shared data backref parent 1232784736256 count 13
                shared data backref parent 1232784719872 count 9
=========

The extent data 327635 starts in this leaf without BTRFS_HEADER_FLAG_RELOC:
=========
leaf 1471521390592 items 146 free space 3671 generation 18581 owner 2192
leaf 1471521390592 flags 0x1(WRITTEN) backref revision 1
...
 item 137 key (327635 EXTENT_DATA 0) itemoff 7745 itemsize 53
                generation 15770 type 1 (regular)
                extent data disk byte 1419709677568 nr 1703936
                extent data offset 0 nr 131072 ram 1703936
                extent compression 0 (none)
        item 138 key (327635 EXTENT_DATA 131072) itemoff 7692 itemsize 53
                generation 15770 type 1 (regular)
                extent data disk byte 1419709677568 nr 1703936
                extent data offset 131072 nr 131072 ram 1703936
                extent compression 0 (none)
...(Exactly 9 items here)
=========

The next leaf is flaged as relocated, so extent data backrefs are
shared not keyed:
=========
leaf 1232784752640 items 159 free space 2503 generation 16924 owner 2192
leaf 1232784752640 flags 0x3(WRITTEN|RELOC) backref revision 1
fs uuid 0f43f49d-6e63-4b1b-bc8c-c54da409872d
chunk uuid e558e6f7-4f08-4292-91fb-9a775fdd530b
        item 0 key (327635 EXTENT_DATA 1179648) itemoff 16230 itemsize 53
                generation 15770 type 1 (regular)
                extent data disk byte 1419709677568 nr 1703936
                extent data offset 1179648 nr 131072 ram 1703936
                extent compression 0 (none)
        item 1 key (327635 EXTENT_DATA 1310720) itemoff 16177 itemsize 53
                generation 15770 type 1 (regular)
                extent data disk byte 1419709677568 nr 1703936
                extent data offset 1310720 nr 131072 ram 1703936
                extent compression 0 (none)
        item 2 key (327635 EXTENT_DATA 1441792) itemoff 16124 itemsize 53
                generation 15770 type 1 (regular)
                extent data disk byte 1419709677568 nr 1703936
                extent data offset 1441792 nr 131072 ram 1703936
                extent compression 0 (none)
        item 3 key (327635 EXTENT_DATA 1572864) itemoff 16071 itemsize 53
=======

Lowmem mode starts to count extent data backrefs in first leaf, those
backrefs are keyed as wanted.
It calls btrfs_next_item to skip to next leaf.
However, the next leaf was relocated, extent data items in this leaf
should have shared backrefs shouldn't be counted.

So let lowmem mode do not count data backrefs if leaf is flaged with
BTRFS_HEADER_FLAG_RELOC.

Reported-by: Chris Murphy <chris@colorremedies.com>
Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-08-06 15:03:14 +02:00
Qu Wenruo c010437455 btrfs-progs: check: orig: Don't panic when unexpected root item is referring to one extent
With crafted image, expected root item can refer to certain extent, and
original mode uses BUG_ON() to handle such case.

Fix it by gracefully return error.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=200403
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-08-06 15:03:07 +02:00
Nikolay Borisov f3c7101116 btrfs-progs: check: Drop trans/root arguments from free_extent_hook
They are not really needed, what free_extent_hook wants is really a
pointer to fs_info so give it to it directly. This is in preparation
of delayed refs code.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-08-06 15:01:57 +02:00
David Disseldorp 7490f94dd7 btrfs-progs: check: add experimental flag for lowmem mode
The experimental flag is already carried in the manpage, but was removed
from the btrfs check usage message as part of refactoring via
87c1bd13c1. Add it back.

Signed-off-by: David Disseldorp <ddiss@suse.de>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-08-06 15:01:19 +02:00
Qu Wenruo eca8dc0757 btrfs-progs: check/lowmem: Repair wrong inline ram_bytes for uncompressed extent
Similar to the original mode repair.

Reported-by: Steve Leung <sjleung@shaw.ca>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-08-06 15:01:03 +02:00
Qu Wenruo cd28b15496 btrfs-progs: check/lowmem: Prepare check_file_extent() to handle repair
Current check_file_extent() doesn't support later repair work, since it
doesn't accept btrfs_path structure as parameter, thus it can't modify
btrfs trees, or later check will still use the old and wrong path.

Use btrfs_path to replace btrfs_key, extent_buffer and slot parameters,
so we can modify @path directly for repair, and reduce the number of
parameters for check_file_extent().

Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-08-06 15:00:58 +02:00
Qu Wenruo e5f50be06f btrfs-progs: check/original: Detect and repair wrong inline ram_bytes
It looks like that around 2014, btrfs kernel has a regression that would
cause offset-by-one ram_bytes for inline extent.

Add the ability to repair it in original mode.

Reported-by: Steve Leung <sjleung@shaw.ca>
Tested-by: Steve Leung <sjleung@shaw.ca>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-08-06 15:00:44 +02:00
Qu Wenruo 3c042605db btrfs-progs: Get rid of the confusing btrfs_file_extent_inline_len()
[BUG]
If one uncompressed inline extent has incorrect ram_bytes, neither btrfs
check nor dump-tree could detect such corruption.

[CAUSE]
Every caller tries to read inline extent ram_bytes is using
btrfs_file_extent_inline_len(), other than directly calling
btrfs_file_extent_ram_bytes().

For compressed extent, it's just calling btrfs_file_extent_ram_bytes().
However for uncompressed extent, it falls back to
btrfs_file_extent_inline_item_len(), makes us unable to detect anything
wrong in ram_bytes.

[FIX]
Just get rid of such confusing btrfs_file_extent_inline_len() function.

Reported-by: Steve Leung <sjleung@shaw.ca>
Tested-by: Steve Leung <sjleung@shaw.ca>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-08-06 15:00:34 +02:00
Nikolay Borisov d4f19ad084 btrfs-progs: check: factor out root parsing from check_chunks_and_extents
check_chunks_and_extents does quite a number of distinct things. The
first of those is going through all root items in the root tree and
classify every root depending on whether they have a dropping operation
in progress or not. Lets factor out this code and move the variables
specific to this in a separate function so clean up check_chunks_and_extents
a bit. Accidentally, this patch fixes some reference leaks since
in error conditions in the loop the code does "goto out" but at that
label we don't really release the path. Having this code extracted in a
separate function which always releases the path avoids this problem
entirely.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-08-06 15:00:08 +02:00
Nikolay Borisov a7773d7f06 btrfs-progs: check: Fix wrong root parameter of btrfs_next_leaf call
The first thing that check_chunks_and_extents does is to iterate all
the root items in the root tree and link them to either the "normal_list"
or "dropping_trees" list. If a leaf has to be crossed during this
operation btrfs_next_leaf is called to do that. However, currently it's
called with a wrong argument for its 'root' parameter. Since we are
iterating the root tree the passed root should be fs_info->tree_rot,
whereas right now we are passing the local variable 'root' which is
assigned to the fs_tree. As it stands, this bug is actually benign since
the passed root is only passed to reada_for_search, where it's used to
reference the fs_info. Nevertheless the code is wrong and at the very least
misleading, so fix it by passing the correct root.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-08-06 14:59:56 +02:00
Misono Tomohiro 26892ad5f1 btrfs-progs: check: Initialize all filed of btrfs_inode_item in insert_inode_item()
Initialize all filed of btrfs_inode_item to zero in order to prevent
having some garbage, especially for flags field.

Signed-off-by: Misono Tomohiro <misono.tomohiro@jp.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:40 +02:00
Su Yue 42f7017ee6 btrfs-progs: check: lowmem: check symlinks with append/immutable flags
Define new error bit INODE_FLAGS_ERROR to represents invalid inode
flags error.

Symlinks should never have append/immutable flags set.
While checking inodes, if found a symlink with append/immutable
flags, report and record the inode flags error.

This is for lowmem mode.

Issue: #133
Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:38 +02:00
Su Yue eef9f3eed6 btrfs-progs: check: check symlinks with append/immutable flags
Define new macro I_ERR_ODD_INODE_FLAGS to represents odd inode flags.

Symlinks should never have append/immutable flags.
While processing inodes, if found a symlink with append/immutable
flags, mark the inode record with I_ERR_ODD_INODE_FLAGS.

This is for original mode.

Issue: #133
Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:37 +02:00
Nikolay Borisov a22b593587 btrfs-progs: Change btrfs_root to btrfs_fs_info argument in btrfs_lookup_extent_info
That function really wants an fs_info and not a root. Accidentally,
this also makes the kernel/user space signatures to be coherent.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:37 +02:00
Nikolay Borisov 12e2280d7b btrfs-progs: check: Remove unused root argument from btrfs_extent_post_op
This is no longer used by the callees of that function so remove it.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:37 +02:00
Nikolay Borisov b4c4ff9c4a btrfs-progs: check: Remove root parameter from btrfs_fix_block_accounting
It's always set to extent_root and the function already takes a
transaction handle where fs_info could be referenced and in turn
the extent_tree.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:36 +02:00
Nikolay Borisov 48663d6e64 btrfs-progs: check: Remove root argument from delete_extent_records
This function is always passed the extent_root as "root" parameter. In
turn it uses the root parameter to mostly access fs_info and performs
only a single call to btrfs_update_block_group where it passses the
passed root. This is all redundant since fs_info can be referenced
from the transaction handle and in turn extent_root can be referenced
from the fs_info. So do that to simplify the function's signature.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:36 +02:00
Qu Wenruo 41750fe660 btrfs-progs: Remove fs_info parameter from btrfs_leaf_free_space()
For btrfs_leaf_free_space(), to get leaf data size, we have two way to
get it:

1) leaf->fs_info->nodesize
2) leaf->len

Anyway, we could get rid of @fs_info parameter for
btrfs_leaf_free_space().
And here we choose method 2), as it provides extra benefit to get leaf
free space without initializing a real fs_info.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:35 +02:00
Nikolay Borisov 5a621e039e btrfs-progs: check: Remove ext_ref local variable from check_fs_roots_lowmem
All real consumers of that variable have inlined the checks since they
are simple enough. So just remove it.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:34 +02:00
Nikolay Borisov 03b6929079 btrfs-progs: check: Drop ext_ref arument from check_fs_root
It's no longer used so just remove it.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:34 +02:00
Nikolay Borisov 511cd09d27 btrfs-progs: check: Drop ext_ref param from check_fs_first_inode
It's no longer used in that function so can be dropped altogether.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:34 +02:00
Nikolay Borisov d01839e95a btrfs-progs: check: Remove ext_ref param from walk_down_tree
It's no longer used so just remove it.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:34 +02:00
Nikolay Borisov cd62501086 btrfs-progs: check: Remove ext_ref param from check_fs_first_inode
It's no longer use and can be dropped.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:34 +02:00
Nikolay Borisov 1e154d9039 btrfs-progs: check: Drop unused ext_ref parameter from process_one_leaf
It's no longer used in the function so just remove it

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:34 +02:00
Nikolay Borisov 72cdfeaf62 btrfs-progs: check: Drop ext_ref argument from check_inode_item
We can derive this argument from root->fs_info and also make it local
to the sole switch case it's used.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:34 +02:00
Nikolay Borisov 990c79bff5 btrfs-progs: check: Drop ext_ref param from check_dir_item
This parameter is no longer used in this function, so drop it

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:34 +02:00
Nikolay Borisov 30c72595ea btrfs-progs: check: Drop ext_ref parameter from find_inode_ref
This is a boolean parameter which signals whether the fs has the
EXTENDED_IREF feature flag toggled or not. Since a reference to fs_info
can be obtained there is no need to pollute the interface.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:33 +02:00
Nikolay Borisov 62b7a389c6 btrfs-progs: check: fix DIR_ITEM checking in lowmem
When checking the validity of a DIR_ITEM item the index variable is
explicitly set to -1 so that the index check in find_inode_ref() is
ignored. This is necessary due to possible name collisions in DIR_ITEMS
(i.e. multiple files with the same crc32c for their names, resulting in
the identical key->offset). Currently the code is broken due to index
being set to -1 at the beginning of check_dir_item and subsequently
reset to the index found in find_inode_ref. On subsequent iterations of
the while loop in check_dir_items we are going to erroneously perform
index checking, since index is not -1 but whatever the index value of
the last handled INODE_REF ITEM.

Without this patch check in lowmem mode produces the following false
warnings positivess:

ERROR: root 5 INODE REF[1991456, 256] name 5ab4e28b~~~~~~~~QBXUT2GBJDRT5CB6ZWAJVDHK filetype 1 missing

But the items for this name are in fact correct:

------------------SNIP------------------------
item 13 key (256 DIR_ITEM 4227063046) itemoff 2945 itemsize 140
	location key (220890 INODE_ITEM 0) type FILE
	transid 2278 data_len 0 name_len 40
	name: 5ab4e1bb~~~~~~~~65KNTAWVJ5VD4SV2R3BKFCXL
	location key (1991456 INODE_ITEM 0) type FILE
	transid 2285 data_len 0 name_len 40
	name: 5ab4e28b~~~~~~~~QBXUT2GBJDRT5CB6ZWAJVDHK

item 21 key (1991456 INODE_REF 256) itemoff 2104 itemsize 50
	index 1934146 namelen 40 name: 5ab4e28b~~~~~~~~QBXUT2GBJDRT5CB6ZWAJVDHK
-------------------SNIP-------------------------

Fix this by moving the code setting index at the beginning of the while
loop. This ensure that for each item in DIR_ITEM we have index set
correctly.

Fixes: 564901eac7 ("btrfs-progs: check: introduce print_dir_item_err()")
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:33 +02:00
Qu Wenruo 4bd7bbb6f6 btrfs-progs: check: Make btrfs check return error for qgroup mismatch
Current btrfs-check will check qgroup consistency, but even when it
finds something wrong, the return value is still 0.

Fix it by allowing report_qgroups() to return int to indicate qgroup
mismatch, and also add extra logic to return no error if qgroup repair
is successful.

Without this patch, fstests can't detect qgroup corruption by its fsck
alone.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:33 +02:00
Nikolay Borisov 873fba7101 btrfs-progs: Remove devid parameter from btrfs_rmap_block
This parameter was introduced with the original implementation of the
function but has never really been used, so just remove it.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:32 +02:00
Su Yue 04855a16d2 btrfs-progs: check: lowmem: end of removing parameters @trans in lowmem
Remove @trans in check_chunks_and_extents_lowmem().

After this patch, lowmem repair works again.

Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:32 +02:00
Su Yue ea8763bd05 btrfs-progs: check: lowmem: introduce repair_block_accounting
Introduce repair_block_accounting() which calls
btrfs_fix_block_accounting() to repair block group accouting.

Replace btrfs_fix_block_accounting() with the new function.

Note: This patch and next patches cause error in lowmem repair like:
"Error: Commit_root already set when starting transaction".
Such error will disappear after removing @trans finished.

Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:31 +02:00
Su Yue b9fb29a9ba btrfs-progs: check: lowmem: remove parameter @trans of check_btrfs_root
Remove parameters @trans of delete_extent_item() and walk_down_tree_v2().

Note: This patch and next patches cause error in lowmem repair like:
"Error: Commit_root already set when starting transaction".
Such error will disappear after removing @trans finished.

Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:31 +02:00
Su Yue 32705f2307 btrfs-progs: check: lowmem: remove parameter @trans of repair_tree_back_ref
This patch removes parameter @trans of repair_tree_back_ref().
It calls try_avoid_extents_overwrite() and starts a transaction by
itself.

Note: This patch and next patches cause error in lowmem repair like:
"Error: Commit_root already set when starting transaction".
Such error will disappear after removing @trans finished.

Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:31 +02:00
Su Yue 4c2b21acaa btrfs-progs: check: lowmem: remove parameter @trans of check_leaf_items
This patch removes parameter @trans of check_leaf_items().

Note: This patch and next patches cause error in lowmem repair like:
"Error: Commit_root already set when starting transaction".
Such error will disappear after removing @trans finished.

Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:31 +02:00
Su Yue adb198aa6d btrfs-progs: check: lowmem: remove parameter @trans of repair_extent_item
This patch removes parameter @trans of repair_extent_item().
It calls try_avoid_extents_overwrite() and starts a transaction by
itself.

Note: This patch and next patches cause error in lowmem repair like:
"Error: Commit_root already set when starting transaction".
Such error will disappear after removing @trans finished.

Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:31 +02:00
Su Yue b4069a192d btrfs-progs: check: lowmem: remove parameter @trans of repair_chunk_item
This patch removes parameter @trans of repair_chunk_item().
It calls try_avoid_extents_overwrite() and starts a transaction by
itself.

Note: This patch and next patches cause error in lowmem repair like:
"Error: Commit_root already set when starting transaction".
Such error will disappear after removing @trans finished.

Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:31 +02:00
Su Yue e9f0396a42 btrfs-progs: check: lowmem: remove parameter @trans of delete_extent_item
This patch removes the parameter @trans of delete_extent_item().
It calls try_avoid_extents_overwrite() and starts a transaction
by itself.

Note: This patch and next patches cause error in lowmem repair like:
"Error: Commit_root already set when starting transaction".
Such error will disappear after removing @trans finished.

Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:31 +02:00
Su Yue 50782a34d7 btrfs-progs: check: lowmem: start to remove parameters @trans in lowmem
Since extents can be avoided to be overwrittten by excluding or chunk
allocation. It's not necessary to do all repairs in one transaction.

This patch removes parameter @trans of repair_extent_data_item().
repair_extent_data_item() calls try_avoid_extents_overwrite()
and starts a transaction by itself.

Note: This patch and next patches cause error in lowmem repair like:
"Error: Commit_root already set when starting transaction".
Such error will disappear after removing @trans finished.

Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:31 +02:00
Su Yue 0ee012318f btrfs-progs: check: lowmem: exclude extents if init-extent-tree in lowmem
If options '--init-extent-tree' and '--mode=lowmem' are both
input, all metadata blocks will be traversed twice.
First one is done by pin_metadata_blocks() in reinit_extent_tree().
Second one is in check_chunks_and_extents_v2().

Excluding instead of pinning metadata blocks before reinitializing th
extent tree in lowmem can save some time.

Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:30 +02:00
Su Yue 4e320db9dd btrfs-progs: check: lowmem: introduce avoid_extents_overwrite
Declare a global u64 variable last_allocated_chunk records start of
the last chunk allocated by lowmem repair.
Although global variable is not nice, it simplifies the code a lot.

avoid_extents_overwrite() prefers to allocate a new chunk first.
If it failed because of no space or wrong used bytes (like in
fsck-tests/004), then it tries to exclude metadata blocks which costs
a lot of time in large filesystems.

Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:30 +02:00
Su Yue e99f377541 btrfs-progs: check: lowmem: introduce try_force_cow_in_new_chunk
Introduce create_chunk_and_block_block_group() to allocate a new chunk
and corresponding block group.

The new function force_cow_in_new_chunk() firstly allocates new chunk
and records its start.
Then it modifies all metadata block groups cached and full.
Finally it marks the new block group uncached and unfree.
In the next COW, extents states will be updated automatically by
cache_block_group().

New function try_to_force_cow_in_new_chunk() will try to mark block
groups full, allocate a new chunk and records the start.
If the last allocated chunk is almost full, a new chunk will be
allocated.

Suggested-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:30 +02:00
Su Yue 8586c84e8e btrfs-progs: check: lowmem: introduce mark/clear_block_groups_full
Excluding or pining all metadata blocks is time-inefficient for large
filesystems.  Here is another way to mark all metadata block groups full
and allocate new chunks for COW. Then new reserved extents never
overwrite extents.

Introduce modify_block_groups_cache() to modify all blocks groups
cache state and set all extents in block groups unfree in free space
cache.
mark/clear_block_groups_full() are wrappers of above function.

Suggested-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:37:07 +02:00
Su Yue d8020d5f69 btrfs-progs: check: lowmem: exclude extents of metadata blocks
Commit d17d6663c99c ("btrfs-progs: lowmem check: Fix regression which
screws up extent allocator") removes pin_metadata_blocks() from lowmem
repair.  So we have to find another way to exclude extents which should
be occupied by existing tree blocks.

Modify pin_down_tree_blocks() and rename it to traverse_tree_blocks
for sharing code with new function exclude_metadata_blocks().

* exclude_metadata_blocks() traverses and marks extents of all tree
  blocks dirty in fs_info->excluded_extents.
* cleanup_excluded_extents() is responsible for cleanup.

Export them to mode-common.h since they will be used both in original
and lowmem modes.

Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:35:55 +02:00
Su Yue 4fb23ea06f btrfs-progs: check: move pin_down_tree_blocks to mode-common.c
Move pin_down_tree_blocks from main.c to mode-common.c for
further patches.
And export pin_metadata_blocks to mode-common.h.

Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-06-07 16:34:46 +02:00