<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-stable.git/fs/btrfs, branch linux-3.4.y</title>
<subtitle>Linux kernel stable tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/'/>
<entry>
<title>Btrfs: fix race leading to BUG_ON when running delalloc for nodatacow</title>
<updated>2016-10-26T15:15:28+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2015-11-09T00:33:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=c9a5c53a3165129becc2f17d7abd5fc3f200dbc1'/>
<id>c9a5c53a3165129becc2f17d7abd5fc3f200dbc1</id>
<content type='text'>
commit 1d512cb77bdbda80f0dd0620a3b260d697fd581d upstream.

If we are using the NO_HOLES feature, we have a tiny time window when
running delalloc for a nodatacow inode where we can race with a concurrent
link or xattr add operation leading to a BUG_ON.

This happens because at run_delalloc_nocow() we end up casting a leaf item
of type BTRFS_INODE_[REF|EXTREF]_KEY or of type BTRFS_XATTR_ITEM_KEY to a
file extent item (struct btrfs_file_extent_item) and then analyse its
extent type field, which won't match any of the expected extent types
(values BTRFS_FILE_EXTENT_[REG|PREALLOC|INLINE]) and therefore trigger an
explicit BUG_ON(1).

The following sequence diagram shows how the race happens when running a
no-cow dellaloc range [4K, 8K[ for inode 257 and we have the following
neighbour leafs:

             Leaf X (has N items)                    Leaf Y

 [ ... (257 INODE_ITEM 0) (257 INODE_REF 256) ]  [ (257 EXTENT_DATA 8192), ... ]
              slot N - 2         slot N - 1              slot 0

 (Note the implicit hole for inode 257 regarding the [0, 8K[ range)

       CPU 1                                         CPU 2

 run_dealloc_nocow()
   btrfs_lookup_file_extent()
     --&gt; searches for a key with value
         (257 EXTENT_DATA 4096) in the
         fs/subvol tree
     --&gt; returns us a path with
         path-&gt;nodes[0] == leaf X and
         path-&gt;slots[0] == N

   because path-&gt;slots[0] is &gt;=
   btrfs_header_nritems(leaf X), it
   calls btrfs_next_leaf()

   btrfs_next_leaf()
     --&gt; releases the path

                                              hard link added to our inode,
                                              with key (257 INODE_REF 500)
                                              added to the end of leaf X,
                                              so leaf X now has N + 1 keys

     --&gt; searches for the key
         (257 INODE_REF 256), because
         it was the last key in leaf X
         before it released the path,
         with path-&gt;keep_locks set to 1

     --&gt; ends up at leaf X again and
         it verifies that the key
         (257 INODE_REF 256) is no longer
         the last key in the leaf, so it
         returns with path-&gt;nodes[0] ==
         leaf X and path-&gt;slots[0] == N,
         pointing to the new item with
         key (257 INODE_REF 500)

   the loop iteration of run_dealloc_nocow()
   does not break out the loop and continues
   because the key referenced in the path
   at path-&gt;nodes[0] and path-&gt;slots[0] is
   for inode 257, its type is &lt; BTRFS_EXTENT_DATA_KEY
   and its offset (500) is less then our delalloc
   range's end (8192)

   the item pointed by the path, an inode reference item,
   is (incorrectly) interpreted as a file extent item and
   we get an invalid extent type, leading to the BUG_ON(1):

   if (extent_type == BTRFS_FILE_EXTENT_REG ||
      extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
       (...)
   } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
       (...)
   } else {
       BUG_ON(1)
   }

The same can happen if a xattr is added concurrently and ends up having
a key with an offset smaller then the delalloc's range end.

So fix this by skipping keys with a type smaller than
BTRFS_EXTENT_DATA_KEY.

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Signed-off-by: Zefan Li &lt;lizefan@huawei.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 1d512cb77bdbda80f0dd0620a3b260d697fd581d upstream.

If we are using the NO_HOLES feature, we have a tiny time window when
running delalloc for a nodatacow inode where we can race with a concurrent
link or xattr add operation leading to a BUG_ON.

This happens because at run_delalloc_nocow() we end up casting a leaf item
of type BTRFS_INODE_[REF|EXTREF]_KEY or of type BTRFS_XATTR_ITEM_KEY to a
file extent item (struct btrfs_file_extent_item) and then analyse its
extent type field, which won't match any of the expected extent types
(values BTRFS_FILE_EXTENT_[REG|PREALLOC|INLINE]) and therefore trigger an
explicit BUG_ON(1).

The following sequence diagram shows how the race happens when running a
no-cow dellaloc range [4K, 8K[ for inode 257 and we have the following
neighbour leafs:

             Leaf X (has N items)                    Leaf Y

 [ ... (257 INODE_ITEM 0) (257 INODE_REF 256) ]  [ (257 EXTENT_DATA 8192), ... ]
              slot N - 2         slot N - 1              slot 0

 (Note the implicit hole for inode 257 regarding the [0, 8K[ range)

       CPU 1                                         CPU 2

 run_dealloc_nocow()
   btrfs_lookup_file_extent()
     --&gt; searches for a key with value
         (257 EXTENT_DATA 4096) in the
         fs/subvol tree
     --&gt; returns us a path with
         path-&gt;nodes[0] == leaf X and
         path-&gt;slots[0] == N

   because path-&gt;slots[0] is &gt;=
   btrfs_header_nritems(leaf X), it
   calls btrfs_next_leaf()

   btrfs_next_leaf()
     --&gt; releases the path

                                              hard link added to our inode,
                                              with key (257 INODE_REF 500)
                                              added to the end of leaf X,
                                              so leaf X now has N + 1 keys

     --&gt; searches for the key
         (257 INODE_REF 256), because
         it was the last key in leaf X
         before it released the path,
         with path-&gt;keep_locks set to 1

     --&gt; ends up at leaf X again and
         it verifies that the key
         (257 INODE_REF 256) is no longer
         the last key in the leaf, so it
         returns with path-&gt;nodes[0] ==
         leaf X and path-&gt;slots[0] == N,
         pointing to the new item with
         key (257 INODE_REF 500)

   the loop iteration of run_dealloc_nocow()
   does not break out the loop and continues
   because the key referenced in the path
   at path-&gt;nodes[0] and path-&gt;slots[0] is
   for inode 257, its type is &lt; BTRFS_EXTENT_DATA_KEY
   and its offset (500) is less then our delalloc
   range's end (8192)

   the item pointed by the path, an inode reference item,
   is (incorrectly) interpreted as a file extent item and
   we get an invalid extent type, leading to the BUG_ON(1):

   if (extent_type == BTRFS_FILE_EXTENT_REG ||
      extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
       (...)
   } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
       (...)
   } else {
       BUG_ON(1)
   }

The same can happen if a xattr is added concurrently and ends up having
a key with an offset smaller then the delalloc's range end.

So fix this by skipping keys with a type smaller than
BTRFS_EXTENT_DATA_KEY.

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Signed-off-by: Zefan Li &lt;lizefan@huawei.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>btrfs: skip waiting on ordered range for special files</title>
<updated>2016-04-27T10:55:22+00:00</updated>
<author>
<name>Jeff Mahoney</name>
<email>jeffm@suse.com</email>
</author>
<published>2015-09-12T01:44:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=413e7340b4ceac04d90253c25472a221e2f529ff'/>
<id>413e7340b4ceac04d90253c25472a221e2f529ff</id>
<content type='text'>
commit a30e577c96f59b1e1678ea5462432b09bf7d5cbc upstream.

In btrfs_evict_inode, we properly truncate the page cache for evicted
inodes but then we call btrfs_wait_ordered_range for every inode as well.
It's the right thing to do for regular files but results in incorrect
behavior for device inodes for block devices.

filemap_fdatawrite_range gets called with inode-&gt;i_mapping which gets
resolved to the block device inode before getting passed to
wbc_attach_fdatawrite_inode and ultimately to inode_to_bdi.  What happens
next depends on whether there's an open file handle associated with the
inode.  If there is, we write to the block device, which is unexpected
behavior.  If there isn't, we through normally and inode-&gt;i_data is used.
We can also end up racing against open/close which can result in crashes
when i_mapping points to a block device inode that has been closed.

Since there can't be any page cache associated with special file inodes,
it's safe to skip the btrfs_wait_ordered_range call entirely and avoid
the problem.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=100911
Tested-by: Christoph Biedl &lt;linux-kernel.bfrz@manchmal.in-ulm.de&gt;
Signed-off-by: Jeff Mahoney &lt;jeffm@suse.com&gt;
Reviewed-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Signed-off-by: Zefan Li &lt;lizefan@huawei.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit a30e577c96f59b1e1678ea5462432b09bf7d5cbc upstream.

In btrfs_evict_inode, we properly truncate the page cache for evicted
inodes but then we call btrfs_wait_ordered_range for every inode as well.
It's the right thing to do for regular files but results in incorrect
behavior for device inodes for block devices.

filemap_fdatawrite_range gets called with inode-&gt;i_mapping which gets
resolved to the block device inode before getting passed to
wbc_attach_fdatawrite_inode and ultimately to inode_to_bdi.  What happens
next depends on whether there's an open file handle associated with the
inode.  If there is, we write to the block device, which is unexpected
behavior.  If there isn't, we through normally and inode-&gt;i_data is used.
We can also end up racing against open/close which can result in crashes
when i_mapping points to a block device inode that has been closed.

Since there can't be any page cache associated with special file inodes,
it's safe to skip the btrfs_wait_ordered_range call entirely and avoid
the problem.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=100911
Tested-by: Christoph Biedl &lt;linux-kernel.bfrz@manchmal.in-ulm.de&gt;
Signed-off-by: Jeff Mahoney &lt;jeffm@suse.com&gt;
Reviewed-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Signed-off-by: Zefan Li &lt;lizefan@huawei.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: use kmem_cache_free when freeing entry in inode cache</title>
<updated>2016-03-21T01:17:39+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2015-06-13T05:52:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=38464cd9b38b43ef757da18bc8b9badcd2b70dfb'/>
<id>38464cd9b38b43ef757da18bc8b9badcd2b70dfb</id>
<content type='text'>
commit c3f4a1685bb87e59c886ee68f7967eae07d4dffa upstream.

The free space entries are allocated using kmem_cache_zalloc(),
through __btrfs_add_free_space(), therefore we should use
kmem_cache_free() and not kfree() to avoid any confusion and
any potential problem. Looking at the kfree() definition at
mm/slab.c it has the following comment:

  /*
   * (...)
   *
   * Don't free memory not originally allocated by kmalloc()
   * or you will run into trouble.
   */

So better be safe and use kmem_cache_free().

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.cz&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
Signed-off-by: Zefan Li &lt;lizefan@huawei.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit c3f4a1685bb87e59c886ee68f7967eae07d4dffa upstream.

The free space entries are allocated using kmem_cache_zalloc(),
through __btrfs_add_free_space(), therefore we should use
kmem_cache_free() and not kfree() to avoid any confusion and
any potential problem. Looking at the kfree() definition at
mm/slab.c it has the following comment:

  /*
   * (...)
   *
   * Don't free memory not originally allocated by kmalloc()
   * or you will run into trouble.
   */

So better be safe and use kmem_cache_free().

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.cz&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
Signed-off-by: Zefan Li &lt;lizefan@huawei.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fix inode eviction infinite loop after cloning into it</title>
<updated>2015-09-18T01:20:30+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2015-03-30T17:23:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=c9ff0e39da0903f48ef93983f84338674192936b'/>
<id>c9ff0e39da0903f48ef93983f84338674192936b</id>
<content type='text'>
commit ccccf3d67294714af2d72a6fd6fd7d73b01c9329 upstream.

If we attempt to clone a 0 length region into a file we can end up
inserting a range in the inode's extent_io tree with a start offset
that is greater then the end offset, which triggers immediately the
following warning:

[ 3914.619057] WARNING: CPU: 17 PID: 4199 at fs/btrfs/extent_io.c:435 insert_state+0x4b/0x10b [btrfs]()
[ 3914.620886] BTRFS: end &lt; start 4095 4096
(...)
[ 3914.638093] Call Trace:
[ 3914.638636]  [&lt;ffffffff81425fd9&gt;] dump_stack+0x4c/0x65
[ 3914.639620]  [&lt;ffffffff81045390&gt;] warn_slowpath_common+0xa1/0xbb
[ 3914.640789]  [&lt;ffffffffa03ca44f&gt;] ? insert_state+0x4b/0x10b [btrfs]
[ 3914.642041]  [&lt;ffffffff810453f0&gt;] warn_slowpath_fmt+0x46/0x48
[ 3914.643236]  [&lt;ffffffffa03ca44f&gt;] insert_state+0x4b/0x10b [btrfs]
[ 3914.644441]  [&lt;ffffffffa03ca729&gt;] __set_extent_bit+0x107/0x3f4 [btrfs]
[ 3914.645711]  [&lt;ffffffffa03cb256&gt;] lock_extent_bits+0x65/0x1bf [btrfs]
[ 3914.646914]  [&lt;ffffffff8142b2fb&gt;] ? _raw_spin_unlock+0x28/0x33
[ 3914.648058]  [&lt;ffffffffa03cbac4&gt;] ? test_range_bit+0xcc/0xde [btrfs]
[ 3914.650105]  [&lt;ffffffffa03cb3c3&gt;] lock_extent+0x13/0x15 [btrfs]
[ 3914.651361]  [&lt;ffffffffa03db39e&gt;] lock_extent_range+0x3d/0xcd [btrfs]
[ 3914.652761]  [&lt;ffffffffa03de1fe&gt;] btrfs_ioctl_clone+0x278/0x388 [btrfs]
[ 3914.654128]  [&lt;ffffffff811226dd&gt;] ? might_fault+0x58/0xb5
[ 3914.655320]  [&lt;ffffffffa03e0909&gt;] btrfs_ioctl+0xb51/0x2195 [btrfs]
(...)
[ 3914.669271] ---[ end trace 14843d3e2e622fc1 ]---

This later makes the inode eviction handler enter an infinite loop that
keeps dumping the following warning over and over:

[ 3915.117629] WARNING: CPU: 22 PID: 4228 at fs/btrfs/extent_io.c:435 insert_state+0x4b/0x10b [btrfs]()
[ 3915.119913] BTRFS: end &lt; start 4095 4096
(...)
[ 3915.137394] Call Trace:
[ 3915.137913]  [&lt;ffffffff81425fd9&gt;] dump_stack+0x4c/0x65
[ 3915.139154]  [&lt;ffffffff81045390&gt;] warn_slowpath_common+0xa1/0xbb
[ 3915.140316]  [&lt;ffffffffa03ca44f&gt;] ? insert_state+0x4b/0x10b [btrfs]
[ 3915.141505]  [&lt;ffffffff810453f0&gt;] warn_slowpath_fmt+0x46/0x48
[ 3915.142709]  [&lt;ffffffffa03ca44f&gt;] insert_state+0x4b/0x10b [btrfs]
[ 3915.143849]  [&lt;ffffffffa03ca729&gt;] __set_extent_bit+0x107/0x3f4 [btrfs]
[ 3915.145120]  [&lt;ffffffffa038c1e3&gt;] ? btrfs_kill_super+0x17/0x23 [btrfs]
[ 3915.146352]  [&lt;ffffffff811548f6&gt;] ? deactivate_locked_super+0x3b/0x50
[ 3915.147565]  [&lt;ffffffffa03cb256&gt;] lock_extent_bits+0x65/0x1bf [btrfs]
[ 3915.148785]  [&lt;ffffffff8142b7e2&gt;] ? _raw_write_unlock+0x28/0x33
[ 3915.149931]  [&lt;ffffffffa03bc325&gt;] btrfs_evict_inode+0x196/0x482 [btrfs]
[ 3915.151154]  [&lt;ffffffff81168904&gt;] evict+0xa0/0x148
[ 3915.152094]  [&lt;ffffffff811689e5&gt;] dispose_list+0x39/0x43
[ 3915.153081]  [&lt;ffffffff81169564&gt;] evict_inodes+0xdc/0xeb
[ 3915.154062]  [&lt;ffffffff81154418&gt;] generic_shutdown_super+0x49/0xef
[ 3915.155193]  [&lt;ffffffff811546d1&gt;] kill_anon_super+0x13/0x1e
[ 3915.156274]  [&lt;ffffffffa038c1e3&gt;] btrfs_kill_super+0x17/0x23 [btrfs]
(...)
[ 3915.167404] ---[ end trace 14843d3e2e622fc2 ]---

So just bail out of the clone ioctl if the length of the region to clone
is zero, without locking any extent range, in order to prevent this issue
(same behaviour as a pwrite with a 0 length for example).

This is trivial to reproduce. For example, the steps for the test I just
made for fstests:

  mkfs.btrfs -f SCRATCH_DEV
  mount SCRATCH_DEV $SCRATCH_MNT

  touch $SCRATCH_MNT/foo
  touch $SCRATCH_MNT/bar

  $CLONER_PROG -s 0 -d 4096 -l 0 $SCRATCH_MNT/foo $SCRATCH_MNT/bar
  umount $SCRATCH_MNT

A test case for fstests follows soon.

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: Omar Sandoval &lt;osandov@osandov.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
Signed-off-by: Zefan Li &lt;lizefan@huawei.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit ccccf3d67294714af2d72a6fd6fd7d73b01c9329 upstream.

If we attempt to clone a 0 length region into a file we can end up
inserting a range in the inode's extent_io tree with a start offset
that is greater then the end offset, which triggers immediately the
following warning:

[ 3914.619057] WARNING: CPU: 17 PID: 4199 at fs/btrfs/extent_io.c:435 insert_state+0x4b/0x10b [btrfs]()
[ 3914.620886] BTRFS: end &lt; start 4095 4096
(...)
[ 3914.638093] Call Trace:
[ 3914.638636]  [&lt;ffffffff81425fd9&gt;] dump_stack+0x4c/0x65
[ 3914.639620]  [&lt;ffffffff81045390&gt;] warn_slowpath_common+0xa1/0xbb
[ 3914.640789]  [&lt;ffffffffa03ca44f&gt;] ? insert_state+0x4b/0x10b [btrfs]
[ 3914.642041]  [&lt;ffffffff810453f0&gt;] warn_slowpath_fmt+0x46/0x48
[ 3914.643236]  [&lt;ffffffffa03ca44f&gt;] insert_state+0x4b/0x10b [btrfs]
[ 3914.644441]  [&lt;ffffffffa03ca729&gt;] __set_extent_bit+0x107/0x3f4 [btrfs]
[ 3914.645711]  [&lt;ffffffffa03cb256&gt;] lock_extent_bits+0x65/0x1bf [btrfs]
[ 3914.646914]  [&lt;ffffffff8142b2fb&gt;] ? _raw_spin_unlock+0x28/0x33
[ 3914.648058]  [&lt;ffffffffa03cbac4&gt;] ? test_range_bit+0xcc/0xde [btrfs]
[ 3914.650105]  [&lt;ffffffffa03cb3c3&gt;] lock_extent+0x13/0x15 [btrfs]
[ 3914.651361]  [&lt;ffffffffa03db39e&gt;] lock_extent_range+0x3d/0xcd [btrfs]
[ 3914.652761]  [&lt;ffffffffa03de1fe&gt;] btrfs_ioctl_clone+0x278/0x388 [btrfs]
[ 3914.654128]  [&lt;ffffffff811226dd&gt;] ? might_fault+0x58/0xb5
[ 3914.655320]  [&lt;ffffffffa03e0909&gt;] btrfs_ioctl+0xb51/0x2195 [btrfs]
(...)
[ 3914.669271] ---[ end trace 14843d3e2e622fc1 ]---

This later makes the inode eviction handler enter an infinite loop that
keeps dumping the following warning over and over:

[ 3915.117629] WARNING: CPU: 22 PID: 4228 at fs/btrfs/extent_io.c:435 insert_state+0x4b/0x10b [btrfs]()
[ 3915.119913] BTRFS: end &lt; start 4095 4096
(...)
[ 3915.137394] Call Trace:
[ 3915.137913]  [&lt;ffffffff81425fd9&gt;] dump_stack+0x4c/0x65
[ 3915.139154]  [&lt;ffffffff81045390&gt;] warn_slowpath_common+0xa1/0xbb
[ 3915.140316]  [&lt;ffffffffa03ca44f&gt;] ? insert_state+0x4b/0x10b [btrfs]
[ 3915.141505]  [&lt;ffffffff810453f0&gt;] warn_slowpath_fmt+0x46/0x48
[ 3915.142709]  [&lt;ffffffffa03ca44f&gt;] insert_state+0x4b/0x10b [btrfs]
[ 3915.143849]  [&lt;ffffffffa03ca729&gt;] __set_extent_bit+0x107/0x3f4 [btrfs]
[ 3915.145120]  [&lt;ffffffffa038c1e3&gt;] ? btrfs_kill_super+0x17/0x23 [btrfs]
[ 3915.146352]  [&lt;ffffffff811548f6&gt;] ? deactivate_locked_super+0x3b/0x50
[ 3915.147565]  [&lt;ffffffffa03cb256&gt;] lock_extent_bits+0x65/0x1bf [btrfs]
[ 3915.148785]  [&lt;ffffffff8142b7e2&gt;] ? _raw_write_unlock+0x28/0x33
[ 3915.149931]  [&lt;ffffffffa03bc325&gt;] btrfs_evict_inode+0x196/0x482 [btrfs]
[ 3915.151154]  [&lt;ffffffff81168904&gt;] evict+0xa0/0x148
[ 3915.152094]  [&lt;ffffffff811689e5&gt;] dispose_list+0x39/0x43
[ 3915.153081]  [&lt;ffffffff81169564&gt;] evict_inodes+0xdc/0xeb
[ 3915.154062]  [&lt;ffffffff81154418&gt;] generic_shutdown_super+0x49/0xef
[ 3915.155193]  [&lt;ffffffff811546d1&gt;] kill_anon_super+0x13/0x1e
[ 3915.156274]  [&lt;ffffffffa038c1e3&gt;] btrfs_kill_super+0x17/0x23 [btrfs]
(...)
[ 3915.167404] ---[ end trace 14843d3e2e622fc2 ]---

So just bail out of the clone ioctl if the length of the region to clone
is zero, without locking any extent range, in order to prevent this issue
(same behaviour as a pwrite with a 0 length for example).

This is trivial to reproduce. For example, the steps for the test I just
made for fstests:

  mkfs.btrfs -f SCRATCH_DEV
  mount SCRATCH_DEV $SCRATCH_MNT

  touch $SCRATCH_MNT/foo
  touch $SCRATCH_MNT/bar

  $CLONER_PROG -s 0 -d 4096 -l 0 $SCRATCH_MNT/foo $SCRATCH_MNT/bar
  umount $SCRATCH_MNT

A test case for fstests follows soon.

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: Omar Sandoval &lt;osandov@osandov.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
Signed-off-by: Zefan Li &lt;lizefan@huawei.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>btrfs: don't accept bare namespace as a valid xattr</title>
<updated>2015-09-18T01:20:26+00:00</updated>
<author>
<name>David Sterba</name>
<email>dsterba@suse.cz</email>
</author>
<published>2015-03-25T18:26:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=60ba3db7e79d02325f0ba2a11246c74e30427d41'/>
<id>60ba3db7e79d02325f0ba2a11246c74e30427d41</id>
<content type='text'>
commit 3c3b04d10ff1811a27f86684ccd2f5ba6983211d upstream.

Due to insufficient check in btrfs_is_valid_xattr, this unexpectedly
works:

 $ touch file
 $ setfattr -n user. -v 1 file
 $ getfattr -d file
user.="1"

ie. the missing attribute name after the namespace.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=94291
Reported-by: William Douglas &lt;william.douglas@intel.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.cz&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
[lizf: Backported to 3.4:
 - 3.4 doesn't support XATTR_BTRFS_PREFIX]
Signed-off-by: Zefan Li &lt;lizefan@huawei.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 3c3b04d10ff1811a27f86684ccd2f5ba6983211d upstream.

Due to insufficient check in btrfs_is_valid_xattr, this unexpectedly
works:

 $ touch file
 $ setfattr -n user. -v 1 file
 $ getfattr -d file
user.="1"

ie. the missing attribute name after the namespace.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=94291
Reported-by: William Douglas &lt;william.douglas@intel.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.cz&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
[lizf: Backported to 3.4:
 - 3.4 doesn't support XATTR_BTRFS_PREFIX]
Signed-off-by: Zefan Li &lt;lizefan@huawei.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fix log tree corruption when fs mounted with -o discard</title>
<updated>2015-09-18T01:20:26+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2015-03-23T14:07:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=abe62247e0fd8ae561d13d803267241143ececa1'/>
<id>abe62247e0fd8ae561d13d803267241143ececa1</id>
<content type='text'>
commit dcc82f4783ad91d4ab654f89f37ae9291cdc846a upstream.

While committing a transaction we free the log roots before we write the
new super block. Freeing the log roots implies marking the disk location
of every node/leaf (metadata extent) as pinned before the new super block
is written. This is to prevent the disk location of log metadata extents
from being reused before the new super block is written, otherwise we
would have a corrupted log tree if before the new super block is written
a crash/reboot happens and the location of any log tree metadata extent
ended up being reused and rewritten.

Even though we pinned the log tree's metadata extents, we were issuing a
discard against them if the fs was mounted with the -o discard option,
resulting in corruption of the log tree if a crash/reboot happened before
writing the new super block - the next time the fs was mounted, during
the log replay process we would find nodes/leafs of the log btree with
a content full of zeroes, causing the process to fail and require the
use of the tool btrfs-zero-log to wipeout the log tree (and all data
previously fsynced becoming lost forever).

Fix this by not doing a discard when pinning an extent. The discard will
be done later when it's safe (after the new super block is committed) at
extent-tree.c:btrfs_finish_extent_commit().

Fixes: e688b7252f78 (Btrfs: fix extent pinning bugs in the tree log)
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>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit dcc82f4783ad91d4ab654f89f37ae9291cdc846a upstream.

While committing a transaction we free the log roots before we write the
new super block. Freeing the log roots implies marking the disk location
of every node/leaf (metadata extent) as pinned before the new super block
is written. This is to prevent the disk location of log metadata extents
from being reused before the new super block is written, otherwise we
would have a corrupted log tree if before the new super block is written
a crash/reboot happens and the location of any log tree metadata extent
ended up being reused and rewritten.

Even though we pinned the log tree's metadata extents, we were issuing a
discard against them if the fs was mounted with the -o discard option,
resulting in corruption of the log tree if a crash/reboot happened before
writing the new super block - the next time the fs was mounted, during
the log replay process we would find nodes/leafs of the log btree with
a content full of zeroes, causing the process to fail and require the
use of the tool btrfs-zero-log to wipeout the log tree (and all data
previously fsynced becoming lost forever).

Fix this by not doing a discard when pinning an extent. The discard will
be done later when it's safe (after the new super block is committed) at
extent-tree.c:btrfs_finish_extent_commit().

Fixes: e688b7252f78 (Btrfs: fix extent pinning bugs in the tree log)
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;
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fix fs corruption on transaction abort if device supports discard</title>
<updated>2015-04-14T09:33:45+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2014-12-07T21:31:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=11b814e3597eeffa475e2e41323aa52d2e2289fa'/>
<id>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>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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;
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fix kfree on list_head in btrfs_lookup_csums_range error cleanup</title>
<updated>2015-02-02T09:05:13+00:00</updated>
<author>
<name>Chris Mason</name>
<email>clm@fb.com</email>
</author>
<published>2014-11-04T14:59:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=547f9e81ecec3e649ab565bf484fdd840bd6dc11'/>
<id>547f9e81ecec3e649ab565bf484fdd840bd6dc11</id>
<content type='text'>
commit 6e5aafb27419f32575b27ef9d6a31e5d54661aca upstream.

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 &lt;clm@fb.com&gt;
Reported-by: Erik Berg &lt;btrfs@slipsprogrammoer.no&gt;
Signed-off-by: Zefan Li &lt;lizefan@huawei.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 6e5aafb27419f32575b27ef9d6a31e5d54661aca upstream.

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 &lt;clm@fb.com&gt;
Reported-by: Erik Berg &lt;btrfs@slipsprogrammoer.no&gt;
Signed-off-by: Zefan Li &lt;lizefan@huawei.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>btrfs: fix use of uninit "ret" in end_extent_writepage()</title>
<updated>2014-07-01T03:01:33+00:00</updated>
<author>
<name>Eric Sandeen</name>
<email>sandeen@redhat.com</email>
</author>
<published>2014-06-12T05:39:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=e18bac2cae5d6efa474611a2dc825b7749760af4'/>
<id>e18bac2cae5d6efa474611a2dc825b7749760af4</id>
<content type='text'>
commit 3e2426bd0eb980648449e7a2f5a23e3cd3c7725c upstream.

If this condition in end_extent_writepage() is false:

	if (tree-&gt;ops &amp;&amp; tree-&gt;ops-&gt;writepage_end_io_hook)

we will then test an uninitialized "ret" at:

	ret = ret &lt; 0 ? ret : -EIO;

The test for ret is for the case where -&gt;writepage_end_io_hook
failed, and we'd choose that ret as the error; but if
there is no -&gt;writepage_end_io_hook, nothing sets ret.

Initializing ret to 0 should be sufficient; if
writepage_end_io_hook wasn't set, (!uptodate) means
non-zero err was passed in, so we choose -EIO in that case.

Signed-of-by: Eric Sandeen &lt;sandeen@redhat.com&gt;

Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 3e2426bd0eb980648449e7a2f5a23e3cd3c7725c upstream.

If this condition in end_extent_writepage() is false:

	if (tree-&gt;ops &amp;&amp; tree-&gt;ops-&gt;writepage_end_io_hook)

we will then test an uninitialized "ret" at:

	ret = ret &lt; 0 ? ret : -EIO;

The test for ret is for the case where -&gt;writepage_end_io_hook
failed, and we'd choose that ret as the error; but if
there is no -&gt;writepage_end_io_hook, nothing sets ret.

Initializing ret to 0 should be sufficient; if
writepage_end_io_hook wasn't set, (!uptodate) means
non-zero err was passed in, so we choose -EIO in that case.

Signed-of-by: Eric Sandeen &lt;sandeen@redhat.com&gt;

Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: use right type to get real comparison</title>
<updated>2014-07-01T03:01:33+00:00</updated>
<author>
<name>Liu Bo</name>
<email>bo.li.liu@oracle.com</email>
</author>
<published>2014-06-08T11:04:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=64b84ef0258d03d80d2581b7f44b7630e945e612'/>
<id>64b84ef0258d03d80d2581b7f44b7630e945e612</id>
<content type='text'>
commit cd857dd6bc2ae9ecea14e75a34e8a8fdc158e307 upstream.

We want to make sure the point is still within the extent item, not to verify
the memory it's pointing to.

Signed-off-by: Liu Bo &lt;bo.li.liu@oracle.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit cd857dd6bc2ae9ecea14e75a34e8a8fdc158e307 upstream.

We want to make sure the point is still within the extent item, not to verify
the memory it's pointing to.

Signed-off-by: Liu Bo &lt;bo.li.liu@oracle.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
</feed>
