<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux.git/fs/btrfs, branch v4.5</title>
<subtitle>Linux kernel source tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/'/>
<entry>
<title>Merge branch 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs</title>
<updated>2016-03-05T01:31:32+00:00</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2016-03-05T01:31:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=2cdcb2b5b5d6d7c1bdefbc1a63187d47fd809408'/>
<id>2cdcb2b5b5d6d7c1bdefbc1a63187d47fd809408</id>
<content type='text'>
Pull btrfs fix from Chris Mason:
 "Filipe nailed down a problem where tree log replay would do some work
  that orphan code wasn't expecting to be done yet, leading to BUG_ON"

* 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  Btrfs: fix loading of orphan roots leading to BUG_ON
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Pull btrfs fix from Chris Mason:
 "Filipe nailed down a problem where tree log replay would do some work
  that orphan code wasn't expecting to be done yet, leading to BUG_ON"

* 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  Btrfs: fix loading of orphan roots leading to BUG_ON
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fix loading of orphan roots leading to BUG_ON</title>
<updated>2016-03-03T23:28:59+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2016-03-02T15:49:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=909c3a22da3b8d2cfd3505ca5658f0176859d400'/>
<id>909c3a22da3b8d2cfd3505ca5658f0176859d400</id>
<content type='text'>
When looking for orphan roots during mount we can end up hitting a
BUG_ON() (at root-item.c:btrfs_find_orphan_roots()) if a log tree is
replayed and qgroups are enabled. This is because after a log tree is
replayed, a transaction commit is made, which triggers qgroup extent
accounting which in turn does backref walking which ends up reading and
inserting all roots in the radix tree fs_info-&gt;fs_root_radix, including
orphan roots (deleted snapshots). So after the log tree is replayed, when
finding orphan roots we hit the BUG_ON with the following trace:

[118209.182438] ------------[ cut here ]------------
[118209.183279] kernel BUG at fs/btrfs/root-tree.c:314!
[118209.184074] invalid opcode: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
[118209.185123] Modules linked in: btrfs dm_flakey dm_mod crc32c_generic ppdev xor raid6_pq evdev sg parport_pc parport acpi_cpufreq tpm_tis tpm psmouse
processor i2c_piix4 serio_raw pcspkr i2c_core button loop autofs4 ext4 crc16 mbcache jbd2 sd_mod sr_mod cdrom ata_generic virtio_scsi ata_piix libata
virtio_pci virtio_ring virtio scsi_mod e1000 floppy [last unloaded: btrfs]
[118209.186318] CPU: 14 PID: 28428 Comm: mount Tainted: G        W       4.5.0-rc5-btrfs-next-24+ #1
[118209.186318] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014
[118209.186318] task: ffff8801ec131040 ti: ffff8800af34c000 task.ti: ffff8800af34c000
[118209.186318] RIP: 0010:[&lt;ffffffffa04237d7&gt;]  [&lt;ffffffffa04237d7&gt;] btrfs_find_orphan_roots+0x1fc/0x244 [btrfs]
[118209.186318] RSP: 0018:ffff8800af34faa8  EFLAGS: 00010246
[118209.186318] RAX: 00000000ffffffef RBX: 00000000ffffffef RCX: 0000000000000001
[118209.186318] RDX: 0000000080000000 RSI: 0000000000000001 RDI: 00000000ffffffff
[118209.186318] RBP: ffff8800af34fb08 R08: 0000000000000001 R09: 0000000000000000
[118209.186318] R10: ffff8800af34f9f0 R11: 6db6db6db6db6db7 R12: ffff880171b97000
[118209.186318] R13: ffff8801ca9d65e0 R14: ffff8800afa2e000 R15: 0000160000000000
[118209.186318] FS:  00007f5bcb914840(0000) GS:ffff88023edc0000(0000) knlGS:0000000000000000
[118209.186318] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[118209.186318] CR2: 00007f5bcaceb5d9 CR3: 00000000b49b5000 CR4: 00000000000006e0
[118209.186318] Stack:
[118209.186318]  fffffbffffffffff 010230ffffffffff 0101000000000000 ff84000000000000
[118209.186318]  fbffffffffffffff 30ffffffffffffff 0000000000000101 ffff880082348000
[118209.186318]  0000000000000000 ffff8800afa2e000 ffff8800afa2e000 0000000000000000
[118209.186318] Call Trace:
[118209.186318]  [&lt;ffffffffa042e2db&gt;] open_ctree+0x1e37/0x21b9 [btrfs]
[118209.186318]  [&lt;ffffffffa040a753&gt;] btrfs_mount+0x97e/0xaed [btrfs]
[118209.186318]  [&lt;ffffffff8108e1c0&gt;] ? trace_hardirqs_on+0xd/0xf
[118209.186318]  [&lt;ffffffff8117b87e&gt;] mount_fs+0x67/0x131
[118209.186318]  [&lt;ffffffff81192d2b&gt;] vfs_kern_mount+0x6c/0xde
[118209.186318]  [&lt;ffffffffa0409f81&gt;] btrfs_mount+0x1ac/0xaed [btrfs]
[118209.186318]  [&lt;ffffffff8108e1c0&gt;] ? trace_hardirqs_on+0xd/0xf
[118209.186318]  [&lt;ffffffff8108c26b&gt;] ? lockdep_init_map+0xb9/0x1b3
[118209.186318]  [&lt;ffffffff8117b87e&gt;] mount_fs+0x67/0x131
[118209.186318]  [&lt;ffffffff81192d2b&gt;] vfs_kern_mount+0x6c/0xde
[118209.186318]  [&lt;ffffffff81195637&gt;] do_mount+0x8a6/0x9e8
[118209.186318]  [&lt;ffffffff8119598d&gt;] SyS_mount+0x77/0x9f
[118209.186318]  [&lt;ffffffff81493017&gt;] entry_SYSCALL_64_fastpath+0x12/0x6b
[118209.186318] Code: 64 00 00 85 c0 89 c3 75 24 f0 41 80 4c 24 20 20 49 8b bc 24 f0 01 00 00 4c 89 e6 e8 e8 65 00 00 85 c0 89 c3 74 11 83 f8 ef 75 02 &lt;0f&gt; 0b
4c 89 e7 e8 da 72 00 00 eb 1c 41 83 bc 24 00 01 00 00 00
[118209.186318] RIP  [&lt;ffffffffa04237d7&gt;] btrfs_find_orphan_roots+0x1fc/0x244 [btrfs]
[118209.186318]  RSP &lt;ffff8800af34faa8&gt;
[118209.230735] ---[ end trace 83938f987d85d477 ]---

So fix this by not treating the error -EEXIST, returned when attempting
to insert a root already inserted by the backref walking code, as an error.

The following test case for xfstests reproduces the bug:

  seq=`basename $0`
  seqres=$RESULT_DIR/$seq
  echo "QA output created by $seq"
  tmp=/tmp/$$
  status=1	# failure is the default!
  trap "_cleanup; exit \$status" 0 1 2 3 15

  _cleanup()
  {
      _cleanup_flakey
      cd /
      rm -f $tmp.*
  }

  # get standard environment, filters and checks
  . ./common/rc
  . ./common/filter
  . ./common/dmflakey

  # real QA test starts here
  _supported_fs btrfs
  _supported_os Linux
  _require_scratch
  _require_dm_target flakey
  _require_metadata_journaling $SCRATCH_DEV

  rm -f $seqres.full

  _scratch_mkfs &gt;&gt;$seqres.full 2&gt;&amp;1
  _init_flakey
  _mount_flakey

  _run_btrfs_util_prog quota enable $SCRATCH_MNT

  # Create 2 directories with one file in one of them.
  # We use these just to trigger a transaction commit later, moving the file from
  # directory a to directory b and doing an fsync against directory a.
  mkdir $SCRATCH_MNT/a
  mkdir $SCRATCH_MNT/b
  touch $SCRATCH_MNT/a/f
  sync

  # Create our test file with 2 4K extents.
  $XFS_IO_PROG -f -s -c "pwrite -S 0xaa 0 8K" $SCRATCH_MNT/foobar | _filter_xfs_io

  # Create a snapshot and delete it. This doesn't really delete the snapshot
  # immediately, just makes it inaccessible and invisible to user space, the
  # snapshot is deleted later by a dedicated kernel thread (cleaner kthread)
  # which is woke up at the next transaction commit.
  # A root orphan item is inserted into the tree of tree roots, so that if a
  # power failure happens before the dedicated kernel thread does the snapshot
  # deletion, the next time the filesystem is mounted it resumes the snapshot
  # deletion.
  _run_btrfs_util_prog subvolume snapshot $SCRATCH_MNT $SCRATCH_MNT/snap
  _run_btrfs_util_prog subvolume delete $SCRATCH_MNT/snap

  # Now overwrite half of the extents we wrote before. Because we made a snapshpot
  # before, which isn't really deleted yet (since no transaction commit happened
  # after we did the snapshot delete request), the non overwritten extents get
  # referenced twice, once by the default subvolume and once by the snapshot.
  $XFS_IO_PROG -c "pwrite -S 0xbb 4K 8K" $SCRATCH_MNT/foobar | _filter_xfs_io

  # Now move file f from directory a to directory b and fsync directory a.
  # The fsync on the directory a triggers a transaction commit (because a file
  # was moved from it to another directory) and the file fsync leaves a log tree
  # with file extent items to replay.
  mv $SCRATCH_MNT/a/f $SCRATCH_MNT/a/b
  $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/a
  $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foobar

  echo "File digest before power failure:"
  md5sum $SCRATCH_MNT/foobar | _filter_scratch

  # Now simulate a power failure and mount the filesystem to replay the log tree.
  # After the log tree was replayed, we used to hit a BUG_ON() when processing
  # the root orphan item for the deleted snapshot. This is because when processing
  # an orphan root the code expected to be the first code inserting the root into
  # the fs_info-&gt;fs_root_radix radix tree, while in reallity it was the second
  # caller attempting to do it - the first caller was the transaction commit that
  # took place after replaying the log tree, when updating the qgroup counters.
  _flakey_drop_and_remount

  echo "File digest before after failure:"
  # Must match what he got before the power failure.
  md5sum $SCRATCH_MNT/foobar | _filter_scratch

  _unmount_flakey
  status=0
  exit

