<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel.git/fs/btrfs/disk-io.c, branch linux-3.4.y</title>
<subtitle>Hosts the 0x221E linux distro kernel.
</subtitle>
<id>https://git.0xinfinity.dev/distro/kernel.git/atom?h=linux-3.4.y</id>
<link rel='self' href='https://git.0xinfinity.dev/distro/kernel.git/atom?h=linux-3.4.y'/>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/'/>
<updated>2015-04-14T09:33:45Z</updated>
<entry>
<title>Btrfs: fix fs corruption on transaction abort if device supports discard</title>
<updated>2015-04-14T09:33:45Z</updated>
<author>
<name>Filipe Manana</name>
</author>
<published>2014-12-07T21:31:47Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=11b814e3597eeffa475e2e41323aa52d2e2289fa'/>
<id>urn:sha1:11b814e3597eeffa475e2e41323aa52d2e2289fa</id>
<content type='text'>
commit 678886bdc6378c1cbd5072da2c5a3035000214e3 upstream.

When we abort a transaction we iterate over all the ranges marked as dirty
in fs_info-&gt;freed_extents[0] and fs_info-&gt;freed_extents[1], clear them
from those trees, add them back (unpin) to the free space caches and, if
the fs was mounted with "-o discard", perform a discard on those regions.
Also, after adding the regions to the free space caches, a fitrim ioctl call
can see those ranges in a block group's free space cache and perform a discard
on the ranges, so the same issue can happen without "-o discard" as well.

This causes corruption, affecting one or multiple btree nodes (in the worst
case leaving the fs unmountable) because some of those ranges (the ones in
the fs_info-&gt;pinned_extents tree) correspond to btree nodes/leafs that are
referred by the last committed super block - breaking the rule that anything
that was committed by a transaction is untouched until the next transaction
commits successfully.

I ran into this while running in a loop (for several hours) the fstest that
I recently submitted:

  [PATCH] fstests: add btrfs test to stress chunk allocation/removal and fstrim

The corruption always happened when a transaction aborted and then fsck complained
like this:

   _check_btrfs_filesystem: filesystem on /dev/sdc is inconsistent
   *** fsck.btrfs output ***
   Check tree block failed, want=94945280, have=0
   Check tree block failed, want=94945280, have=0
   Check tree block failed, want=94945280, have=0
   Check tree block failed, want=94945280, have=0
   Check tree block failed, want=94945280, have=0
   read block failed check_tree_block
   Couldn't open file system

In this case 94945280 corresponded to the root of a tree.
Using frace what I observed was the following sequence of steps happened:

   1) transaction N started, fs_info-&gt;pinned_extents pointed to
      fs_info-&gt;freed_extents[0];

   2) node/eb 94945280 is created;

   3) eb is persisted to disk;

   4) transaction N commit starts, fs_info-&gt;pinned_extents now points to
      fs_info-&gt;freed_extents[1], and transaction N completes;

   5) transaction N + 1 starts;

   6) eb is COWed, and btrfs_free_tree_block() called for this eb;

   7) eb range (94945280 to 94945280 + 16Kb) is added to
      fs_info-&gt;pinned_extents (fs_info-&gt;freed_extents[1]);

   8) Something goes wrong in transaction N + 1, like hitting ENOSPC
      for example, and the transaction is aborted, turning the fs into
      readonly mode. The stack trace I got for example:

      [112065.253935]  [&lt;ffffffff8140c7b6&gt;] dump_stack+0x4d/0x66
      [112065.254271]  [&lt;ffffffff81042984&gt;] warn_slowpath_common+0x7f/0x98
      [112065.254567]  [&lt;ffffffffa0325990&gt;] ? __btrfs_abort_transaction+0x50/0x10b [btrfs]
      [112065.261674]  [&lt;ffffffff810429e5&gt;] warn_slowpath_fmt+0x48/0x50
      [112065.261922]  [&lt;ffffffffa032949e&gt;] ? btrfs_free_path+0x26/0x29 [btrfs]
      [112065.262211]  [&lt;ffffffffa0325990&gt;] __btrfs_abort_transaction+0x50/0x10b [btrfs]
      [112065.262545]  [&lt;ffffffffa036b1d6&gt;] btrfs_remove_chunk+0x537/0x58b [btrfs]
      [112065.262771]  [&lt;ffffffffa033840f&gt;] btrfs_delete_unused_bgs+0x1de/0x21b [btrfs]
      [112065.263105]  [&lt;ffffffffa0343106&gt;] cleaner_kthread+0x100/0x12f [btrfs]
      (...)
      [112065.264493] ---[ end trace dd7903a975a31a08 ]---
      [112065.264673] BTRFS: error (device sdc) in btrfs_remove_chunk:2625: errno=-28 No space left
      [112065.264997] BTRFS info (device sdc): forced readonly

   9) The clear kthread sees that the BTRFS_FS_STATE_ERROR bit is set in
      fs_info-&gt;fs_state and calls btrfs_cleanup_transaction(), which in
      turn calls btrfs_destroy_pinned_extent();

   10) Then btrfs_destroy_pinned_extent() iterates over all the ranges
       marked as dirty in fs_info-&gt;freed_extents[], and for each one
       it calls discard, if the fs was mounted with "-o discard", and
       adds the range to the free space cache of the respective block
       group;

   11) btrfs_trim_block_group(), invoked from the fitrim ioctl code path,
       sees the free space entries and performs a discard;

   12) After an umount and mount (or fsck), our eb's location on disk was full
       of zeroes, and it should have been untouched, because it was marked as
       dirty in the fs_info-&gt;pinned_extents tree, and therefore used by the
       trees that the last committed superblock points to.

