GitHub/LineageOS/G12/android_kernel_amlogic_linux-4.9.git
10 years agobtrfs: fix lockups from btrfs_clear_path_blocking
Chris Mason [Wed, 19 Nov 2014 18:25:09 +0000 (10:25 -0800)]
btrfs: fix lockups from btrfs_clear_path_blocking

The fair reader/writer locks mean that btrfs_clear_path_blocking needs
to strictly follow lock ordering rules even when we already have
blocking locks on a given path.

Before we can clear a blocking lock on the path, we need to make sure
all of the locks have been converted to blocking.  This will remove lock
inversions against anyone spinning in write_lock() against the buffers
we're trying to get read locks on.  These inversions didn't exist before
the fair read/writer locks, but now we need to be more careful.

We papered over this deadlock in the past by changing
btrfs_try_read_lock() to be a true trylock against both the spinlock and
the blocking lock.  This was slower, and not sufficient to fix all the
deadlocks.  This patch adds a btrfs_tree_read_lock_atomic(), which
basically means get the spinlock but trylock on the blocking lock.

Signed-off-by: Chris Mason <clm@fb.com>
Signed-off-by: Josef Bacik <jbacik@fb.com>
Reported-by: Patrick Schmid <schmid@phys.ethz.ch>
cc: stable@vger.kernel.org #v3.15+

10 years agoBtrfs: fix kfree on list_head in btrfs_lookup_csums_range error cleanup
Chris Mason [Tue, 4 Nov 2014 14:59:04 +0000 (06:59 -0800)]
Btrfs: fix kfree on list_head in btrfs_lookup_csums_range error cleanup

If we hit any errors in btrfs_lookup_csums_range, we'll loop through all
the csums we allocate and free them.  But the code was using list_entry
incorrectly, and ended up trying to free the on-stack list_head instead.

This bug came from commit 0678b6185

btrfs: Don't BUG_ON kzalloc error in btrfs_lookup_csums_range()

Signed-off-by: Chris Mason <clm@fb.com>
Reported-by: Erik Berg <btrfs@slipsprogrammoer.no>
cc: stable@vger.kernel.org # 3.3 or newer

10 years agoBtrfs: fix race that makes btrfs_lookup_extent_info miss skinny extent items
Filipe Manana [Mon, 27 Oct 2014 09:19:52 +0000 (09:19 +0000)]
Btrfs: fix race that makes btrfs_lookup_extent_info miss skinny extent items

We have a race that can lead us to miss skinny extent items in the function
btrfs_lookup_extent_info() when the skinny metadata feature is enabled.
So basically the sequence of steps is:

1) We search in the extent tree for the skinny extent, which returns > 0
   (not found);

2) We check the previous item in the returned leaf for a non-skinny extent,
   and we don't find it;

3) Because we didn't find the non-skinny extent in step 2), we release our
   path to search the extent tree again, but this time for a non-skinny
   extent key;

4) Right after we released our path in step 3), a skinny extent was inserted
   in the extent tree (delayed refs were run) - our second extent tree search
   will miss it, because it's not looking for a skinny extent;

5) After the second search returned (with ret > 0), we look for any delayed
   ref for our extent's bytenr (and we do it while holding a read lock on the
   leaf), but we won't find any, as such delayed ref had just run and completed
   after we released out path in step 3) before doing the second search.

Fix this by removing completely the path release and re-search logic. This is
safe, because if we seach for a metadata item and we don't find it, we have the
guarantee that the returned leaf is the one where the item would be inserted,
and so path->slots[0] > 0 and path->slots[0] - 1 must be the slot where the
non-skinny extent item is if it exists. The only case where path->slots[0] is
zero is when there are no smaller keys in the tree (i.e. no left siblings for
our leaf), in which case the re-search logic isn't needed as well.

This race has been present since the introduction of skinny metadata (change
3173a18f70554fe7880bb2d85c7da566e364eb3c).

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: properly clean up btrfs_end_io_wq_cache
Josef Bacik [Wed, 15 Oct 2014 21:19:59 +0000 (17:19 -0400)]
Btrfs: properly clean up btrfs_end_io_wq_cache

In one of Dave's cleanup commits he forgot to call btrfs_end_io_wq_exit on
unload, which makes us unable to unload and then re-load the btrfs module.  This
fixes the problem.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fb.com>
Reviewed-by: David Sterba <dsterba@suse.cz>
Reviewed-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix invalid leaf slot access in btrfs_lookup_extent()
Filipe Manana [Mon, 27 Oct 2014 10:44:24 +0000 (10:44 +0000)]
Btrfs: fix invalid leaf slot access in btrfs_lookup_extent()

If we couldn't find our extent item, we accessed the current slot
(path->slots[0]) to check if it corresponds to an equivalent skinny
metadata item. However this slot could be beyond our last item in the
leaf (i.e. path->slots[0] >= btrfs_header_nritems(leaf)), in which case
we shouldn't process it.

Since btrfs_lookup_extent() is only used to find extent items for data
extents, fix this by removing completely the logic that looks up for an
equivalent skinny metadata item, since it can not exist.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agobtrfs: use macro accessors in superblock validation checks
David Sterba [Mon, 27 Oct 2014 12:52:21 +0000 (13:52 +0100)]
btrfs: use macro accessors in superblock validation checks

The initial patch c926093ec516f5d316 (btrfs: add more superblock checks)
did not properly use the macro accessors that wrap endianness and the
code would not work correctly on big endian machines.

Reported-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoRevert "Btrfs: race free update of commit root for ro snapshots"
Chris Mason [Wed, 15 Oct 2014 20:50:56 +0000 (13:50 -0700)]
Revert "Btrfs: race free update of commit root for ro snapshots"

This reverts commit 9c3b306e1c9e6be4be09e99a8fe2227d1005effc.

Switching only one commit root during a transaction is wrong because it
leads the fs into an inconsistent state. All commit roots should be
switched at once, at transaction commit time, otherwise backref walking
can often miss important references that were only accessible through
the old commit root.  Plus, the root item for the snapshot's root wasn't
getting updated and preventing the next transaction commit to do it.

This made several users get into random corruption issues after creation
of readonly snapshots.

A regression test for xfstests will follow soon.

Cc: stable@vger.kernel.org # 3.17
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agobtrfs: Fix compile error when CONFIG_SECURITY is not set.
Qu Wenruo [Wed, 8 Oct 2014 02:19:08 +0000 (10:19 +0800)]
btrfs: Fix compile error when CONFIG_SECURITY is not set.

Fix the following compile error when CONFIG_SECURITY is not set:

error: 'struct security_mnt_opts' has no member named 'num_mnt_opts'

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix compiles when CONFIG_BTRFS_FS_RUN_SANITY_TESTS is off
Chris Mason [Tue, 7 Oct 2014 20:24:20 +0000 (13:24 -0700)]
Btrfs: fix compiles when CONFIG_BTRFS_FS_RUN_SANITY_TESTS is off

Commit fccb84c94 moved added some helpers to cleanup our sanity tests,
but it looks like both Dave and I always compile with the tests enabled.

This fixes things to work when they are turned off too.

Signed-off-by: Chris Mason <clm@fb.com>
10 years agobtrfs: Make btrfs handle security mount options internally to avoid losing security...
Qu Wenruo [Tue, 23 Sep 2014 05:40:08 +0000 (13:40 +0800)]
btrfs: Make btrfs handle security mount options internally to avoid losing security label.

[BUG]
Originally when mount btrfs with "-o subvol=" mount option, btrfs will
lose all security lable.
And if the btrfs fs is mounted somewhere else, due to the lost of
security lable, SELinux will refuse to mount since the same super block
is being mounted using different security lable.