Fixes: 2d9e97761087 ("Btrfs: use btrfs_get_fs_root in resolve_indirect_ref")
Cc: stable@vger.kernel.org  # 4.4+
Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: Qu Wenruo &lt;quwenruo@cn.fujitsu.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When looking for orphan roots during mount we can end up hitting a
BUG_ON() (at root-item.c:btrfs_find_orphan_roots()) if a log tree is
replayed and qgroups are enabled. This is because after a log tree is
replayed, a transaction commit is made, which triggers qgroup extent
accounting which in turn does backref walking which ends up reading and
inserting all roots in the radix tree fs_info-&gt;fs_root_radix, including
orphan roots (deleted snapshots). So after the log tree is replayed, when
finding orphan roots we hit the BUG_ON with the following trace:

[118209.182438] ------------[ cut here ]------------
[118209.183279] kernel BUG at fs/btrfs/root-tree.c:314!
[118209.184074] invalid opcode: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
[118209.185123] Modules linked in: btrfs dm_flakey dm_mod crc32c_generic ppdev xor raid6_pq evdev sg parport_pc parport acpi_cpufreq tpm_tis tpm psmouse
processor i2c_piix4 serio_raw pcspkr i2c_core button loop autofs4 ext4 crc16 mbcache jbd2 sd_mod sr_mod cdrom ata_generic virtio_scsi ata_piix libata
virtio_pci virtio_ring virtio scsi_mod e1000 floppy [last unloaded: btrfs]
[118209.186318] CPU: 14 PID: 28428 Comm: mount Tainted: G        W       4.5.0-rc5-btrfs-next-24+ #1
[118209.186318] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014
[118209.186318] task: ffff8801ec131040 ti: ffff8800af34c000 task.ti: ffff8800af34c000
[118209.186318] RIP: 0010:[&lt;ffffffffa04237d7&gt;]  [&lt;ffffffffa04237d7&gt;] btrfs_find_orphan_roots+0x1fc/0x244 [btrfs]
[118209.186318] RSP: 0018:ffff8800af34faa8  EFLAGS: 00010246
[118209.186318] RAX: 00000000ffffffef RBX: 00000000ffffffef RCX: 0000000000000001
[118209.186318] RDX: 0000000080000000 RSI: 0000000000000001 RDI: 00000000ffffffff
[118209.186318] RBP: ffff8800af34fb08 R08: 0000000000000001 R09: 0000000000000000
[118209.186318] R10: ffff8800af34f9f0 R11: 6db6db6db6db6db7 R12: ffff880171b97000
[118209.186318] R13: ffff8801ca9d65e0 R14: ffff8800afa2e000 R15: 0000160000000000
[118209.186318] FS:  00007f5bcb914840(0000) GS:ffff88023edc0000(0000) knlGS:0000000000000000
[118209.186318] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[118209.186318] CR2: 00007f5bcaceb5d9 CR3: 00000000b49b5000 CR4: 00000000000006e0
[118209.186318] Stack:
[118209.186318]  fffffbffffffffff 010230ffffffffff 0101000000000000 ff84000000000000
[118209.186318]  fbffffffffffffff 30ffffffffffffff 0000000000000101 ffff880082348000
[118209.186318]  0000000000000000 ffff8800afa2e000 ffff8800afa2e000 0000000000000000
[118209.186318] Call Trace:
[118209.186318]  [&lt;ffffffffa042e2db&gt;] open_ctree+0x1e37/0x21b9 [btrfs]
[118209.186318]  [&lt;ffffffffa040a753&gt;] btrfs_mount+0x97e/0xaed [btrfs]
[118209.186318]  [&lt;ffffffff8108e1c0&gt;] ? trace_hardirqs_on+0xd/0xf
[118209.186318]  [&lt;ffffffff8117b87e&gt;] mount_fs+0x67/0x131
[118209.186318]  [&lt;ffffffff81192d2b&gt;] vfs_kern_mount+0x6c/0xde
[118209.186318]  [&lt;ffffffffa0409f81&gt;] btrfs_mount+0x1ac/0xaed [btrfs]
[118209.186318]  [&lt;ffffffff8108e1c0&gt;] ? trace_hardirqs_on+0xd/0xf
[118209.186318]  [&lt;ffffffff8108c26b&gt;] ? lockdep_init_map+0xb9/0x1b3
[118209.186318]  [&lt;ffffffff8117b87e&gt;] mount_fs+0x67/0x131
[118209.186318]  [&lt;ffffffff81192d2b&gt;] vfs_kern_mount+0x6c/0xde
[118209.186318]  [&lt;ffffffff81195637&gt;] do_mount+0x8a6/0x9e8
[118209.186318]  [&lt;ffffffff8119598d&gt;] SyS_mount+0x77/0x9f
[118209.186318]  [&lt;ffffffff81493017&gt;] entry_SYSCALL_64_fastpath+0x12/0x6b
[118209.186318] Code: 64 00 00 85 c0 89 c3 75 24 f0 41 80 4c 24 20 20 49 8b bc 24 f0 01 00 00 4c 89 e6 e8 e8 65 00 00 85 c0 89 c3 74 11 83 f8 ef 75 02 &lt;0f&gt; 0b
4c 89 e7 e8 da 72 00 00 eb 1c 41 83 bc 24 00 01 00 00 00
[118209.186318] RIP  [&lt;ffffffffa04237d7&gt;] btrfs_find_orphan_roots+0x1fc/0x244 [btrfs]
[118209.186318]  RSP &lt;ffff8800af34faa8&gt;
[118209.230735] ---[ end trace 83938f987d85d477 ]---

So fix this by not treating the error -EEXIST, returned when attempting
to insert a root already inserted by the backref walking code, as an error.

The following test case for xfstests reproduces the bug:

  seq=`basename $0`
  seqres=$RESULT_DIR/$seq
  echo "QA output created by $seq"
  tmp=/tmp/$$
  status=1	# failure is the default!
  trap "_cleanup; exit \$status" 0 1 2 3 15

  _cleanup()
  {
      _cleanup_flakey
      cd /
      rm -f $tmp.*
  }

  # get standard environment, filters and checks
  . ./common/rc
  . ./common/filter
  . ./common/dmflakey

  # real QA test starts here
  _supported_fs btrfs
  _supported_os Linux
  _require_scratch
  _require_dm_target flakey
  _require_metadata_journaling $SCRATCH_DEV

  rm -f $seqres.full

  _scratch_mkfs &gt;&gt;$seqres.full 2&gt;&amp;1
  _init_flakey
  _mount_flakey

  _run_btrfs_util_prog quota enable $SCRATCH_MNT

  # Create 2 directories with one file in one of them.
  # We use these just to trigger a transaction commit later, moving the file from
  # directory a to directory b and doing an fsync against directory a.
  mkdir $SCRATCH_MNT/a
  mkdir $SCRATCH_MNT/b
  touch $SCRATCH_MNT/a/f
  sync

  # Create our test file with 2 4K extents.
  $XFS_IO_PROG -f -s -c "pwrite -S 0xaa 0 8K" $SCRATCH_MNT/foobar | _filter_xfs_io

  # Create a snapshot and delete it. This doesn't really delete the snapshot
  # immediately, just makes it inaccessible and invisible to user space, the
  # snapshot is deleted later by a dedicated kernel thread (cleaner kthread)
  # which is woke up at the next transaction commit.
  # A root orphan item is inserted into the tree of tree roots, so that if a
  # power failure happens before the dedicated kernel thread does the snapshot
  # deletion, the next time the filesystem is mounted it resumes the snapshot
  # deletion.
  _run_btrfs_util_prog subvolume snapshot $SCRATCH_MNT $SCRATCH_MNT/snap
  _run_btrfs_util_prog subvolume delete $SCRATCH_MNT/snap

  # Now overwrite half of the extents we wrote before. Because we made a snapshpot
  # before, which isn't really deleted yet (since no transaction commit happened
  # after we did the snapshot delete request), the non overwritten extents get
  # referenced twice, once by the default subvolume and once by the snapshot.
  $XFS_IO_PROG -c "pwrite -S 0xbb 4K 8K" $SCRATCH_MNT/foobar | _filter_xfs_io

  # Now move file f from directory a to directory b and fsync directory a.
  # The fsync on the directory a triggers a transaction commit (because a file
  # was moved from it to another directory) and the file fsync leaves a log tree
  # with file extent items to replay.
  mv $SCRATCH_MNT/a/f $SCRATCH_MNT/a/b
  $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/a
  $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foobar

  echo "File digest before power failure:"
  md5sum $SCRATCH_MNT/foobar | _filter_scratch

  # Now simulate a power failure and mount the filesystem to replay the log tree.
  # After the log tree was replayed, we used to hit a BUG_ON() when processing
  # the root orphan item for the deleted snapshot. This is because when processing
  # an orphan root the code expected to be the first code inserting the root into
  # the fs_info-&gt;fs_root_radix radix tree, while in reallity it was the second
  # caller attempting to do it - the first caller was the transaction commit that
  # took place after replaying the log tree, when updating the qgroup counters.
  _flakey_drop_and_remount

  echo "File digest before after failure:"
  # Must match what he got before the power failure.
  md5sum $SCRATCH_MNT/foobar | _filter_scratch

  _unmount_flakey
  status=0
  exit