Fix this by not performing a discard and not adding the ranges to the free space
caches - it's useless from this point since the fs is now in readonly mode and
we won't write free space caches to disk anymore (otherwise we would leak space)
nor any new superblock. By not adding the ranges to the free space caches, it
prevents other code paths from allocating that space and write to it as well,
therefore being safer and simpler.

This isn't a new problem, as it's been present since 2011 (git commit
acce952b0263825da32cf10489413dec78053347).

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
Signed-off-by: Zefan Li &lt;lizefan@huawei.com&gt;
</content>
</entry>
<entry>
<title>Btrfs: avoid sleeping in verify_parent_transid while atomic</title>
<updated>2012-05-06T11:23:47Z</updated>
<author>
<name>Chris Mason</name>
</author>
<published>2012-05-06T11:23:47Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=b9fab919b748c7b39c19ff236ed6c5682c266dde'/>
<id>urn:sha1:b9fab919b748c7b39c19ff236ed6c5682c266dde</id>
<content type='text'>
verify_parent_transid needs to lock the extent range to make
sure no IO is underway, and so it can safely clear the
uptodate bits if our checks fail.

But, a few callers are using it with spinlocks held.  Most
of the time, the generation numbers are going to match, and
we don't want to switch to a blocking lock just for the error
case.  This adds an atomic flag to verify_parent_transid,
and changes it to return EAGAIN if it needs to block to
properly verifiy things.

Signed-off-by: Chris Mason &lt;chris.mason@oracle.com&gt;
</content>
</entry>
<entry>
<title>Btrfs: always store the mirror we read the eb from</title>
<updated>2012-04-18T17:22:30Z</updated>
<author>
<name>Josef Bacik</name>
</author>
<published>2012-04-16T13:42:26Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=5cf1ab56133ad7b712673c071b439d4a555a2d1e'/>
<id>urn:sha1:5cf1ab56133ad7b712673c071b439d4a555a2d1e</id>
<content type='text'>
A user reported a panic where we were trying to fix a bad mirror but the
mirror number we were giving was 0, which is invalid.  This is because we
don't do the transid verification until after the read, so as far as the
read code is concerned the read was a success.  So instead store the mirror
we read from so that if there is some failure post read we know which mirror
to try next and which mirror needs to be fixed if we find a good copy of the
block.  Thanks,

Signed-off-by: Josef Bacik &lt;josef@redhat.com&gt;
</content>
</entry>
<entry>
<title>Btrfs: do not mount when we have a sectorsize unequal to PAGE_SIZE</title>
<updated>2012-04-18T17:22:13Z</updated>
<author>
<name>Liu Bo</name>
</author>
<published>2012-04-03T01:56:53Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=8d082fb727ac11930ea20bf1612e334ea7c2b697'/>
<id>urn:sha1:8d082fb727ac11930ea20bf1612e334ea7c2b697</id>
<content type='text'>
Our code is not ready to cope with a sectorsize that's not equal to PAGE_SIZE.
It will lead to hanging-on while writing something.

Signed-off-by: Liu Bo &lt;liubo2009@cn.fujitsu.com&gt;
</content>
</entry>
<entry>
<title>Btrfs: update the checks for mixed block groups with big metadata blocks</title>
<updated>2012-03-29T21:02:47Z</updated>
<author>
<name>Chris Mason</name>
</author>
<published>2012-03-29T21:02:47Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=bc3f116fec194f1d7329b160c266fe16b9266a1e'/>
<id>urn:sha1:bc3f116fec194f1d7329b160c266fe16b9266a1e</id>
<content type='text'>
Dave Sterba had put in patches to look for mixed data/metadata groups
with metadata bigger than 4KB.  But these ended up in the wrong place
and it wasn't testing the feature flag correctly.