[REPRODUCER]
With SELinux enabled:
 #mkfs -t btrfs /dev/sda5
 #mount -o context=system_u:object_r:nfs_t:s0 /dev/sda5 /mnt/btrfs
 #btrfs subvolume create /mnt/btrfs/subvol
 #mount -o subvol=subvol,context=system_u:object_r:nfs_t:s0 /dev/sda5
  /mnt/test

kernel message:
SELinux: mount invalid.  Same superblock, different security settings
for (dev sda5, type btrfs)

[REASON]
This happens because btrfs will call vfs_kern_mount() and then
mount_subtree() to handle subvolume name lookup.
First mount will cut off all the security lables and when it comes to
the second vfs_kern_mount(), it has no security label now.

[FIX]
This patch will makes btrfs behavior much more like nfs,
which has the type flag FS_BINARY_MOUNTDATA,
making btrfs handles the security label internally.
So security label will be set in the real mount time and won't lose
label when use with "subvol=" mount option.

Reported-by: Eryu Guan <guaneryu@gmail.com>
Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoMerge branch 'remove-unlikely' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
Chris Mason [Sat, 4 Oct 2014 16:57:44 +0000 (09:57 -0700)]
Merge branch 'remove-unlikely' of git://git./linux/kernel/git/kdave/linux into for-linus

10 years agoMerge branch 'cleanup/blocksize-diet-part1' of git://git.kernel.org/pub/scm/linux...
Chris Mason [Sat, 4 Oct 2014 16:57:14 +0000 (09:57 -0700)]
Merge branch 'cleanup/blocksize-diet-part1' of git://git./linux/kernel/git/kdave/linux into for-linus

10 years agoMerge branch 'cleanup/misc-for-3.18' of git://git.kernel.org/pub/scm/linux/kernel...
Chris Mason [Sat, 4 Oct 2014 16:56:45 +0000 (09:56 -0700)]
Merge branch 'cleanup/misc-for-3.18' of git://git./linux/kernel/git/kdave/linux into for-linus

Signed-off-by: Chris Mason <clm@fb.com>
Conflicts:
fs/btrfs/extent_io.c

10 years agoBtrfs: send, don't delay dir move if there's a new parent inode
Filipe Manana [Thu, 2 Oct 2014 18:17:32 +0000 (19:17 +0100)]
Btrfs: send, don't delay dir move if there's a new parent inode

If between two snapshots we rename an existing directory named X to Y and
make it a child (direct or not) of a new inode named X, we were delaying
the move/rename of the former directory unnecessarily, which would result
in attempting to rename the new directory from its orphan name to name X
prematurely.

Minimal reproducer:

    $ mkfs.btrfs -f /dev/vdd
    $ mount /dev/vdd /mnt
    $ mkdir -p /mnt/merlin/RC/OSD/Source

    $ btrfs subvolume snapshot -r /mnt /mnt/mysnap1

    $ mkdir /mnt/OSD
    $ mv /mnt/merlin/RC/OSD /mnt/OSD/OSD-Plane_788
    $ mv /mnt/OSD /mnt/merlin/RC

    $ btrfs subvolume snapshot -r /mnt /mnt/mysnap2

    $ btrfs send /mnt/mysnap1 -f /tmp/1.snap
    $ btrfs send -p /mnt/mysnap1 /mnt/mysnap2 -f /tmp/2.snap

    $ mkfs.btrfs -f /dev/vdc
    $ mount /dev/vdc /mnt2

    $ btrfs receive /mnt2 -f /tmp/1.snap
    $ btrfs receive /mnt2 -f /tmp/2.snap

The second receive (from an incremental send) failed with the following
error message: "rename o261-7-0 -> merlin/RC/OSD failed".
This is a regression introduced in the 3.16 kernel.

A test case for xfstests follows.

Reported-by: Marc Merlin <marc@merlins.org>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agobtrfs: add more superblock checks
David Sterba [Tue, 30 Sep 2014 17:16:47 +0000 (19:16 +0200)]
btrfs: add more superblock checks

Populate btrfs_check_super_valid() with checks that try to verify
consistency of superblock by additional conditions that may arise from
corrupted devices or bitflips. Some of tests are only hints and issue
warnings instead of failing the mount, basically when the checks are
derived from the data found in the superblock.

Tested on a broken image provided by Qu.

Reported-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix race in WAIT_SYNC ioctl
Sage Weil [Fri, 26 Sep 2014 15:30:06 +0000 (08:30 -0700)]
Btrfs: fix race in WAIT_SYNC ioctl

We check whether transid is already committed via last_trans_committed and
then search through trans_list for pending transactions.  If
last_trans_committed is updated by btrfs_commit_transaction after we check
it (there is no locking), we will fail to find the committed transaction
and return EINVAL to the caller.  This has been observed occasionally by
ceph-osd (which uses this ioctl heavily).

Fix by rechecking whether the provided transid <= last_trans_committed
after the search fails, and if so return 0.

Signed-off-by: Sage Weil <sage@redhat.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: be aware of btree inode write errors to avoid fs corruption
Filipe Manana [Fri, 26 Sep 2014 11:25:56 +0000 (12:25 +0100)]
Btrfs: be aware of btree inode write errors to avoid fs corruption