Fixes: 2d9e97761087 ("Btrfs: use btrfs_get_fs_root in resolve_indirect_ref")
Cc: stable@vger.kernel.org  # 4.4+
Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: Qu Wenruo &lt;quwenruo@cn.fujitsu.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs</title>
<updated>2016-02-19T21:40:42+00:00</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2016-02-19T21:40:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=ce6b71432d42afe5c3ae25ab2980304c32ecb915'/>
<id>ce6b71432d42afe5c3ae25ab2980304c32ecb915</id>
<content type='text'>
Pull btrfs fix from Chris Mason:
 "My for-linus-4.5 branch has a btrfs DIO error passing fix.

  I know how much you love DIO, so I'm going to suggest against reading
  it.  We'll follow up with a patch to drop the error arg from
  dio_end_io in the next merge window."

* 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  Btrfs: fix direct IO requests not reporting IO error to user space
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Pull btrfs fix from Chris Mason:
 "My for-linus-4.5 branch has a btrfs DIO error passing fix.

  I know how much you love DIO, so I'm going to suggest against reading
  it.  We'll follow up with a patch to drop the error arg from
  dio_end_io in the next merge window."

* 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  Btrfs: fix direct IO requests not reporting IO error to user space
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fix direct IO requests not reporting IO error to user space</title>
<updated>2016-02-16T03:41:26+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2016-02-15T16:20:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=1636d1d77ef4e01e57f706a4cae3371463896136'/>
<id>1636d1d77ef4e01e57f706a4cae3371463896136</id>
<content type='text'>
If a bio for a direct IO request fails, we were not setting the error in
the parent bio (the main DIO bio), making us not return the error to
user space in btrfs_direct_IO(), that is, it made __blockdev_direct_IO()
return the number of bytes issued for IO and not the error a bio created
and submitted by btrfs_submit_direct() got from the block layer.
This essentially happens because when we call:

   dio_end_io(dio_bio, bio-&gt;bi_error);

It does not set dio_bio-&gt;bi_error to the value of the second argument.
So just add this missing assignment in endio callbacks, just as we do in
the error path at btrfs_submit_direct() when we fail to clone the dio bio
or allocate its private object. This follows the convention of what is
done with other similar APIs such as bio_endio() where the caller is
responsible for setting the bi_error field in the bio it passes as an
argument to bio_endio().

This was detected by the new generic test cases in xfstests: 271, 272,
276 and 278. Which essentially setup a dm error target, then load the
error table, do a direct IO write and unload the error table. They
expect the write to fail with -EIO, which was not getting reported
when testing against btrfs.

Cc: stable@vger.kernel.org  # 4.3+
Fixes: 4246a0b63bd8 ("block: add a bi_error field to struct bio")
Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
If a bio for a direct IO request fails, we were not setting the error in
the parent bio (the main DIO bio), making us not return the error to
user space in btrfs_direct_IO(), that is, it made __blockdev_direct_IO()
return the number of bytes issued for IO and not the error a bio created
and submitted by btrfs_submit_direct() got from the block layer.
This essentially happens because when we call:

   dio_end_io(dio_bio, bio-&gt;bi_error);

It does not set dio_bio-&gt;bi_error to the value of the second argument.
So just add this missing assignment in endio callbacks, just as we do in
the error path at btrfs_submit_direct() when we fail to clone the dio bio
or allocate its private object. This follows the convention of what is
done with other similar APIs such as bio_endio() where the caller is
responsible for setting the bi_error field in the bio it passes as an
argument to bio_endio().

This was detected by the new generic test cases in xfstests: 271, 272,
276 and 278. Which essentially setup a dm error target, then load the
error table, do a direct IO write and unload the error table. They
expect the write to fail with -EIO, which was not getting reported
when testing against btrfs.

Cc: stable@vger.kernel.org  # 4.3+
Fixes: 4246a0b63bd8 ("block: add a bi_error field to struct bio")
Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs</title>
<updated>2016-02-12T17:21:28+00:00</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2016-02-12T17:21:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=27c9d772e50731dfd682b4ea9459eccec2071c49'/>
<id>27c9d772e50731dfd682b4ea9459eccec2071c49</id>
<content type='text'>
Pull btrfs fixes from Chris Mason:
 "This has a few fixes from Filipe, along with a readdir fix from Dave
  that we've been testing for some time"

* 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  btrfs: properly set the termination value of ctx-&gt;pos in readdir
  Btrfs: fix hang on extent buffer lock caused by the inode_paths ioctl
  Btrfs: remove no longer used function extent_read_full_page_nolock()
  Btrfs: fix page reading in extent_same ioctl leading to csum errors
  Btrfs: fix invalid page accesses in extent_same (dedup) ioctl
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Pull btrfs fixes from Chris Mason:
 "This has a few fixes from Filipe, along with a readdir fix from Dave
  that we've been testing for some time"

* 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  btrfs: properly set the termination value of ctx-&gt;pos in readdir
  Btrfs: fix hang on extent buffer lock caused by the inode_paths ioctl
  Btrfs: remove no longer used function extent_read_full_page_nolock()
  Btrfs: fix page reading in extent_same ioctl leading to csum errors
  Btrfs: fix invalid page accesses in extent_same (dedup) ioctl
</pre>
</div>
</content>
</entry>
<entry>
<title>btrfs: properly set the termination value of ctx-&gt;pos in readdir</title>
<updated>2016-02-11T15:01:59+00:00</updated>
<author>
<name>David Sterba</name>
<email>dsterba@suse.com</email>
</author>
<published>2015-11-13T12:44:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=bc4ef7592f657ae81b017207a1098817126ad4cb'/>
<id>bc4ef7592f657ae81b017207a1098817126ad4cb</id>
<content type='text'>
The value of ctx-&gt;pos in the last readdir call is supposed to be set to
INT_MAX due to 32bit compatibility, unless 'pos' is intentially set to a
larger value, then it's LLONG_MAX.