This updates the tests to make sure our sizes are matching

Signed-off-by: Chris Mason &lt;chris.mason@oracle.com&gt;
</content>
</entry>
<entry>
<title>Btrfs: flush out and clean up any block device pages during mount</title>
<updated>2012-03-29T00:33:58Z</updated>
<author>
<name>Chris Mason</name>
</author>
<published>2012-03-27T22:56:56Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=3c4bb26b213e618473e486776483a5bad15ba6da'/>
<id>urn:sha1:3c4bb26b213e618473e486776483a5bad15ba6da</id>
<content type='text'>
Btrfs puts the filesystem metadata into its own address space, and
somehow the block device address space isn't getting onto disk properly
before a mount.  The end result is that a loop of mkfs and mounting the
filesystem will sometimes find stale or incorrect data.

This commit should fix it by sprinkling fdatawrites and invalidate_bdev
calls around.  This is a short term measure to make sure it is fixed.
The block devices really should be flushed and cleaned up higher in the
stack.

Signed-off-by: Chris Mason &lt;chris.mason@oracle.com&gt;
</content>
</entry>
<entry>
<title>Merge branch 'error-handling' into for-linus</title>
<updated>2012-03-29T00:31:37Z</updated>
<author>
<name>Chris Mason</name>
</author>
<published>2012-03-29T00:31:37Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=1d4284bd6e8d7dd1d5521a6747bdb6dc1caf0225'/>
<id>urn:sha1:1d4284bd6e8d7dd1d5521a6747bdb6dc1caf0225</id>
<content type='text'>
Conflicts:
	fs/btrfs/ctree.c
	fs/btrfs/disk-io.c
	fs/btrfs/extent-tree.c
	fs/btrfs/extent_io.c
	fs/btrfs/extent_io.h
	fs/btrfs/inode.c
	fs/btrfs/scrub.c

Signed-off-by: Chris Mason &lt;chris.mason@oracle.com&gt;
</content>
</entry>
<entry>
<title>btrfs: disallow unequal data/metadata blocksize for mixed block groups</title>
<updated>2012-03-29T00:30:28Z</updated>
<author>
<name>David Sterba</name>
</author>
<published>2012-02-17T11:26:09Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=65139ed99234d8505948cdb7a835452eb5c191f9'/>
<id>urn:sha1:65139ed99234d8505948cdb7a835452eb5c191f9</id>
<content type='text'>
With support for bigger metadata blocks, we must avoid mounting a
filesystem with different block size for mixed block groups, this causes
corruption (found by xfstests/083).

Signed-off-by: David Sterba &lt;dsterba@suse.cz&gt;
</content>
</entry>
<entry>
<title>Btrfs: enhance superblock sanity checks</title>
<updated>2012-03-29T00:30:28Z</updated>
<author>
<name>David Sterba</name>
</author>
<published>2012-03-05T23:06:18Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=fcd1f065daca593badb7f99d473639cf3b551795'/>
<id>urn:sha1:fcd1f065daca593badb7f99d473639cf3b551795</id>
<content type='text'>
Validate checksum algorithm during mount and prevent BUG_ON later in
btrfs_super_csum_size.

Signed-off-by: David Sterba &lt;dsterba@suse.cz&gt;
</content>
</entry>
<entry>
<title>Btrfs: deal with read errors on extent buffers differently</title>
<updated>2012-03-27T01:57:36Z</updated>
<author>
<name>Josef Bacik</name>
</author>
<published>2012-03-27T01:57:36Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=ea466794084f55d8fcc100711cf17923bf57e962'/>
<id>urn:sha1:ea466794084f55d8fcc100711cf17923bf57e962</id>
<content type='text'>
Since we need to read and write extent buffers in their entirety we can't use
the normal bio_readpage_error stuff since it only works on a per page basis.  So
instead make it so that if we see an io error in endio we just mark the eb as
having an IO error and then in btree_read_extent_buffer_pages we will manually
try other mirrors and then overwrite the bad mirror if we find a good copy.
This works with larger than page size blocks.  Thanks,

Signed-off-by: Josef Bacik &lt;josef@redhat.com&gt;
Signed-off-by: Chris Mason &lt;chris.mason@oracle.com&gt;
</content>
</entry>
</feed>