While we have a transaction ongoing, the VM might decide at any time
to call btree_inode->i_mapping->a_ops->writepages(), which will start
writeback of dirty pages belonging to btree nodes/leafs. This call
might return an error or the writeback might finish with an error
before we attempt to commit the running transaction. If this happens,
we might have no way of knowing that such error happened when we are
committing the transaction - because the pages might no longer be
marked dirty nor tagged for writeback (if a subsequent modification
to the extent buffer didn't happen before the transaction commit) which
makes filemap_fdata[write|wait]_range unable to find such pages (even
if they're marked with SetPageError).
So if this happens we must abort the transaction, otherwise we commit
a super block with btree roots that point to btree nodes/leafs whose
content on disk is invalid - either garbage or the content of some
node/leaf from a past generation that got cowed or deleted and is no
longer valid (for this later case we end up getting error messages like
"parent transid verify failed on 10826481664 wanted 25748 found 29562"
when reading btree nodes/leafs from disk).

Note that setting and checking AS_EIO/AS_ENOSPC in the btree inode's
i_mapping would not be enough because we need to distinguish between
log tree extents (not fatal) vs non-log tree extents (fatal) and
because the next call to filemap_fdatawait_range() will catch and clear
such errors in the mapping - and that call might be from a log sync and
not from a transaction commit, which means we would not know about the
error at transaction commit time. Also, checking for the eb flag
EXTENT_BUFFER_IOERR at transaction commit time isn't done and would
not be completely reliable, as the eb might be removed from memory and
read back when trying to get it, which clears that flag right before
reading the eb's pages from disk, making us not know about the previous
write error.

Using the new 3 flags for the btree inode also makes us achieve the
goal of AS_EIO/AS_ENOSPC when writepages() returns success, started
writeback for all dirty pages and before filemap_fdatawait_range() is
called, the writeback for all dirty pages had already finished with
errors - because we were not using AS_EIO/AS_ENOSPC,
filemap_fdatawait_range() would return success, as it could not know
that writeback errors happened (the pages were no longer tagged for
writeback).

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: remove redundant btrfs_verify_qgroup_counts declaration.
Fabian Frederick [Thu, 25 Sep 2014 21:33:06 +0000 (23:33 +0200)]
Btrfs: remove redundant btrfs_verify_qgroup_counts declaration.

Do like disk-io function declared under CONFIG_BTRFS_FS_RUN_SANITY_TESTS
and keep prototype in qgroup.h only

Signed-off-by: Fabian Frederick <fabf@skynet.be>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agobtrfs: fix shadow warning on cmp
Fabian Frederick [Thu, 25 Sep 2014 17:35:02 +0000 (19:35 +0200)]
btrfs: fix shadow warning on cmp

cmp was declared twice in btrfs_compare_trees resulting in a shadow
warning. This patch renames second internal variable.

Signed-off-by: Fabian Frederick <fabf@skynet.be>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix compilation errors under DEBUG
Fabian Frederick [Wed, 24 Sep 2014 18:23:05 +0000 (20:23 +0200)]
Btrfs: fix compilation errors under DEBUG

bi_sector and bi_size moved to bi_iter since commit 4f024f3797c4
("block: Abstract out bvec iterator")

Signed-off-by: Fabian Frederick <fabf@skynet.be>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix crash of btrfs_release_extent_buffer_page
Liu Bo [Tue, 23 Sep 2014 14:22:33 +0000 (22:22 +0800)]
Btrfs: fix crash of btrfs_release_extent_buffer_page

This is actually inspired by Filipe's patch.  When write_one_eb() fails on
submit_extent_page(), it'll give up writing this eb and mark it with
EXTENT_BUFFER_IOERR.  So if it's not the last page that encounter the failure,
there are some left pages which remain DIRTY, and if a later COW on this eb
happens, ie. eb is COWed and freed, it'd run into BUG_ON in
btrfs_release_extent_buffer_page() for the DIRTY page, ie. BUG_ON(PageDirty(page));

This adds the missing clear_page_dirty_for_io() for the rest pages of eb.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: add missing end_page_writeback on submit_extent_page failure
Filipe Manana [Mon, 22 Sep 2014 16:41:04 +0000 (17:41 +0100)]
Btrfs: add missing end_page_writeback on submit_extent_page failure

If submit_extent_page() fails in write_one_eb(), we end up with the current
page not marked dirty anymore, unlocked and marked for writeback. But we never
end up calling end_page_writeback() against the page, which will make calls to
filemap_fdatawait_range (e.g. at transaction commit time) hang forever waiting
for the writeback bit to be cleared from the page.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agobtrfs: Fix the wrong condition judgment about subset extent map
Qu Wenruo [Mon, 22 Sep 2014 01:13:03 +0000 (09:13 +0800)]
btrfs: Fix the wrong condition judgment about subset extent map

Previous commit: btrfs: Fix and enhance merge_extent_mapping() to insert
best fitted extent map
is using wrong condition to judgement whether the range is a subset of a
existing extent map.

This may cause bug in btrfs no-holes mode.

This patch will correct the judgment and fix the bug.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix build_backref_tree issue with multiple shared blocks
Josef Bacik [Fri, 19 Sep 2014 19:43:34 +0000 (15:43 -0400)]
Btrfs: fix build_backref_tree issue with multiple shared blocks

Marc Merlin sent me a broken fs image months ago where it would blow up in the
upper->checked BUG_ON() in build_backref_tree.  This is because we had a
scenario like this

block a -- level 4 (not shared)
   |
block b -- level 3 (reloc block, shared)
   |
block c -- level 2 (not shared)
   |
block d -- level 1 (shared)
   |
block e -- level 0 (shared)

We go to build a backref tree for block e, we notice block d is shared and add
it to the list of blocks to lookup it's backrefs for.  Now when we loop around
we will check edges for the block, so we will see we looked up block c last
time.  So we lookup block d and then see that the block that points to it is
block c and we can just skip that edge since we've already been up this path.
The problem is because we clear need_check when we see block d (as it is shared)
we never add block b as needing to be checked.  And because block c is in our
path already we bail out before we walk up to block b and add it to the backref
check list.

To fix this we need to reset need_check if we trip over a block that doesn't
need to be checked.  This will make sure that any subsequent blocks in the path
as we're walking up afterwards are added to the list to be processed.  With this
patch I can now mount Marc's fs image and it'll complete the balance without
panicing.  Thanks,

Reported-by: Marc MERLIN <marc@merlins.org>
Signed-off-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: cleanup error handling in build_backref_tree
Josef Bacik [Fri, 19 Sep 2014 14:40:00 +0000 (10:40 -0400)]
Btrfs: cleanup error handling in build_backref_tree

When balance panics it tends to panic in the

BUG_ON(!upper->checked);

test, because it means it couldn't build the backref tree properly.  This is
annoying to users and frankly a recoverable error, nothing in this function is
actually fatal since it is just an in-memory building of the backrefs for a
given bytenr.  So go through and change all the BUG_ON()'s to ASSERT()'s, and
fix the BUG_ON(!upper->checked) thing to just return an error.

This patch also fixes the error handling so it tears down the work we've done
properly.  This code was horribly broken since we always just panic'ed instead
of actually erroring out, so it needed to be completely re-worked.  With this
patch my broken image no longer panics when I mount it.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agobtrfs: move checks for DUMMY_ROOT into a helper
David Sterba [Mon, 29 Sep 2014 21:53:21 +0000 (23:53 +0200)]
btrfs: move checks for DUMMY_ROOT into a helper

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: new define for the inline extent data start
David Sterba [Thu, 24 Jul 2014 15:34:58 +0000 (17:34 +0200)]
btrfs: new define for the inline extent data start

Use a common definition for the inline data start so we don't have to
open-code it and introduce bugs like "Btrfs: fix wrong max inline data
size limit" fixed.

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: kill extent_buffer_page helper
David Sterba [Wed, 30 Jul 2014 23:03:53 +0000 (01:03 +0200)]
btrfs: kill extent_buffer_page helper

It used to be more complex but now it's just a simple array access.

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: drop constant param from btrfs_release_extent_buffer_page
David Sterba [Wed, 30 Jul 2014 22:51:36 +0000 (00:51 +0200)]
btrfs: drop constant param from btrfs_release_extent_buffer_page

All callers use the same value, simplify the function.

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: hide typecast to definition of BTRFS_SEND_TRANS_STUB
David Sterba [Wed, 30 Jul 2014 22:43:18 +0000 (00:43 +0200)]
btrfs: hide typecast to definition of BTRFS_SEND_TRANS_STUB

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: let merge_reloc_roots return void
David Sterba [Tue, 29 Jul 2014 23:53:30 +0000 (01:53 +0200)]
btrfs: let merge_reloc_roots return void

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: remove unused members from struct scrub_warning
David Sterba [Tue, 29 Jul 2014 23:25:30 +0000 (01:25 +0200)]
btrfs: remove unused members from struct scrub_warning

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: use slab for end_io_wq structures
David Sterba [Tue, 29 Jul 2014 22:55:42 +0000 (00:55 +0200)]
btrfs: use slab for end_io_wq structures

The structure is frequently reused.  Rename it according to the slab
name.

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: fix error labels in init_btrfs_fs
David Sterba [Tue, 29 Jul 2014 22:58:37 +0000 (00:58 +0200)]
btrfs: fix error labels in init_btrfs_fs

btrfs_interface_init rarely fails but we could leak the prelim_ref slab.

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: use enum for wq endio metadata type
David Sterba [Tue, 29 Jul 2014 22:25:45 +0000 (00:25 +0200)]
btrfs: use enum for wq endio metadata type

The enum exists but is not consistently used.

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: remove unused extent state bits
David Sterba [Tue, 29 Jul 2014 22:03:56 +0000 (00:03 +0200)]
btrfs: remove unused extent state bits

The last users are long gone.

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agoBtrfs: set default max_inline to 8KiB instead of 8MiB
Filipe David Borba Manana [Thu, 8 Aug 2013 21:45:48 +0000 (22:45 +0100)]
Btrfs: set default max_inline to 8KiB instead of 8MiB

8MiB is way too large and likely set by mistake. This is not
a significant issue as in practice the max amount of data
added to an inline extent is also limited by the page cache
and btree leaf sizes.

Signed-off-by: Filipe David Borba Manana <fdmanana@gmail.com>
Reviewed-by: David Sterba <dsterba@suse.cz>
Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: remove blocksize from btrfs_alloc_free_block and rename
David Sterba [Sat, 14 Jun 2014 23:54:12 +0000 (01:54 +0200)]
btrfs: remove blocksize from btrfs_alloc_free_block and rename

Rename to btrfs_alloc_tree_block as it fits to the alloc/find/free +
_tree_block family. The parameter blocksize was set to the metadata
block size, directly or indirectly.

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: remove unused parameter blocksize from btrfs_find_tree_block
David Sterba [Sat, 14 Jun 2014 23:43:40 +0000 (01:43 +0200)]
btrfs: remove unused parameter blocksize from btrfs_find_tree_block

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: remove parameter blocksize from read_tree_block
David Sterba [Sat, 14 Jun 2014 23:07:32 +0000 (01:07 +0200)]
btrfs: remove parameter blocksize from read_tree_block

We know the tree block size, no need to pass it around.

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: inline code of reada_tree_block and remove it
David Sterba [Sat, 14 Jun 2014 22:51:19 +0000 (00:51 +0200)]
btrfs: inline code of reada_tree_block and remove it

It's trivial with a single user. And remove one pointless BUG_ON.

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: return void from readahead_tree_block
David Sterba [Sat, 14 Jun 2014 22:49:36 +0000 (00:49 +0200)]
btrfs: return void from readahead_tree_block

Errors in readahead are not fatal and ignored elsewhere in the code.

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: remove unused parameter from readahead_tree_block
David Sterba [Sat, 14 Jun 2014 22:29:04 +0000 (00:29 +0200)]
btrfs: remove unused parameter from readahead_tree_block

The parent_transid parameter has been unused since its introduction in
ca7a79ad8dbe2466 ("Pass down the expected generation number when reading
tree blocks").  In reada_tree_block, it was even wrongly set to leafsize.
Transid check is done in the proper read and readahead ignores errors.

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: remove unlikely from data-dependent branches and slow paths
David Sterba [Mon, 29 Sep 2014 23:33:33 +0000 (01:33 +0200)]
btrfs: remove unlikely from data-dependent branches and slow paths

There are the branch hints that obviously depend on the data being
processed, the CPU predictor will do better job according to the actual
load. It also does not make sense to use the hints in slow paths that do
a lot of other operations like locking, waiting or IO.

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: remove unlikely from NULL checks
David Sterba [Mon, 29 Sep 2014 17:20:37 +0000 (19:20 +0200)]
btrfs: remove unlikely from NULL checks

Unlikely is implicit for NULL checks of pointers.

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: remove unused variable from btrfs_parse_options
David Sterba [Tue, 29 Jul 2014 15:41:08 +0000 (17:41 +0200)]
btrfs: remove unused variable from btrfs_parse_options

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agobtrfs: defrag, use unsigned type for extent thresh
David Sterba [Tue, 29 Jul 2014 15:32:10 +0000 (17:32 +0200)]
btrfs: defrag, use unsigned type for extent thresh

Signed type mismatches the ioctl structure, all extent calculations are
done on unsigned types.

Signed-off-by: David Sterba <dsterba@suse.cz>
10 years agoBtrfs: try not to ENOSPC on log replay
Josef Bacik [Thu, 18 Sep 2014 15:30:44 +0000 (11:30 -0400)]
Btrfs: try not to ENOSPC on log replay

When doing log replay we may have to update inodes, which traditionally goes
through our delayed inode stuff.  This will try to move space over from the
trans handle, but we don't reserve space in our trans handle on replay since we
don't know how much we will need, so instead we try to flush.  But because we
have a trans handle open we won't flush anything, so if we are out of reserve
space we will simply return ENOSPC.  Since we know that if an operation made it
into the log then we definitely had space before the box bought the farm then we
don't need to worry about doing this space reservation.  Use the
fs_info->log_root_recovering flag to skip the delayed inode stuff and update the
item directly.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: don't do async reclaim during log replay
Josef Bacik [Thu, 18 Sep 2014 15:27:17 +0000 (11:27 -0400)]
Btrfs: don't do async reclaim during log replay

Trying to reproduce a log enospc bug I hit a panic in the async reclaim code
during log replay.  This is because we use fs_info->fs_root as our root for
shrinking and such.  Technically we can use whatever root we want, but let's
just not allow async reclaim while we're doing log replay.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: remove empty block groups automatically
Josef Bacik [Thu, 18 Sep 2014 15:20:02 +0000 (11:20 -0400)]
Btrfs: remove empty block groups automatically

One problem that has plagued us is that a user will use up all of his space with
data, remove a bunch of that data, and then try to create a bunch of small files
and run out of space.  This happens because all the chunks were allocated for
data since the metadata requirements were so low.  But now there's a bunch of
empty data block groups and not enough metadata space to do anything.  This
patch solves this problem by automatically deleting empty block groups.  If we
notice the used count go down to 0 when deleting or on mount notice that a block
group has a used count of 0 then we will queue it to be deleted.

When the cleaner thread runs we will double check to make sure the block group
is still empty and then we will delete it.  This patch has the side effect of no
longer having a bunch of BUG_ON()'s in the chunk delete code, which will be
helpful for both this and relocate.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix data corruption after fast fsync and writeback error
Filipe Manana [Fri, 5 Sep 2014 14:14:39 +0000 (15:14 +0100)]
Btrfs: fix data corruption after fast fsync and writeback error

When we do a fast fsync, we start all ordered operations and then while
they're running in parallel we visit the list of modified extent maps
and construct their matching file extent items and write them to the
log btree. After that, in btrfs_sync_log() we wait for all the ordered
operations to finish (via btrfs_wait_logged_extents).

The problem with this is that we were completely ignoring errors that
can happen in the extent write path, such as -ENOSPC, a temporary -ENOMEM
or -EIO errors for example. When such error happens, it means we have parts
of the on disk extent that weren't written to, and so we end up logging
file extent items that point to these extents that contain garbage/random
data - so after a crash/reboot plus log replay, we get our inode's metadata
pointing to those extents.

This worked in contrast with the full (non-fast) fsync path, where we
start all ordered operations, wait for them to finish and then write
to the log btree. In this path, after each ordered operation completes
we check if it's flagged with an error (BTRFS_ORDERED_IOERR) and return
-EIO if so (via btrfs_wait_ordered_range).

So if an error happens with any ordered operation, just return a -EIO
error to userspace, so that it knows that not all of its previous writes
were durably persisted and the application can take proper action (like
redo the writes for e.g.) - and definitely not leave any file extent items
in the log refer to non fully written extents.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix fsync race leading to invalid data after log replay
Filipe Manana [Tue, 2 Sep 2014 10:09:58 +0000 (11:09 +0100)]
Btrfs: fix fsync race leading to invalid data after log replay

When the fsync callback (btrfs_sync_file) starts, it first waits for
the writeback of any dirty pages to start and finish without holding
the inode's mutex (to reduce contention). After this it acquires the
inode's mutex and repeats that process via btrfs_wait_ordered_range
only if we're doing a full sync (BTRFS_INODE_NEEDS_FULL_SYNC flag
is set on the inode).

This is not safe for a non full sync - we need to start and wait for
writeback to finish for any pages that might have been made dirty
before acquiring the inode's mutex and after that first step mentioned
before. Why this is needed is explained by the following comment added
to btrfs_sync_file:

  "Right before acquiring the inode's mutex, we might have new
   writes dirtying pages, which won't immediately start the
   respective ordered operations - that is done through the
   fill_delalloc callbacks invoked from the writepage and
   writepages address space operations. So make sure we start
   all ordered operations before starting to log our inode. Not
   doing this means that while logging the inode, writeback
   could start and invoke writepage/writepages, which would call
   the fill_delalloc callbacks (cow_file_range,
   submit_compressed_extents). These callbacks add first an
   extent map to the modified list of extents and then create
   the respective ordered operation, which means in
   tree-log.c:btrfs_log_inode() we might capture all existing
   ordered operations (with btrfs_get_logged_extents()) before
   the fill_delalloc callback adds its ordered operation, and by
   the time we visit the modified list of extent maps (with
   btrfs_log_changed_extents()), we see and process the extent
   map they created. We then use the extent map to construct a
   file extent item for logging without waiting for the
   respective ordered operation to finish - this file extent
   item points to a disk location that might not have yet been
   written to, containing random data - so after a crash a log
   replay will make our inode have file extent items that point
   to disk locations containing invalid data, as we returned
   success to userspace without waiting for the respective
   ordered operation to finish, because it wasn't captured by
   btrfs_get_logged_extents()."

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix wrong parse of extent map's tracepoint
Liu Bo [Wed, 17 Sep 2014 13:36:41 +0000 (21:36 +0800)]
Btrfs: fix wrong parse of extent map's tracepoint

The tracepoint of extent map doesn't parse @flag correctly, we set @flag via
set_bit(), so we need to parse it on a bit bias.

Also add the missing flag, EXTENT_FLAG_FS_MAPPING.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agobtrfs: Fix and enhance merge_extent_mapping() to insert best fitted extent map
Qu Wenruo [Wed, 17 Sep 2014 03:53:35 +0000 (11:53 +0800)]
btrfs: Fix and enhance merge_extent_mapping() to insert best fitted extent map

The following commit enhanced the merge_extent_mapping() to reduce
fragment in extent map tree, but it can't handle case which existing
lies before map_start:
51f39 btrfs: Use right extent length when inserting overlap extent map.

[BUG]
When existing extent map's start is before map_start,
the em->len will be minus, which will corrupt the extent map and fail to
insert the new extent map.
This will happen when someone get a large extent map, but when it is
going to insert it into extent map tree, some one has already commit
some write and split the huge extent into small parts.

[REPRODUCER]
It is very easy to tiger using filebench with randomrw personality.
It is about 100% to reproduce when using 8G preallocated file in 60s
randonrw test.

[FIX]
This patch can now handle any existing extent position.
Since it does not directly use existing->start, now it will find the
previous and next extent around map_start.
So the old existing->start < map_start bug will never happen again.

[ENHANCE]
This patch will insert the best fitted extent map into extent map tree,
other than the oldest [map_start, map_start + sectorsize) or the
relatively newer but not perfect [map_start, existing->start).

The patch will first search existing extent that does not intersects with
the desired map range [map_start, map_start + len).
The existing extent will be either before or behind map_start, and based
on the existing extent, we can find out the previous and next extent
around map_start.

So the best fitted extent would be [prev->end, next->start).
For prev or next is not found, em->start would be prev->end and em->end
wold be next->start.

With this patch, the fragment in extent map tree should be reduced much
more than the 51f39 commit and reduce an unneeded extent map tree search.

Reported-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix up bounds checking in lseek
Liu Bo [Tue, 16 Sep 2014 09:49:30 +0000 (17:49 +0800)]
Btrfs: fix up bounds checking in lseek

An user reported this, it is because that lseek's SEEK_SET/SEEK_CUR/SEEK_END
allow a negative value for @offset, but btrfs's SEEK_DATA/SEEK_HOLE don't
prepare for that and convert the negative @offset into unsigned type,
so we get (end < start) warning.

[ 1269.835374] ------------[ cut here ]------------
[ 1269.836809] WARNING: CPU: 0 PID: 1241 at fs/btrfs/extent_io.c:430 insert_state+0x11d/0x140()
[ 1269.838816] BTRFS: end < start 4094 18446744073709551615
[ 1269.840334] CPU: 0 PID: 1241 Comm: a.out Tainted: G        W      3.16.0+ #306
[ 1269.858229] Call Trace:
[ 1269.858612]  [<ffffffff81801a69>] dump_stack+0x4e/0x68
[ 1269.858952]  [<ffffffff8107894c>] warn_slowpath_common+0x8c/0xc0
[ 1269.859416]  [<ffffffff81078a36>] warn_slowpath_fmt+0x46/0x50
[ 1269.859929]  [<ffffffff813b0fbd>] insert_state+0x11d/0x140
[ 1269.860409]  [<ffffffff813b1396>] __set_extent_bit+0x3b6/0x4e0
[ 1269.860805]  [<ffffffff813b21c7>] lock_extent_bits+0x87/0x200
[ 1269.861697]  [<ffffffff813a5b28>] btrfs_file_llseek+0x148/0x2a0
[ 1269.862168]  [<ffffffff811f201e>] SyS_lseek+0xae/0xc0
[ 1269.862620]  [<ffffffff8180b212>] system_call_fastpath+0x16/0x1b
[ 1269.862970] ---[ end trace 4d33ea885832054b ]---

This assumes that btrfs starts finding DATA/HOLE from the beginning of file
if the assigned @offset is negative.

Also we add alignment for lock_extent_bits 's range.

Reported-by: Toralf Förster <toralf.foerster@gmx.de>
Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: cleanup the read failure record after write or when the inode is freeing
Miao Xie [Fri, 12 Sep 2014 10:44:04 +0000 (18:44 +0800)]
Btrfs: cleanup the read failure record after write or when the inode is freeing

After the data is written successfully, we should cleanup the read failure record
in that range because
- If we set data COW for the file, the range that the failure record pointed to is
  mapped to a new place, so it is invalid.
- If we set no data COW for the file, and if there is no error during writting,
  the corrupted data is corrected, so the failure record can be removed. And if
  some errors happen on the mirrors, we also needn't worry about it because the
  failure record will be recreated if we read the same place again.

Sometimes, we may fail to correct the data, so the failure records will be left
in the tree, we need free them when we free the inode or the memory leak happens.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: implement repair function when direct read fails
Miao Xie [Fri, 12 Sep 2014 10:44:03 +0000 (18:44 +0800)]
Btrfs: implement repair function when direct read fails

This patch implement data repair function when direct read fails.

The detail of the implementation is:
- When we find the data is not right, we try to read the data from the other
  mirror.
- When the io on the mirror ends, we will insert the endio work into the
  dedicated btrfs workqueue, not common read endio workqueue, because the
  original endio work is still blocked in the btrfs endio workqueue, if we
  insert the endio work of the io on the mirror into that workqueue, deadlock
  would happen.
- After we get right data, we write it back to the corrupted mirror.
- And if the data on the new mirror is still corrupted, we will try next
  mirror until we read right data or all the mirrors are traversed.
- After the above work, we set the uptodate flag according to the result.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: Set real mirror number for read operation on RAID0/5/6
Miao Xie [Fri, 12 Sep 2014 10:44:02 +0000 (18:44 +0800)]
Btrfs: Set real mirror number for read operation on RAID0/5/6

We need real mirror number for RAID0/5/6 when reading data, or if read error
happens, we would pass 0 as the number of the mirror on which the io error
happens. It is wrong and would cause the filesystem read the data from the
corrupted mirror again.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: modify clean_io_failure and make it suit direct io
Miao Xie [Fri, 12 Sep 2014 10:44:01 +0000 (18:44 +0800)]
Btrfs: modify clean_io_failure and make it suit direct io

We could not use clean_io_failure in the direct IO path because it got the
filesystem information from the page structure, but the page in the direct
IO bio didn't have the filesystem information in its structure. So we need
modify it and pass all the information it need by parameters.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: modify repair_io_failure and make it suit direct io
Miao Xie [Fri, 12 Sep 2014 10:44:00 +0000 (18:44 +0800)]
Btrfs: modify repair_io_failure and make it suit direct io

The original code of repair_io_failure was just used for buffered read,
because it got some filesystem data from page structure, it is safe for
the page in the page cache. But when we do a direct read, the pages in bio
are not in the page cache, that is there is no filesystem data in the page
structure. In order to implement direct read data repair, we need modify
repair_io_failure and pass all filesystem data it need by function
parameters.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: split bio_readpage_error into several functions
Miao Xie [Fri, 12 Sep 2014 10:43:59 +0000 (18:43 +0800)]
Btrfs: split bio_readpage_error into several functions

The data repair function of direct read will be implemented later, and some code
in bio_readpage_error will be reused, so split bio_readpage_error into
several functions which will be used in direct read repair later.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: Cleanup unused variant and argument of IO failure handlers
Miao Xie [Fri, 12 Sep 2014 10:43:58 +0000 (18:43 +0800)]
Btrfs: Cleanup unused variant and argument of IO failure handlers

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix missing error handler if submiting re-read bio fails
Miao Xie [Fri, 12 Sep 2014 10:43:57 +0000 (18:43 +0800)]
Btrfs: fix missing error handler if submiting re-read bio fails

We forgot to free failure record and bio after submitting re-read bio failed,
fix it.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: do file data check by sub-bio's self
Miao Xie [Fri, 12 Sep 2014 10:43:56 +0000 (18:43 +0800)]
Btrfs: do file data check by sub-bio's self

Direct IO splits the original bio to several sub-bios because of the limit of
raid stripe, and the filesystem will wait for all sub-bios and then run final
end io process.

But it was very hard to implement the data repair when dio read failure happens,
because at the final end io function, we didn't know which mirror the data was
read from. So in order to implement the data repair, we have to move the file data
check in the final end io function to the sub-bio end io function, in which we can
get the mirror number of the device we access. This patch did this work as the
first step of the direct io data repair implementation.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: cleanup similar code of the buffered data data check and dio read data check
Miao Xie [Fri, 12 Sep 2014 10:43:55 +0000 (18:43 +0800)]
Btrfs: cleanup similar code of the buffered data data check and dio read data check

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: load checksum data once when submitting a direct read io
Miao Xie [Fri, 12 Sep 2014 10:43:54 +0000 (18:43 +0800)]
Btrfs: load checksum data once when submitting a direct read io

The current code would load checksum data for several times when we split
a whole direct read io because of the limit of the raid stripe, it would
make us search the csum tree for several times. In fact, it just wasted time,
and made the contention of the csum tree root be more serious. This patch
improves this problem by loading the data at once.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: modify rw_devices counter under chunk_mutex context
Miao Xie [Wed, 3 Sep 2014 13:35:47 +0000 (21:35 +0800)]
Btrfs: modify rw_devices counter under chunk_mutex context

rw_devices counter is often used to tune the profile when doing chunk allocation,
so we should modify it under the chunk_mutex context to avoid getting wrong
chunk profile.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: move the missing device to its own fs device list
Miao Xie [Wed, 3 Sep 2014 13:35:46 +0000 (21:35 +0800)]
Btrfs: move the missing device to its own fs device list

For a missing device, we don't know it belong to which fs before we read its
fsid from the chunk tree. So we add them into the current fs device list at first.
When we get its fsid, we should move them to their own fs device list.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: stop mounting the fs if the non-ENOENT errors happen when opening seed fs
Miao Xie [Wed, 3 Sep 2014 13:35:45 +0000 (21:35 +0800)]
Btrfs: stop mounting the fs if the non-ENOENT errors happen when opening seed fs

When we open a seed filesystem, if the degraded mount option is set, we continue to
mount the fs if we don't find some devices in the seed filesystem. But we should stop
mounting if other errors happen. Fix it

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: make the logic of source device removing more clear
Miao Xie [Wed, 3 Sep 2014 13:35:44 +0000 (21:35 +0800)]
Btrfs: make the logic of source device removing more clear

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix use-after-free problem of the device during device replace
Miao Xie [Wed, 3 Sep 2014 13:35:43 +0000 (21:35 +0800)]
Btrfs: fix use-after-free problem of the device during device replace

The problem is:
Task0(device scan task) Task1(device replace task)
scan_one_device()
mutex_lock(&uuid_mutex)
device = find_device()
mutex_lock(&device_list_mutex)
lock_chunk()
rm_and_free_source_device
unlock_chunk()
mutex_unlock(&device_list_mutex)
check device

Destroying the target device if device replace fails also has the same problem.

We fix this problem by locking uuid_mutex during destroying source device or
target device, just like the device remove operation.

It is a temporary solution, we can fix this problem and make the code more
clear by atomic counter in the future.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix unprotected device list access when cloning fs devices
Miao Xie [Wed, 3 Sep 2014 13:35:42 +0000 (21:35 +0800)]
Btrfs: fix unprotected device list access when cloning fs devices

We can build a new filesystem based a seed filesystem, and we need clone
the fs devices when we open the new filesystem. But someone might clear
the seed flag of the seed filesystem, then mount that filesystem and
remove some device. If we mount the new filesystem, we might access
a device list which was being changed when we clone the fs devices.
Fix it.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: Fix misuse of chunk mutex
Miao Xie [Wed, 3 Sep 2014 13:35:41 +0000 (21:35 +0800)]
Btrfs: Fix misuse of chunk mutex

There were several problems about chunk mutex usage:
- Lock chunk mutex when updating metadata. It would cause the nested
  deadlock because updating metadata might need allocate new chunks
  that need acquire chunk mutex. We remove chunk mutex at this case,
  because b-tree lock and other lock mechanism can help us.
- ABBA deadlock occured between device_list_mutex and chunk_mutex.
  When we update device status, we must acquire device_list_mutex at the
  beginning, and then we might get chunk_mutex during the device status
  update because we need allocate new chunks for metadata COW. But at
  most place, we acquire chunk_mutex at first and then acquire device list
  mutex. We need change the lock order.
- Some place we needn't acquire chunk_mutex. For example we needn't get
  chunk_mutex when we free a empty seed fs_devices structure.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix unprotected device list access when getting the fs information
Miao Xie [Wed, 3 Sep 2014 13:35:40 +0000 (21:35 +0800)]
Btrfs: fix unprotected device list access when getting the fs information

When we get the fs information, we forgot to acquire the mutex of device list,
it might cause the problem we might access a device that was removed. Fix
it by acquiring the device list mutex.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix unprotected system chunk array insertion
Miao Xie [Wed, 3 Sep 2014 13:35:39 +0000 (21:35 +0800)]
Btrfs: fix unprotected system chunk array insertion

We didn't protect the system chunk array when we added a new
system chunk into it, it would cause the array be corrupted
if someone remove/add some system chunk into array at the same
time. Fix it by chunk lock.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix unprotected device's variants on 32bits machine
Miao Xie [Wed, 3 Sep 2014 13:35:38 +0000 (21:35 +0800)]
Btrfs: fix unprotected device's variants on 32bits machine

->total_bytes,->disk_total_bytes,->bytes_used is protected by chunk
lock when we change them, but sometimes we read them without any lock,
and we might get unexpected value. We fix this problem like inode's
i_size.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: update free_chunk_space during allocting a new chunk
Miao Xie [Wed, 3 Sep 2014 13:35:37 +0000 (21:35 +0800)]
Btrfs: update free_chunk_space during allocting a new chunk

We should update free_chunk_space in time when we allocate a new chunk,
not when we deal with the pending device update and block group insertion,
because we need the real free_chunk_space data to calculate the reserved
space, if we don't update it in time, we would consider the disk space which
has be allocated as free space, and would use it to do overcommit reservation.
Fix it.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix unprotected device->bytes_used update
Miao Xie [Wed, 3 Sep 2014 13:35:36 +0000 (21:35 +0800)]
Btrfs: fix unprotected device->bytes_used update

We should update device->bytes_used in the lock context of
chunk_mutex, or we would get wrong data.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: Fix wrong free_chunk_space assignment during removing a device
Miao Xie [Wed, 3 Sep 2014 13:35:35 +0000 (21:35 +0800)]
Btrfs: Fix wrong free_chunk_space assignment during removing a device

During removing a device, we have modified free_chunk_space when we
shrink the device, so we needn't assign a new value to it after
the device shrink. Fix it.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix wrong device bytes_used in the super block
Miao Xie [Wed, 3 Sep 2014 13:35:34 +0000 (21:35 +0800)]
Btrfs: fix wrong device bytes_used in the super block

device->bytes_used will be changed when allocating a new chunk, and
disk_total_size will be changed if resizing is successful.
Meanwhile, the on-disk super blocks of the previous transaction
might not be updated. Considering the consistency of the metadata
in the previous transaction, We should use the size in the previous
transaction to check if the super block is beyond the boundary
of the device.

Though it is not big problem because we don't use it now, but anyway
it is better that we make it be consistent with the common metadata,
maybe we will use it in the future.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix wrong disk size when writing super blocks
Miao Xie [Wed, 3 Sep 2014 13:35:33 +0000 (21:35 +0800)]
Btrfs: fix wrong disk size when writing super blocks

total_size will be changed when resizing a device, and disk_total_size
will be changed if resizing is successful. Meanwhile, the on-disk super
blocks of the previous transaction might not be updated. Considering
the consistency of the metadata in the previous transaction, We should
use the size in the previous transaction to check if the super block is
beyond the boundary of the device. Fix it.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix unprotected assignment of the target device
Miao Xie [Wed, 3 Sep 2014 13:35:32 +0000 (21:35 +0800)]
Btrfs: fix unprotected assignment of the target device

We didn't protect the assignment of the target device, it might cause the
problem that the super block update was skipped because we might find wrong
size of the target device during the assignment. Fix it by moving the
assignment sentences into the initialization function of the target device.
And there is another merit that we can check if the target device is suitable
more early.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: cleanup double assignment of device->bytes_used when device replace finishes
Miao Xie [Wed, 3 Sep 2014 13:35:31 +0000 (21:35 +0800)]
Btrfs: cleanup double assignment of device->bytes_used when device replace finishes

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: cleanup unused num_can_discard in fs_devices
Miao Xie [Wed, 3 Sep 2014 13:35:30 +0000 (21:35 +0800)]
Btrfs: cleanup unused num_can_discard in fs_devices

The member variants - num_can_discard - of fs_devices structure
are set, but no one use them to do anything. so remove them.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agobtrfs: remove the wrong comments
Li RongQing [Mon, 8 Sep 2014 12:41:09 +0000 (20:41 +0800)]
btrfs: remove the wrong comments

This comments became wrong after c3c532[bdi: add helper function for
doing init and register of a bdi for a file system], so remove them.

Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix directory recovery from fsync log
Filipe Manana [Mon, 8 Sep 2014 21:53:18 +0000 (22:53 +0100)]
Btrfs: fix directory recovery from fsync log

When replaying a directory from the fsync log, if a directory entry
exists both in the fs/subvol tree and in the log, the directory's inode
got its i_size updated incorrectly, accounting for the dentry's name
twice.

Reproducer, from a test for xfstests:

    _scratch_mkfs >> $seqres.full 2>&1
    _init_flakey
    _mount_flakey

    touch $SCRATCH_MNT/foo
    sync

    touch $SCRATCH_MNT/bar
    xfs_io -c "fsync" $SCRATCH_MNT
    xfs_io -c "fsync" $SCRATCH_MNT/bar

    _load_flakey_table $FLAKEY_DROP_WRITES
    _unmount_flakey

    _load_flakey_table $FLAKEY_ALLOW_WRITES
    _mount_flakey

    [ -f $SCRATCH_MNT/foo ] || echo "file foo is missing"
    [ -f $SCRATCH_MNT/bar ] || echo "file bar is missing"

    _unmount_flakey
    _check_scratch_fs $FLAKEY_DEV

The filesystem check at the end failed with the message:
"root 5 root dir 256 error".

A test case for xfstests follows.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: fix loop writing of async reclaim
Liu Bo [Wed, 10 Sep 2014 04:58:50 +0000 (12:58 +0800)]
Btrfs: fix loop writing of async reclaim

One of my tests shows that when we really don't have space to reclaim via
flush_space and also run out of space, this async reclaim work loops on adding
itself into the workqueue and keeps writing something to disk according to
iostat's results, and these writes mainly comes from commit_transaction which
writes super_block.  This's unacceptable as it can be bad to disks, especially
memeory storages.

This adds a check to avoid the above situation.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: make fiemap not blow when you have lots of snapshots
Josef Bacik [Wed, 10 Sep 2014 20:20:45 +0000 (16:20 -0400)]
Btrfs: make fiemap not blow when you have lots of snapshots

We have been iterating all references for each extent we have in a file when we
do fiemap to see if it is shared.  This is fine when you have a few clones or a
few snapshots, but when you have 5k snapshots suddenly fiemap just sits there
and stares at you.  So add btrfs_check_shared which will use the backref walking
code but will short circuit as soon as it finds a root or inode that doesn't
match the one we currently have.  This makes fiemap on my testbox go from
looking at me blankly for a day to spitting out actual output in a reasonable
amount of time.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: add missing compression property remove in btrfs_ioctl_setflags
Filipe Manana [Thu, 11 Sep 2014 10:44:49 +0000 (11:44 +0100)]
Btrfs: add missing compression property remove in btrfs_ioctl_setflags

The behaviour of a 'chattr -c' consists of getting the current flags,
clearing the FS_COMPR_FL bit and then sending the result to the set
flags ioctl - this means the bit FS_NOCOMP_FL isn't set in the flags
passed to the ioctl. This results in the compression property not being
cleared from the inode - it was cleared only if the bit FS_NOCOMP_FL
was set in the received flags.

Reproducer:

    $ mkfs.btrfs -f /dev/sdd
    $ mount /dev/sdd /mnt && cd /mnt
    $ mkdir a
    $ chattr +c a
    $ touch a/file
    $ lsattr a/file
    --------c------- a/file
    $ chattr -c a
    $ touch a/file2
    $ lsattr a/file2
    --------c------- a/file2
    $ lsattr -d a
    ---------------- a

Reported-by: Andreas Schneider <asn@cryptomilk.org>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agobtrfs: Fix a deadlock in btrfs_dev_replace_finishing()
Qu Wenruo [Wed, 20 Aug 2014 08:10:15 +0000 (16:10 +0800)]
btrfs: Fix a deadlock in btrfs_dev_replace_finishing()

btrfs-transacion:5657
[stack snip]
btrfs_bio_map()
    btrfs_bio_counter_inc_blocked()
        percpu_counter_inc(&fs_info->bio_counter)  ###bio_counter > 0(A)
        __btrfs_bio_map()
            btrfs_dev_replace_lock()
                mutex_lock(dev_replace->lock)    ###wait mutex(B)

btrfs:32612
[stack snip]
btrfs_dev_replace_start()
    btrfs_dev_replace_lock()
mutex_lock(dev_replace->lock)    ###hold mutex(B)
    btrfs_dev_replace_finishing()
        btrfs_rm_dev_replace_blocked()
            wait until percpu_counter_sum == 0    ###wait on bio_counter(A)

This bug can be triggered quite easily by the following test script:
http://pastebin.com/MQmb37Cy

This patch will fix the ABBA problem by calling
btrfs_dev_replace_unlock() before btrfs_rm_dev_replace_blocked().

The consistency of btrfs devices list and their superblocks is protected
by device_list_mutex, not btrfs_dev_replace_lock/unlock().
So it is safe the move btrfs_dev_replace_unlock() before
btrfs_rm_dev_replace_blocked().

Reported-by: Zhao Lei <zhaolei@cn.fujitsu.com>
Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Cc: Stefan Behrens <sbehrens@giantdisaster.de>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: cleanup the same name in end_bio_extent_readpage
Liu Bo [Tue, 19 Aug 2014 15:32:22 +0000 (23:32 +0800)]
Btrfs: cleanup the same name in end_bio_extent_readpage

We've defined a 'offset' out of bio_for_each_segment_all.

This is just a clean rename, no function changes.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agobtrfs: don't go readonly on existing qgroup items
Mark Fasheh [Mon, 18 Aug 2014 21:01:17 +0000 (14:01 -0700)]
btrfs: don't go readonly on existing qgroup items

btrfs_drop_snapshot() leaves subvolume qgroup items on disk after
completion. This can cause problems with snapshot creation. If a new
snapshot tries to claim the deleted subvolumes id, btrfs will get -EEXIST
from add_qgroup_item() and go read-only. The following commands will
reproduce this problem (assume btrfs is on /dev/sda and is mounted at
/btrfs)

mkfs.btrfs -f /dev/sda
mount -t btrfs /dev/sda /btrfs/
btrfs quota enable /btrfs/
btrfs su sna /btrfs/ /btrfs/snap
btrfs su de /btrfs/snap
sleep 45
umount /btrfs/
mount -t btrfs /dev/sda /btrfs/

We can fix this by catching -EEXIST in add_qgroup_item() and
initializing the existing items. We have the problem of orphaned
relation items being on disk from an old snapshot but that is outside
the scope of this patch.

Signed-off-by: Mark Fasheh <mfasheh@suse.de>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: show real function name in btrfs workqueue tracepoint
Liu Bo [Fri, 15 Aug 2014 15:38:06 +0000 (23:38 +0800)]
Btrfs: show real function name in btrfs workqueue tracepoint

Use %pf instead of %p, just same as kernel workqueue tracepoints.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: shrink further sizeof(struct extent_buffer)
Filipe Manana [Thu, 14 Aug 2014 11:25:14 +0000 (12:25 +0100)]
Btrfs: shrink further sizeof(struct extent_buffer)

The map_start and map_len fields aren't used anywhere, so just remove
them. On a x86_64 system, this reduced sizeof(struct extent_buffer)
from 296 bytes to 280 bytes, and therefore 14 extent_buffer structs can
now fit into a page instead of 13.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: send, lower mem requirements for processing xattrs
Filipe Manana [Wed, 20 Aug 2014 09:45:45 +0000 (10:45 +0100)]
Btrfs: send, lower mem requirements for processing xattrs

Maximum xattr size can be up to nearly the leaf size. For an fs with a
leaf size larger than the page size, using kmalloc requires allocating
multiple pages that are contiguous, which might not be possible if
there's heavy memory fragmentation. Therefore fallback to vmalloc if
we fail to allocate with kmalloc. Also start with a smaller buffer size,
since xattr values typically are smaller than a page.

Reported-by: Chris Murphy <lists@colorremedies.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agobtrfs: remove stale define after removing ordered operations
David Sterba [Wed, 20 Aug 2014 15:34:22 +0000 (17:34 +0200)]
btrfs: remove stale define after removing ordered operations

Last user removed in commit "btrfs: disable strict file flushes for
renames and truncates" (8d875f95da43c6a8f18f77869f2ef26e9594fecc).

Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agoBtrfs: improve free space cache management and space allocation
Filipe Manana [Fri, 29 Aug 2014 12:35:13 +0000 (13:35 +0100)]
Btrfs: improve free space cache management and space allocation

While under random IO, a block group's free space cache eventually reaches
a state where it has a mix of extent entries and bitmap entries representing
free space regions.

As later free space regions are returned to the cache, some of them are merged
with existing extent entries if they are contiguous with them. But others are
not merged, because despite the existence of adjacent free space regions in
the cache, the merging doesn't happen because the existing free space regions
are represented in bitmap extents. Even when new free space regions are merged
with existing extent entries (enlarging the free space range they represent),
we create chances of having after an enlarged region that is contiguous with
some other region represented in a bitmap entry.

Both clustered and non-clustered space allocation work by iterating over our
extent and bitmap entries and skipping any that represents a region smaller
then the allocation request (and giving preference to extent entries before
bitmap entries). By having a contiguous free space region that is represented
by 2 (or more) entries (mix of extent and bitmap entries), we end up not
satisfying an allocation request with a size larger than the size of any of
the entries but no larger than the sum of their sizes. Making the caller assume
we're under a ENOSPC condition or force it to allocate multiple smaller space
regions (as we do for file data writes), which adds extra overhead and more
chances of causing fragmentation due to the smaller regions being all spread
apart from each other (more likely when under concurrency).

For example, if we have the following in the cache:

* extent entry representing free space range: [128Mb - 256Kb, 128Mb[

* bitmap entry covering the range [128Mb, 256Mb[, but only with the bits
  representing the range [128Mb, 128Mb + 768Kb[ set - that is, only that
  space in this 128Mb area is marked as free

An allocation request for 1Mb, starting at offset not greater than 128Mb - 256Kb,
would fail before, despite the existence of such contiguous free space area in the
cache. The caller could only allocate up to 768Kb of space at once and later another
256Kb (or vice-versa). In between each smaller allocation request, another task
working on a different file/inode might come in and take that space, preventing the
former task of getting a contiguous 1Mb region of free space.

Therefore this change implements the ability to move free space from bitmap
entries into existing and new free space regions represented with extent
entries. This is done when a space region is added to the cache.

A test was added to the sanity tests that explains in detail the issue too.

Some performance test results with compilebench on a 4 cores machine, with
32Gb of ram and using an HDD follow.

Test: compilebench -D /mnt -i 30 -r 1000 --makej

Before this change:

   intial create total runs 30 avg 69.02 MB/s (user 0.28s sys 0.57s)
   compile total runs 30 avg 314.96 MB/s (user 0.12s sys 0.25s)
   read compiled tree total runs 3 avg 27.14 MB/s (user 1.52s sys 0.90s)
   delete compiled tree total runs 30 avg 3.14 seconds (user 0.15s sys 0.66s)

After this change:

   intial create total runs 30 avg 68.37 MB/s (user 0.29s sys 0.55s)
   compile total runs 30 avg 382.83 MB/s (user 0.12s sys 0.24s)
   read compiled tree total runs 3 avg 27.82 MB/s (user 1.45s sys 0.97s)
   delete compiled tree total runs 30 avg 3.18 seconds (user 0.17s sys 0.65s)

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agobtrfs: rename total_bytes to avoid confusion
Anand Jain [Wed, 20 Aug 2014 02:54:17 +0000 (10:54 +0800)]
btrfs: rename total_bytes to avoid confusion

we are assigning number_devices to the total_bytes,
that's very confusing for a moment

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agobtrfs: fix typo in the log message
Anand Jain [Wed, 13 Aug 2014 06:24:25 +0000 (14:24 +0800)]
btrfs: fix typo in the log message

there is no matching open parenthesis for the closing parenthesis

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: Chris Mason <clm@fb.com>
10 years agobtrfs: rw_devices shouldn't be incremented for seed fs in btrfs_rm_dev_replace_srcdev()
Anand Jain [Wed, 13 Aug 2014 06:24:24 +0000 (14:24 +0800)]
btrfs: rw_devices shouldn't be incremented for seed fs in btrfs_rm_dev_replace_srcdev()

seed fs devices don't participate as rw_device, so don't increment
rw_devices when the device being handled belongs to a seed fs.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: Chris Mason <clm@fb.com>