There's a report from PaX SIZE_OVERFLOW plugin that "ctx-&gt;pos++"
overflows (https://forums.grsecurity.net/viewtopic.php?f=1&amp;t=4284), on a
64bit arch, where the value is 0x7fffffffffffffff ie. LLONG_MAX before
the increment.

We can get to that situation like that:

* emit all regular readdir entries
* still in the same call to readdir, bump the last pos to INT_MAX
* next call to readdir will not emit any entries, but will reach the
  bump code again, finds pos to be INT_MAX and sets it to LLONG_MAX

Normally this is not a problem, but if we call readdir again, we'll find
'pos' set to LLONG_MAX and the unconditional increment will overflow.

The report from Victor at
(http://thread.gmane.org/gmane.comp.file-systems.btrfs/49500) with debugging
print shows that pattern:

 Overflow: e
 Overflow: 7fffffff
 Overflow: 7fffffffffffffff
 PAX: size overflow detected in function btrfs_real_readdir
   fs/btrfs/inode.c:5760 cicus.935_282 max, count: 9, decl: pos; num: 0;
   context: dir_context;
 CPU: 0 PID: 2630 Comm: polkitd Not tainted 4.2.3-grsec #1
 Hardware name: Gigabyte Technology Co., Ltd. H81ND2H/H81ND2H, BIOS F3 08/11/2015
  ffffffff81901608 0000000000000000 ffffffff819015e6 ffffc90004973d48
  ffffffff81742f0f 0000000000000007 ffffffff81901608 ffffc90004973d78
  ffffffff811cb706 0000000000000000 ffff8800d47359e0 ffffc90004973ed8
 Call Trace:
  [&lt;ffffffff81742f0f&gt;] dump_stack+0x4c/0x7f
  [&lt;ffffffff811cb706&gt;] report_size_overflow+0x36/0x40
  [&lt;ffffffff812ef0bc&gt;] btrfs_real_readdir+0x69c/0x6d0
  [&lt;ffffffff811dafc8&gt;] iterate_dir+0xa8/0x150
  [&lt;ffffffff811e6d8d&gt;] ? __fget_light+0x2d/0x70
  [&lt;ffffffff811dba3a&gt;] SyS_getdents+0xba/0x1c0
 Overflow: 1a
  [&lt;ffffffff811db070&gt;] ? iterate_dir+0x150/0x150
  [&lt;ffffffff81749b69&gt;] entry_SYSCALL_64_fastpath+0x12/0x83

The jump from 7fffffff to 7fffffffffffffff happens when new dir entries
are not yet synced and are processed from the delayed list. Then the code
could go to the bump section again even though it might not emit any new
dir entries from the delayed list.

The fix avoids entering the "bump" section again once we've finished
emitting the entries, both for synced and delayed entries.

References: https://forums.grsecurity.net/viewtopic.php?f=1&amp;t=4284
Reported-by: Victor &lt;services@swwu.com&gt;
CC: stable@vger.kernel.org
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
Tested-by: Holger Hoffstätte &lt;holger.hoffstaette@googlemail.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The value of ctx-&gt;pos in the last readdir call is supposed to be set to
INT_MAX due to 32bit compatibility, unless 'pos' is intentially set to a
larger value, then it's LLONG_MAX.

There's a report from PaX SIZE_OVERFLOW plugin that "ctx-&gt;pos++"
overflows (https://forums.grsecurity.net/viewtopic.php?f=1&amp;t=4284), on a
64bit arch, where the value is 0x7fffffffffffffff ie. LLONG_MAX before
the increment.

We can get to that situation like that:

* emit all regular readdir entries
* still in the same call to readdir, bump the last pos to INT_MAX
* next call to readdir will not emit any entries, but will reach the
  bump code again, finds pos to be INT_MAX and sets it to LLONG_MAX

Normally this is not a problem, but if we call readdir again, we'll find
'pos' set to LLONG_MAX and the unconditional increment will overflow.

The report from Victor at
(http://thread.gmane.org/gmane.comp.file-systems.btrfs/49500) with debugging
print shows that pattern:

 Overflow: e
 Overflow: 7fffffff
 Overflow: 7fffffffffffffff
 PAX: size overflow detected in function btrfs_real_readdir
   fs/btrfs/inode.c:5760 cicus.935_282 max, count: 9, decl: pos; num: 0;
   context: dir_context;
 CPU: 0 PID: 2630 Comm: polkitd Not tainted 4.2.3-grsec #1
 Hardware name: Gigabyte Technology Co., Ltd. H81ND2H/H81ND2H, BIOS F3 08/11/2015
  ffffffff81901608 0000000000000000 ffffffff819015e6 ffffc90004973d48
  ffffffff81742f0f 0000000000000007 ffffffff81901608 ffffc90004973d78
  ffffffff811cb706 0000000000000000 ffff8800d47359e0 ffffc90004973ed8
 Call Trace:
  [&lt;ffffffff81742f0f&gt;] dump_stack+0x4c/0x7f
  [&lt;ffffffff811cb706&gt;] report_size_overflow+0x36/0x40
  [&lt;ffffffff812ef0bc&gt;] btrfs_real_readdir+0x69c/0x6d0
  [&lt;ffffffff811dafc8&gt;] iterate_dir+0xa8/0x150
  [&lt;ffffffff811e6d8d&gt;] ? __fget_light+0x2d/0x70
  [&lt;ffffffff811dba3a&gt;] SyS_getdents+0xba/0x1c0
 Overflow: 1a
  [&lt;ffffffff811db070&gt;] ? iterate_dir+0x150/0x150
  [&lt;ffffffff81749b69&gt;] entry_SYSCALL_64_fastpath+0x12/0x83

The jump from 7fffffff to 7fffffffffffffff happens when new dir entries
are not yet synced and are processed from the delayed list. Then the code
could go to the bump section again even though it might not emit any new
dir entries from the delayed list.

The fix avoids entering the "bump" section again once we've finished
emitting the entries, both for synced and delayed entries.

References: https://forums.grsecurity.net/viewtopic.php?f=1&amp;t=4284
Reported-by: Victor &lt;services@swwu.com&gt;
CC: stable@vger.kernel.org
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
Tested-by: Holger Hoffstätte &lt;holger.hoffstaette@googlemail.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fix hang on extent buffer lock caused by the inode_paths ioctl</title>
<updated>2016-02-05T02:26:25+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2016-02-03T19:17:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=0c0fe3b0fa45082cd752553fdb3a4b42503a118e'/>
<id>0c0fe3b0fa45082cd752553fdb3a4b42503a118e</id>
<content type='text'>
While doing some tests I ran into an hang on an extent buffer's rwlock
that produced the following trace:

[39389.800012] NMI watchdog: BUG: soft lockup - CPU#15 stuck for 22s! [fdm-stress:32166]
[39389.800016] NMI watchdog: BUG: soft lockup - CPU#14 stuck for 22s! [fdm-stress:32165]
[39389.800016] Modules linked in: btrfs dm_mod ppdev xor sha256_generic hmac raid6_pq drbg ansi_cprng aesni_intel i2c_piix4 acpi_cpufreq aes_x86_64 ablk_helper tpm_tis parport_pc i2c_core sg cryptd evdev psmouse lrw tpm parport gf128mul serio_raw pcspkr glue_helper processor button loop autofs4 ext4 crc16 mbcache jbd2 sd_mod sr_mod cdrom ata_generic virtio_scsi ata_piix libata virtio_pci virtio_ring crc32c_intel scsi_mod e1000 virtio floppy [last unloaded: btrfs]
[39389.800016] irq event stamp: 0
[39389.800016] hardirqs last  enabled at (0): [&lt;          (null)&gt;]           (null)
[39389.800016] hardirqs last disabled at (0): [&lt;ffffffff8104e58d&gt;] copy_process+0x638/0x1a35
[39389.800016] softirqs last  enabled at (0): [&lt;ffffffff8104e58d&gt;] copy_process+0x638/0x1a35
[39389.800016] softirqs last disabled at (0): [&lt;          (null)&gt;]           (null)
[39389.800016] CPU: 14 PID: 32165 Comm: fdm-stress Not tainted 4.4.0-rc6-btrfs-next-18+ #1
[39389.800016] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014
[39389.800016] task: ffff880175b1ca40 ti: ffff8800a185c000 task.ti: ffff8800a185c000
[39389.800016] RIP: 0010:[&lt;ffffffff810902af&gt;]  [&lt;ffffffff810902af&gt;] queued_spin_lock_slowpath+0x57/0x158
[39389.800016] RSP: 0018:ffff8800a185fb80  EFLAGS: 00000202
[39389.800016] RAX: 0000000000000101 RBX: ffff8801710c4e9c RCX: 0000000000000101
[39389.800016] RDX: 0000000000000100 RSI: 0000000000000001 RDI: 0000000000000001
[39389.800016] RBP: ffff8800a185fb98 R08: 0000000000000001 R09: 0000000000000000
[39389.800016] R10: ffff8800a185fb68 R11: 6db6db6db6db6db7 R12: ffff8801710c4e98
[39389.800016] R13: ffff880175b1ca40 R14: ffff8800a185fc10 R15: ffff880175b1ca40
[39389.800016] FS:  00007f6d37fff700(0000) GS:ffff8802be9c0000(0000) knlGS:0000000000000000
[39389.800016] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[39389.800016] CR2: 00007f6d300019b8 CR3: 0000000037c93000 CR4: 00000000001406e0
[39389.800016] Stack:
[39389.800016]  ffff8801710c4e98 ffff8801710c4e98 ffff880175b1ca40 ffff8800a185fbb0
[39389.800016]  ffffffff81091e11 ffff8801710c4e98 ffff8800a185fbc8 ffffffff81091895
[39389.800016]  ffff8801710c4e98 ffff8800a185fbe8 ffffffff81486c5c ffffffffa067288c
[39389.800016] Call Trace:
[39389.800016]  [&lt;ffffffff81091e11&gt;] queued_read_lock_slowpath+0x46/0x60
[39389.800016]  [&lt;ffffffff81091895&gt;] do_raw_read_lock+0x3e/0x41
[39389.800016]  [&lt;ffffffff81486c5c&gt;] _raw_read_lock+0x3d/0x44
[39389.800016]  [&lt;ffffffffa067288c&gt;] ? btrfs_tree_read_lock+0x54/0x125 [btrfs]
[39389.800016]  [&lt;ffffffffa067288c&gt;] btrfs_tree_read_lock+0x54/0x125 [btrfs]
[39389.800016]  [&lt;ffffffffa0622ced&gt;] ? btrfs_find_item+0xa7/0xd2 [btrfs]
[39389.800016]  [&lt;ffffffffa069363f&gt;] btrfs_ref_to_path+0xd6/0x174 [btrfs]
[39389.800016]  [&lt;ffffffffa0693730&gt;] inode_to_path+0x53/0xa2 [btrfs]
[39389.800016]  [&lt;ffffffffa0693e2e&gt;] paths_from_inode+0x117/0x2ec [btrfs]
[39389.800016]  [&lt;ffffffffa0670cff&gt;] btrfs_ioctl+0xd5b/0x2793 [btrfs]
[39389.800016]  [&lt;ffffffff8108a8b0&gt;] ? arch_local_irq_save+0x9/0xc
[39389.800016]  [&lt;ffffffff81276727&gt;] ? __this_cpu_preempt_check+0x13/0x15
[39389.800016]  [&lt;ffffffff8108a8b0&gt;] ? arch_local_irq_save+0x9/0xc
[39389.800016]  [&lt;ffffffff8118b3d4&gt;] ? rcu_read_unlock+0x3e/0x5d
[39389.800016]  [&lt;ffffffff811822f8&gt;] do_vfs_ioctl+0x42b/0x4ea
[39389.800016]  [&lt;ffffffff8118b4f3&gt;] ? __fget_light+0x62/0x71
[39389.800016]  [&lt;ffffffff8118240e&gt;] SyS_ioctl+0x57/0x79
[39389.800016]  [&lt;ffffffff814872d7&gt;] entry_SYSCALL_64_fastpath+0x12/0x6f
[39389.800016] Code: b9 01 01 00 00 f7 c6 00 ff ff ff 75 32 83 fe 01 89 ca 89 f0 0f 45 d7 f0 0f b1 13 39 f0 74 04 89 c6 eb e2 ff ca 0f 84 fa 00 00 00 &lt;8b&gt; 03 84 c0 74 04 f3 90 eb f6 66 c7 03 01 00 e9 e6 00 00 00 e8
[39389.800012] Modules linked in: btrfs dm_mod ppdev xor sha256_generic hmac raid6_pq drbg ansi_cprng aesni_intel i2c_piix4 acpi_cpufreq aes_x86_64 ablk_helper tpm_tis parport_pc i2c_core sg cryptd evdev psmouse lrw tpm parport gf128mul serio_raw pcspkr glue_helper processor button loop autofs4 ext4 crc16 mbcache jbd2 sd_mod sr_mod cdrom ata_generic virtio_scsi ata_piix libata virtio_pci virtio_ring crc32c_intel scsi_mod e1000 virtio floppy [last unloaded: btrfs]
[39389.800012] irq event stamp: 0
[39389.800012] hardirqs last  enabled at (0): [&lt;          (null)&gt;]           (null)
[39389.800012] hardirqs last disabled at (0): [&lt;ffffffff8104e58d&gt;] copy_process+0x638/0x1a35
[39389.800012] softirqs last  enabled at (0): [&lt;ffffffff8104e58d&gt;] copy_process+0x638/0x1a35
[39389.800012] softirqs last disabled at (0): [&lt;          (null)&gt;]           (null)
[39389.800012] CPU: 15 PID: 32166 Comm: fdm-stress Tainted: G             L  4.4.0-rc6-btrfs-next-18+ #1
[39389.800012] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014
[39389.800012] task: ffff880179294380 ti: ffff880034a60000 task.ti: ffff880034a60000
[39389.800012] RIP: 0010:[&lt;ffffffff81091e8d&gt;]  [&lt;ffffffff81091e8d&gt;] queued_write_lock_slowpath+0x62/0x72
[39389.800012] RSP: 0018:ffff880034a639f0  EFLAGS: 00000206
[39389.800012] RAX: 0000000000000101 RBX: ffff8801710c4e98 RCX: 0000000000000000
[39389.800012] RDX: 00000000000000ff RSI: 0000000000000000 RDI: ffff8801710c4e9c
[39389.800012] RBP: ffff880034a639f8 R08: 0000000000000001 R09: 0000000000000000
[39389.800012] R10: ffff880034a639b0 R11: 0000000000001000 R12: ffff8801710c4e98
[39389.800012] R13: 0000000000000001 R14: ffff880172cbc000 R15: ffff8801710c4e00
[39389.800012] FS:  00007f6d377fe700(0000) GS:ffff8802be9e0000(0000) knlGS:0000000000000000
[39389.800012] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[39389.800012] CR2: 00007f6d3d3c1000 CR3: 0000000037c93000 CR4: 00000000001406e0
[39389.800012] Stack:
[39389.800012]  ffff8801710c4e98 ffff880034a63a10 ffffffff81091963 ffff8801710c4e98
[39389.800012]  ffff880034a63a30 ffffffff81486f1b ffffffffa0672cb3 ffff8801710c4e00
[39389.800012]  ffff880034a63a78 ffffffffa0672cb3 ffff8801710c4e00 ffff880034a63a58
[39389.800012] Call Trace:
[39389.800012]  [&lt;ffffffff81091963&gt;] do_raw_write_lock+0x72/0x8c
[39389.800012]  [&lt;ffffffff81486f1b&gt;] _raw_write_lock+0x3a/0x41
[39389.800012]  [&lt;ffffffffa0672cb3&gt;] ? btrfs_tree_lock+0x119/0x251 [btrfs]
[39389.800012]  [&lt;ffffffffa0672cb3&gt;] btrfs_tree_lock+0x119/0x251 [btrfs]
[39389.800012]  [&lt;ffffffffa061aeba&gt;] ? rcu_read_unlock+0x5b/0x5d [btrfs]
[39389.800012]  [&lt;ffffffffa061ce13&gt;] ? btrfs_root_node+0xda/0xe6 [btrfs]
[39389.800012]  [&lt;ffffffffa061ce83&gt;] btrfs_lock_root_node+0x22/0x42 [btrfs]
[39389.800012]  [&lt;ffffffffa062046b&gt;] btrfs_search_slot+0x1b8/0x758 [btrfs]
[39389.800012]  [&lt;ffffffff810fc6b0&gt;] ? time_hardirqs_on+0x15/0x28
[39389.800012]  [&lt;ffffffffa06365db&gt;] btrfs_lookup_inode+0x31/0x95 [btrfs]
[39389.800012]  [&lt;ffffffff8108d62f&gt;] ? trace_hardirqs_on+0xd/0xf
[39389.800012]  [&lt;ffffffff8148482b&gt;] ? mutex_lock_nested+0x397/0x3bc
[39389.800012]  [&lt;ffffffffa068821b&gt;] __btrfs_update_delayed_inode+0x59/0x1c0 [btrfs]
[39389.800012]  [&lt;ffffffffa068858e&gt;] __btrfs_commit_inode_delayed_items+0x194/0x5aa [btrfs]
[39389.800012]  [&lt;ffffffff81486ab7&gt;] ? _raw_spin_unlock+0x31/0x44
[39389.800012]  [&lt;ffffffffa0688a48&gt;] __btrfs_run_delayed_items+0xa4/0x15c [btrfs]
[39389.800012]  [&lt;ffffffffa0688d62&gt;] btrfs_run_delayed_items+0x11/0x13 [btrfs]
[39389.800012]  [&lt;ffffffffa064048e&gt;] btrfs_commit_transaction+0x234/0x96e [btrfs]
[39389.800012]  [&lt;ffffffffa0618d10&gt;] btrfs_sync_fs+0x145/0x1ad [btrfs]
[39389.800012]  [&lt;ffffffffa0671176&gt;] btrfs_ioctl+0x11d2/0x2793 [btrfs]
[39389.800012]  [&lt;ffffffff8108a8b0&gt;] ? arch_local_irq_save+0x9/0xc
[39389.800012]  [&lt;ffffffff81140261&gt;] ? __might_fault+0x4c/0xa7
[39389.800012]  [&lt;ffffffff81140261&gt;] ? __might_fault+0x4c/0xa7
[39389.800012]  [&lt;ffffffff8108a8b0&gt;] ? arch_local_irq_save+0x9/0xc
[39389.800012]  [&lt;ffffffff8118b3d4&gt;] ? rcu_read_unlock+0x3e/0x5d
[39389.800012]  [&lt;ffffffff811822f8&gt;] do_vfs_ioctl+0x42b/0x4ea
[39389.800012]  [&lt;ffffffff8118b4f3&gt;] ? __fget_light+0x62/0x71
[39389.800012]  [&lt;ffffffff8118240e&gt;] SyS_ioctl+0x57/0x79
[39389.800012]  [&lt;ffffffff814872d7&gt;] entry_SYSCALL_64_fastpath+0x12/0x6f
[39389.800012] Code: f0 0f b1 13 85 c0 75 ef eb 2a f3 90 8a 03 84 c0 75 f8 f0 0f b0 13 84 c0 75 f0 ba ff 00 00 00 eb 0a f0 0f b1 13 ff c8 74 0b f3 90 &lt;8b&gt; 03 83 f8 01 75 f7 eb ed c6 43 04 00 5b 5d c3 0f 1f 44 00 00

This happens because in the code path executed by the inode_paths ioctl we
end up nesting two calls to read lock a leaf's rwlock when after the first
call to read_lock() and before the second call to read_lock(), another
task (running the delayed items as part of a transaction commit) has
already called write_lock() against the leaf's rwlock. This situation is
illustrated by the following diagram:

         Task A                       Task B

  btrfs_ref_to_path()               btrfs_commit_transaction()
    read_lock(&amp;eb-&gt;lock);

                                      btrfs_run_delayed_items()
                                        __btrfs_commit_inode_delayed_items()
                                          __btrfs_update_delayed_inode()
                                            btrfs_lookup_inode()

                                              write_lock(&amp;eb-&gt;lock);
                                                --&gt; task waits for lock

    read_lock(&amp;eb-&gt;lock);
    --&gt; makes this task hang
        forever (and task B too
	of course)

So fix this by avoiding doing the nested read lock, which is easily
avoidable. This issue does not happen if task B calls write_lock() after
task A does the second call to read_lock(), however there does not seem
to exist anything in the documentation that mentions what is the expected
behaviour for recursive locking of rwlocks (leaving the idea that doing
so is not a good usage of rwlocks).

Also, as a side effect necessary for this fix, make sure we do not
needlessly read lock extent buffers when the input path has skip_locking
set (used when called from send).

Cc: stable@vger.kernel.org
Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
While doing some tests I ran into an hang on an extent buffer's rwlock
that produced the following trace:

[39389.800012] NMI watchdog: BUG: soft lockup - CPU#15 stuck for 22s! [fdm-stress:32166]
[39389.800016] NMI watchdog: BUG: soft lockup - CPU#14 stuck for 22s! [fdm-stress:32165]
[39389.800016] Modules linked in: btrfs dm_mod ppdev xor sha256_generic hmac raid6_pq drbg ansi_cprng aesni_intel i2c_piix4 acpi_cpufreq aes_x86_64 ablk_helper tpm_tis parport_pc i2c_core sg cryptd evdev psmouse lrw tpm parport gf128mul serio_raw pcspkr glue_helper processor button loop autofs4 ext4 crc16 mbcache jbd2 sd_mod sr_mod cdrom ata_generic virtio_scsi ata_piix libata virtio_pci virtio_ring crc32c_intel scsi_mod e1000 virtio floppy [last unloaded: btrfs]
[39389.800016] irq event stamp: 0
[39389.800016] hardirqs last  enabled at (0): [&lt;          (null)&gt;]           (null)
[39389.800016] hardirqs last disabled at (0): [&lt;ffffffff8104e58d&gt;] copy_process+0x638/0x1a35
[39389.800016] softirqs last  enabled at (0): [&lt;ffffffff8104e58d&gt;] copy_process+0x638/0x1a35
[39389.800016] softirqs last disabled at (0): [&lt;          (null)&gt;]           (null)
[39389.800016] CPU: 14 PID: 32165 Comm: fdm-stress Not tainted 4.4.0-rc6-btrfs-next-18+ #1
[39389.800016] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014
[39389.800016] task: ffff880175b1ca40 ti: ffff8800a185c000 task.ti: ffff8800a185c000
[39389.800016] RIP: 0010:[&lt;ffffffff810902af&gt;]  [&lt;ffffffff810902af&gt;] queued_spin_lock_slowpath+0x57/0x158
[39389.800016] RSP: 0018:ffff8800a185fb80  EFLAGS: 00000202
[39389.800016] RAX: 0000000000000101 RBX: ffff8801710c4e9c RCX: 0000000000000101
[39389.800016] RDX: 0000000000000100 RSI: 0000000000000001 RDI: 0000000000000001
[39389.800016] RBP: ffff8800a185fb98 R08: 0000000000000001 R09: 0000000000000000
[39389.800016] R10: ffff8800a185fb68 R11: 6db6db6db6db6db7 R12: ffff8801710c4e98
[39389.800016] R13: ffff880175b1ca40 R14: ffff8800a185fc10 R15: ffff880175b1ca40
[39389.800016] FS:  00007f6d37fff700(0000) GS:ffff8802be9c0000(0000) knlGS:0000000000000000
[39389.800016] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[39389.800016] CR2: 00007f6d300019b8 CR3: 0000000037c93000 CR4: 00000000001406e0
[39389.800016] Stack:
[39389.800016]  ffff8801710c4e98 ffff8801710c4e98 ffff880175b1ca40 ffff8800a185fbb0
[39389.800016]  ffffffff81091e11 ffff8801710c4e98 ffff8800a185fbc8 ffffffff81091895
[39389.800016]  ffff8801710c4e98 ffff8800a185fbe8 ffffffff81486c5c ffffffffa067288c
[39389.800016] Call Trace:
[39389.800016]  [&lt;ffffffff81091e11&gt;] queued_read_lock_slowpath+0x46/0x60
[39389.800016]  [&lt;ffffffff81091895&gt;] do_raw_read_lock+0x3e/0x41
[39389.800016]  [&lt;ffffffff81486c5c&gt;] _raw_read_lock+0x3d/0x44
[39389.800016]  [&lt;ffffffffa067288c&gt;] ? btrfs_tree_read_lock+0x54/0x125 [btrfs]
[39389.800016]  [&lt;ffffffffa067288c&gt;] btrfs_tree_read_lock+0x54/0x125 [btrfs]
[39389.800016]  [&lt;ffffffffa0622ced&gt;] ? btrfs_find_item+0xa7/0xd2 [btrfs]
[39389.800016]  [&lt;ffffffffa069363f&gt;] btrfs_ref_to_path+0xd6/0x174 [btrfs]
[39389.800016]  [&lt;ffffffffa0693730&gt;] inode_to_path+0x53/0xa2 [btrfs]
[39389.800016]  [&lt;ffffffffa0693e2e&gt;] paths_from_inode+0x117/0x2ec [btrfs]
[39389.800016]  [&lt;ffffffffa0670cff&gt;] btrfs_ioctl+0xd5b/0x2793 [btrfs]
[39389.800016]  [&lt;ffffffff8108a8b0&gt;] ? arch_local_irq_save+0x9/0xc
[39389.800016]  [&lt;ffffffff81276727&gt;] ? __this_cpu_preempt_check+0x13/0x15
[39389.800016]  [&lt;ffffffff8108a8b0&gt;] ? arch_local_irq_save+0x9/0xc
[39389.800016]  [&lt;ffffffff8118b3d4&gt;] ? rcu_read_unlock+0x3e/0x5d
[39389.800016]  [&lt;ffffffff811822f8&gt;] do_vfs_ioctl+0x42b/0x4ea
[39389.800016]  [&lt;ffffffff8118b4f3&gt;] ? __fget_light+0x62/0x71
[39389.800016]  [&lt;ffffffff8118240e&gt;] SyS_ioctl+0x57/0x79
[39389.800016]  [&lt;ffffffff814872d7&gt;] entry_SYSCALL_64_fastpath+0x12/0x6f
[39389.800016] Code: b9 01 01 00 00 f7 c6 00 ff ff ff 75 32 83 fe 01 89 ca 89 f0 0f 45 d7 f0 0f b1 13 39 f0 74 04 89 c6 eb e2 ff ca 0f 84 fa 00 00 00 &lt;8b&gt; 03 84 c0 74 04 f3 90 eb f6 66 c7 03 01 00 e9 e6 00 00 00 e8
[39389.800012] Modules linked in: btrfs dm_mod ppdev xor sha256_generic hmac raid6_pq drbg ansi_cprng aesni_intel i2c_piix4 acpi_cpufreq aes_x86_64 ablk_helper tpm_tis parport_pc i2c_core sg cryptd evdev psmouse lrw tpm parport gf128mul serio_raw pcspkr glue_helper processor button loop autofs4 ext4 crc16 mbcache jbd2 sd_mod sr_mod cdrom ata_generic virtio_scsi ata_piix libata virtio_pci virtio_ring crc32c_intel scsi_mod e1000 virtio floppy [last unloaded: btrfs]
[39389.800012] irq event stamp: 0
[39389.800012] hardirqs last  enabled at (0): [&lt;          (null)&gt;]           (null)
[39389.800012] hardirqs last disabled at (0): [&lt;ffffffff8104e58d&gt;] copy_process+0x638/0x1a35
[39389.800012] softirqs last  enabled at (0): [&lt;ffffffff8104e58d&gt;] copy_process+0x638/0x1a35
[39389.800012] softirqs last disabled at (0): [&lt;          (null)&gt;]           (null)
[39389.800012] CPU: 15 PID: 32166 Comm: fdm-stress Tainted: G             L  4.4.0-rc6-btrfs-next-18+ #1
[39389.800012] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014
[39389.800012] task: ffff880179294380 ti: ffff880034a60000 task.ti: ffff880034a60000
[39389.800012] RIP: 0010:[&lt;ffffffff81091e8d&gt;]  [&lt;ffffffff81091e8d&gt;] queued_write_lock_slowpath+0x62/0x72
[39389.800012] RSP: 0018:ffff880034a639f0  EFLAGS: 00000206
[39389.800012] RAX: 0000000000000101 RBX: ffff8801710c4e98 RCX: 0000000000000000
[39389.800012] RDX: 00000000000000ff RSI: 0000000000000000 RDI: ffff8801710c4e9c
[39389.800012] RBP: ffff880034a639f8 R08: 0000000000000001 R09: 0000000000000000
[39389.800012] R10: ffff880034a639b0 R11: 0000000000001000 R12: ffff8801710c4e98
[39389.800012] R13: 0000000000000001 R14: ffff880172cbc000 R15: ffff8801710c4e00
[39389.800012] FS:  00007f6d377fe700(0000) GS:ffff8802be9e0000(0000) knlGS:0000000000000000
[39389.800012] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[39389.800012] CR2: 00007f6d3d3c1000 CR3: 0000000037c93000 CR4: 00000000001406e0
[39389.800012] Stack:
[39389.800012]  ffff8801710c4e98 ffff880034a63a10 ffffffff81091963 ffff8801710c4e98
[39389.800012]  ffff880034a63a30 ffffffff81486f1b ffffffffa0672cb3 ffff8801710c4e00
[39389.800012]  ffff880034a63a78 ffffffffa0672cb3 ffff8801710c4e00 ffff880034a63a58
[39389.800012] Call Trace:
[39389.800012]  [&lt;ffffffff81091963&gt;] do_raw_write_lock+0x72/0x8c
[39389.800012]  [&lt;ffffffff81486f1b&gt;] _raw_write_lock+0x3a/0x41
[39389.800012]  [&lt;ffffffffa0672cb3&gt;] ? btrfs_tree_lock+0x119/0x251 [btrfs]
[39389.800012]  [&lt;ffffffffa0672cb3&gt;] btrfs_tree_lock+0x119/0x251 [btrfs]
[39389.800012]  [&lt;ffffffffa061aeba&gt;] ? rcu_read_unlock+0x5b/0x5d [btrfs]
[39389.800012]  [&lt;ffffffffa061ce13&gt;] ? btrfs_root_node+0xda/0xe6 [btrfs]
[39389.800012]  [&lt;ffffffffa061ce83&gt;] btrfs_lock_root_node+0x22/0x42 [btrfs]
[39389.800012]  [&lt;ffffffffa062046b&gt;] btrfs_search_slot+0x1b8/0x758 [btrfs]
[39389.800012]  [&lt;ffffffff810fc6b0&gt;] ? time_hardirqs_on+0x15/0x28
[39389.800012]  [&lt;ffffffffa06365db&gt;] btrfs_lookup_inode+0x31/0x95 [btrfs]
[39389.800012]  [&lt;ffffffff8108d62f&gt;] ? trace_hardirqs_on+0xd/0xf
[39389.800012]  [&lt;ffffffff8148482b&gt;] ? mutex_lock_nested+0x397/0x3bc
[39389.800012]  [&lt;ffffffffa068821b&gt;] __btrfs_update_delayed_inode+0x59/0x1c0 [btrfs]
[39389.800012]  [&lt;ffffffffa068858e&gt;] __btrfs_commit_inode_delayed_items+0x194/0x5aa [btrfs]
[39389.800012]  [&lt;ffffffff81486ab7&gt;] ? _raw_spin_unlock+0x31/0x44
[39389.800012]  [&lt;ffffffffa0688a48&gt;] __btrfs_run_delayed_items+0xa4/0x15c [btrfs]
[39389.800012]  [&lt;ffffffffa0688d62&gt;] btrfs_run_delayed_items+0x11/0x13 [btrfs]
[39389.800012]  [&lt;ffffffffa064048e&gt;] btrfs_commit_transaction+0x234/0x96e [btrfs]
[39389.800012]  [&lt;ffffffffa0618d10&gt;] btrfs_sync_fs+0x145/0x1ad [btrfs]
[39389.800012]  [&lt;ffffffffa0671176&gt;] btrfs_ioctl+0x11d2/0x2793 [btrfs]
[39389.800012]  [&lt;ffffffff8108a8b0&gt;] ? arch_local_irq_save+0x9/0xc
[39389.800012]  [&lt;ffffffff81140261&gt;] ? __might_fault+0x4c/0xa7
[39389.800012]  [&lt;ffffffff81140261&gt;] ? __might_fault+0x4c/0xa7
[39389.800012]  [&lt;ffffffff8108a8b0&gt;] ? arch_local_irq_save+0x9/0xc
[39389.800012]  [&lt;ffffffff8118b3d4&gt;] ? rcu_read_unlock+0x3e/0x5d
[39389.800012]  [&lt;ffffffff811822f8&gt;] do_vfs_ioctl+0x42b/0x4ea
[39389.800012]  [&lt;ffffffff8118b4f3&gt;] ? __fget_light+0x62/0x71
[39389.800012]  [&lt;ffffffff8118240e&gt;] SyS_ioctl+0x57/0x79
[39389.800012]  [&lt;ffffffff814872d7&gt;] entry_SYSCALL_64_fastpath+0x12/0x6f
[39389.800012] Code: f0 0f b1 13 85 c0 75 ef eb 2a f3 90 8a 03 84 c0 75 f8 f0 0f b0 13 84 c0 75 f0 ba ff 00 00 00 eb 0a f0 0f b1 13 ff c8 74 0b f3 90 &lt;8b&gt; 03 83 f8 01 75 f7 eb ed c6 43 04 00 5b 5d c3 0f 1f 44 00 00

This happens because in the code path executed by the inode_paths ioctl we
end up nesting two calls to read lock a leaf's rwlock when after the first
call to read_lock() and before the second call to read_lock(), another
task (running the delayed items as part of a transaction commit) has
already called write_lock() against the leaf's rwlock. This situation is
illustrated by the following diagram:

         Task A                       Task B

  btrfs_ref_to_path()               btrfs_commit_transaction()
    read_lock(&amp;eb-&gt;lock);

                                      btrfs_run_delayed_items()
                                        __btrfs_commit_inode_delayed_items()
                                          __btrfs_update_delayed_inode()
                                            btrfs_lookup_inode()

                                              write_lock(&amp;eb-&gt;lock);
                                                --&gt; task waits for lock

    read_lock(&amp;eb-&gt;lock);
    --&gt; makes this task hang
        forever (and task B too
	of course)

So fix this by avoiding doing the nested read lock, which is easily
avoidable. This issue does not happen if task B calls write_lock() after
task A does the second call to read_lock(), however there does not seem
to exist anything in the documentation that mentions what is the expected
behaviour for recursive locking of rwlocks (leaving the idea that doing
so is not a good usage of rwlocks).

Also, as a side effect necessary for this fix, make sure we do not
needlessly read lock extent buffers when the input path has skip_locking
set (used when called from send).

Cc: stable@vger.kernel.org
Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: remove no longer used function extent_read_full_page_nolock()</title>
<updated>2016-02-03T19:27:10+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2016-01-27T19:17:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=7f042a8370a5bb7e29a6a6372e8180a56d44aa5c'/>
<id>7f042a8370a5bb7e29a6a6372e8180a56d44aa5c</id>
<content type='text'>
Not needed after the previous patch named
"Btrfs: fix page reading in extent_same ioctl leading to csum errors".

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Not needed after the previous patch named
"Btrfs: fix page reading in extent_same ioctl leading to csum errors".

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fix page reading in extent_same ioctl leading to csum errors</title>
<updated>2016-02-03T19:27:10+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2016-01-27T18:37:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=313140023026ae542ad76e7e268c56a1eaa2c28e'/>
<id>313140023026ae542ad76e7e268c56a1eaa2c28e</id>
<content type='text'>
In the extent_same ioctl, we were grabbing the pages (locked) and
attempting to read them without bothering about any concurrent IO
against them. That is, we were not checking for any ongoing ordered
extents nor waiting for them to complete, which leads to a race where
the extent_same() code gets a checksum verification error when it
reads the pages, producing a message like the following in dmesg
and making the operation fail to user space with -ENOMEM:

[18990.161265] BTRFS warning (device sdc): csum failed ino 259 off 495616 csum 685204116 expected csum 1515870868

Fix this by using btrfs_readpage() for reading the pages instead of
extent_read_full_page_nolock(), which waits for any concurrent ordered
extents to complete and locks the io range. Also do better error handling
and don't treat all failures as -ENOMEM, as that's clearly misleasing,
becoming identical to the checks and operation of prepare_uptodate_page().

The use of extent_read_full_page_nolock() was required before
commit f441460202cb ("btrfs: fix deadlock with extent-same and readpage"),
as we had the range locked in an inode's io tree before attempting to
read the pages.

Fixes: f441460202cb ("btrfs: fix deadlock with extent-same and readpage")
Cc: stable@vger.kernel.org   # 4.2+
Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In the extent_same ioctl, we were grabbing the pages (locked) and
attempting to read them without bothering about any concurrent IO
against them. That is, we were not checking for any ongoing ordered
extents nor waiting for them to complete, which leads to a race where
the extent_same() code gets a checksum verification error when it
reads the pages, producing a message like the following in dmesg
and making the operation fail to user space with -ENOMEM:

[18990.161265] BTRFS warning (device sdc): csum failed ino 259 off 495616 csum 685204116 expected csum 1515870868

Fix this by using btrfs_readpage() for reading the pages instead of
extent_read_full_page_nolock(), which waits for any concurrent ordered
extents to complete and locks the io range. Also do better error handling
and don't treat all failures as -ENOMEM, as that's clearly misleasing,
becoming identical to the checks and operation of prepare_uptodate_page().

The use of extent_read_full_page_nolock() was required before
commit f441460202cb ("btrfs: fix deadlock with extent-same and readpage"),
as we had the range locked in an inode's io tree before attempting to
read the pages.

Fixes: f441460202cb ("btrfs: fix deadlock with extent-same and readpage")
Cc: stable@vger.kernel.org   # 4.2+
Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fix invalid page accesses in extent_same (dedup) ioctl</title>
<updated>2016-02-03T19:27:09+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2016-01-27T10:20:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=e0bd70c67bf996b360f706b6c643000f2e384681'/>
<id>e0bd70c67bf996b360f706b6c643000f2e384681</id>
<content type='text'>
In the extent_same ioctl we are getting the pages for the source and
target ranges and unlocking them immediately after, which is incorrect
because later we attempt to map them (with kmap_atomic) and access their
contents at btrfs_cmp_data(). When we do such access the pages might have
been relocated or removed from memory, which leads to an invalid memory
access. This issue is detected on a kernel with CONFIG_DEBUG_PAGEALLOC=y
which produces a trace like the following:

186736.677437] general protection fault: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
[186736.680382] Modules linked in: btrfs dm_flakey dm_mod ppdev xor raid6_pq sha256_generic hmac drbg ansi_cprng acpi_cpufreq evdev sg aesni_intel aes_x86_64
parport_pc ablk_helper tpm_tis psmouse parport i2c_piix4 tpm cryptd i2c_core lrw processor button serio_raw pcspkr gf128mul glue_helper loop autofs4 ext4
crc16 mbcache jbd2 sd_mod sr_mod cdrom ata_generic virtio_scsi ata_piix libata virtio_pci virtio_ring crc32c_intel scsi_mod e1000 virtio floppy [last
unloaded: btrfs]
[186736.681319] CPU: 13 PID: 10222 Comm: duperemove Tainted: G        W       4.4.0-rc6-btrfs-next-18+ #1
[186736.681319] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014
[186736.681319] task: ffff880132600400 ti: ffff880362284000 task.ti: ffff880362284000
[186736.681319] RIP: 0010:[&lt;ffffffff81264d00&gt;]  [&lt;ffffffff81264d00&gt;] memcmp+0xb/0x22
[186736.681319] RSP: 0018:ffff880362287d70  EFLAGS: 00010287
[186736.681319] RAX: 000002c002468acf RBX: 0000000012345678 RCX: 0000000000000000
[186736.681319] RDX: 0000000000001000 RSI: 0005d129c5cf9000 RDI: 0005d129c5cf9000
[186736.681319] RBP: ffff880362287d70 R08: 0000000000000000 R09: 0000000000001000
[186736.681319] R10: ffff880000000000 R11: 0000000000000476 R12: 0000000000001000
[186736.681319] R13: ffff8802f91d4c88 R14: ffff8801f2a77830 R15: ffff880352e83e40
[186736.681319] FS:  00007f27b37fe700(0000) GS:ffff88043dda0000(0000) knlGS:0000000000000000
[186736.681319] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[186736.681319] CR2: 00007f27a406a000 CR3: 0000000217421000 CR4: 00000000001406e0
[186736.681319] Stack:
[186736.681319]  ffff880362287ea0 ffffffffa048d0bd 000000000009f000 0000000000001000
[186736.681319]  0100000000000000 ffff8801f2a77850 ffff8802f91d49b0 ffff880132600400
[186736.681319]  00000000000004f8 ffff8801c1efbe41 0000000000000000 0000000000000038
[186736.681319] Call Trace:
[186736.681319]  [&lt;ffffffffa048d0bd&gt;] btrfs_ioctl+0x24cb/0x2731 [btrfs]
[186736.681319]  [&lt;ffffffff8108a8b0&gt;] ? arch_local_irq_save+0x9/0xc
[186736.681319]  [&lt;ffffffff8118b3d4&gt;] ? rcu_read_unlock+0x3e/0x5d
[186736.681319]  [&lt;ffffffff811822f8&gt;] do_vfs_ioctl+0x42b/0x4ea
[186736.681319]  [&lt;ffffffff8118b4f3&gt;] ? __fget_light+0x62/0x71
[186736.681319]  [&lt;ffffffff8118240e&gt;] SyS_ioctl+0x57/0x79
[186736.681319]  [&lt;ffffffff814872d7&gt;] entry_SYSCALL_64_fastpath+0x12/0x6f
[186736.681319] Code: 0a 3c 6e 74 0d 3c 79 74 04 3c 59 75 0c c6 06 01 eb 03 c6 06 00 31 c0 eb 05 b8 ea ff ff ff 5d c3 55 31 c9 48 89 e5 48 39 d1 74 13 &lt;0f&gt; b6
04 0f 44 0f b6 04 0e 48 ff c1 44 29 c0 74 ea eb 02 31 c0

(gdb) list *(btrfs_ioctl+0x24cb)
0x5e0e1 is in btrfs_ioctl (fs/btrfs/ioctl.c:2972).
2967                    dst_addr = kmap_atomic(dst_page);
2968
2969                    flush_dcache_page(src_page);
2970                    flush_dcache_page(dst_page);
2971
2972                    if (memcmp(addr, dst_addr, cmp_len))
2973                            ret = BTRFS_SAME_DATA_DIFFERS;
2974
2975                    kunmap_atomic(addr);
2976                    kunmap_atomic(dst_addr);

So fix this by making sure we keep the pages locked and respect the same
locking order as everywhere else: get and lock the pages first and then
lock the range in the inode's io tree (like for example at
__btrfs_buffered_write() and extent_readpages()). If an ordered extent
is found after locking the range in the io tree, unlock the range,
unlock the pages, wait for the ordered extent to complete and repeat the
entire locking process until no overlapping ordered extents are found.

Cc: stable@vger.kernel.org   # 4.2+
Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In the extent_same ioctl we are getting the pages for the source and
target ranges and unlocking them immediately after, which is incorrect
because later we attempt to map them (with kmap_atomic) and access their
contents at btrfs_cmp_data(). When we do such access the pages might have
been relocated or removed from memory, which leads to an invalid memory
access. This issue is detected on a kernel with CONFIG_DEBUG_PAGEALLOC=y
which produces a trace like the following:

186736.677437] general protection fault: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
[186736.680382] Modules linked in: btrfs dm_flakey dm_mod ppdev xor raid6_pq sha256_generic hmac drbg ansi_cprng acpi_cpufreq evdev sg aesni_intel aes_x86_64
parport_pc ablk_helper tpm_tis psmouse parport i2c_piix4 tpm cryptd i2c_core lrw processor button serio_raw pcspkr gf128mul glue_helper loop autofs4 ext4
crc16 mbcache jbd2 sd_mod sr_mod cdrom ata_generic virtio_scsi ata_piix libata virtio_pci virtio_ring crc32c_intel scsi_mod e1000 virtio floppy [last
unloaded: btrfs]
[186736.681319] CPU: 13 PID: 10222 Comm: duperemove Tainted: G        W       4.4.0-rc6-btrfs-next-18+ #1
[186736.681319] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014
[186736.681319] task: ffff880132600400 ti: ffff880362284000 task.ti: ffff880362284000
[186736.681319] RIP: 0010:[&lt;ffffffff81264d00&gt;]  [&lt;ffffffff81264d00&gt;] memcmp+0xb/0x22
[186736.681319] RSP: 0018:ffff880362287d70  EFLAGS: 00010287
[186736.681319] RAX: 000002c002468acf RBX: 0000000012345678 RCX: 0000000000000000
[186736.681319] RDX: 0000000000001000 RSI: 0005d129c5cf9000 RDI: 0005d129c5cf9000
[186736.681319] RBP: ffff880362287d70 R08: 0000000000000000 R09: 0000000000001000
[186736.681319] R10: ffff880000000000 R11: 0000000000000476 R12: 0000000000001000
[186736.681319] R13: ffff8802f91d4c88 R14: ffff8801f2a77830 R15: ffff880352e83e40
[186736.681319] FS:  00007f27b37fe700(0000) GS:ffff88043dda0000(0000) knlGS:0000000000000000
[186736.681319] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[186736.681319] CR2: 00007f27a406a000 CR3: 0000000217421000 CR4: 00000000001406e0
[186736.681319] Stack:
[186736.681319]  ffff880362287ea0 ffffffffa048d0bd 000000000009f000 0000000000001000
[186736.681319]  0100000000000000 ffff8801f2a77850 ffff8802f91d49b0 ffff880132600400
[186736.681319]  00000000000004f8 ffff8801c1efbe41 0000000000000000 0000000000000038
[186736.681319] Call Trace:
[186736.681319]  [&lt;ffffffffa048d0bd&gt;] btrfs_ioctl+0x24cb/0x2731 [btrfs]
[186736.681319]  [&lt;ffffffff8108a8b0&gt;] ? arch_local_irq_save+0x9/0xc
[186736.681319]  [&lt;ffffffff8118b3d4&gt;] ? rcu_read_unlock+0x3e/0x5d
[186736.681319]  [&lt;ffffffff811822f8&gt;] do_vfs_ioctl+0x42b/0x4ea
[186736.681319]  [&lt;ffffffff8118b4f3&gt;] ? __fget_light+0x62/0x71
[186736.681319]  [&lt;ffffffff8118240e&gt;] SyS_ioctl+0x57/0x79
[186736.681319]  [&lt;ffffffff814872d7&gt;] entry_SYSCALL_64_fastpath+0x12/0x6f
[186736.681319] Code: 0a 3c 6e 74 0d 3c 79 74 04 3c 59 75 0c c6 06 01 eb 03 c6 06 00 31 c0 eb 05 b8 ea ff ff ff 5d c3 55 31 c9 48 89 e5 48 39 d1 74 13 &lt;0f&gt; b6
04 0f 44 0f b6 04 0e 48 ff c1 44 29 c0 74 ea eb 02 31 c0

(gdb) list *(btrfs_ioctl+0x24cb)
0x5e0e1 is in btrfs_ioctl (fs/btrfs/ioctl.c:2972).
2967                    dst_addr = kmap_atomic(dst_page);
2968
2969                    flush_dcache_page(src_page);
2970                    flush_dcache_page(dst_page);
2971
2972                    if (memcmp(addr, dst_addr, cmp_len))
2973                            ret = BTRFS_SAME_DATA_DIFFERS;
2974
2975                    kunmap_atomic(addr);
2976                    kunmap_atomic(dst_addr);

So fix this by making sure we keep the pages locked and respect the same
locking order as everywhere else: get and lock the pages first and then
lock the range in the inode's io tree (like for example at
__btrfs_buffered_write() and extent_readpages()). If an ordered extent
is found after locking the range in the io tree, unlock the range,
unlock the pages, wait for the ordered extent to complete and repeat the
entire locking process until no overlapping ordered extents are found.

Cc: stable@vger.kernel.org   # 4.2+
Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
