<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux.git/fs/btrfs/inode.c, branch v4.2</title>
<subtitle>Linux kernel source tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/'/>
<entry>
<title>Btrfs: fix shrinking truncate when the no_holes feature is enabled</title>
<updated>2015-07-11T21:33:14+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2015-06-20T17:20:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=c1aa45759e90b4204ab8bce027a925fc7c87d00a'/>
<id>c1aa45759e90b4204ab8bce027a925fc7c87d00a</id>
<content type='text'>
If the no_holes feature is enabled, we attempt to shrink a file to a size
that ends up in the middle of a hole and we don't have any file extent
items in the fs/subvol tree that go beyond the new file size (or any
ordered extents that will insert such file extent items), we end up not
updating the inode's disk_i_size, we only update the inode's i_size.

This means that after unmounting and mounting the filesystem, or after
the inode is evicted and reloaded, its i_size ends up being incorrect
(an inode's i_size is set to the disk_i_size field when an inode is
loaded). This happens when btrfs_truncate_inode_items() doesn't find
any file extent items to drop - in this case it never makes a call to
btrfs_ordered_update_i_size() in order to update the inode's disk_i_size.

Example reproducer:

  $ mkfs.btrfs -O no-holes -f /dev/sdd
  $ mount /dev/sdd /mnt

  # Create our test file with some data and durably persist it.
  $ xfs_io -f -c "pwrite -S 0xaa 0 128K" /mnt/foo
  $ sync

  # Append some data to the file, increasing its size, and leave a hole
  # between the old size and the start offset if the following write. So
  # our file gets a hole in the range [128Kb, 256Kb[.
  $ xfs_io -c "truncate 160K" /mnt/foo

  # We expect to see our file with a size of 160Kb, with the first 128Kb
  # of data all having the value 0xaa and the remaining 32Kb of data all
  # having the value 0x00.
  $ od -t x1 /mnt/foo
  0000000 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa
  *
  0400000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  *
  0500000

  # Now cleanly unmount and mount again the filesystem.
  $ umount /mnt
  $ mount /dev/sdd /mnt

  # We expect to get the same result as before, a file with a size of
  # 160Kb, with the first 128Kb of data all having the value 0xaa and the
  # remaining 32Kb of data all having the value 0x00.
  $ od -t x1 /mnt/foo
  0000000 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa
  *
  0400000

In the example above the file size/data do not match what they were before
the remount.

Fix this by always calling btrfs_ordered_update_i_size() with a size
matching the size the file was truncated to if btrfs_truncate_inode_items()
is not called for a log tree and no file extent items were dropped. This
ensures the same behaviour as when the no_holes feature is not enabled.

A test case for fstests follows soon.

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
If the no_holes feature is enabled, we attempt to shrink a file to a size
that ends up in the middle of a hole and we don't have any file extent
items in the fs/subvol tree that go beyond the new file size (or any
ordered extents that will insert such file extent items), we end up not
updating the inode's disk_i_size, we only update the inode's i_size.

This means that after unmounting and mounting the filesystem, or after
the inode is evicted and reloaded, its i_size ends up being incorrect
(an inode's i_size is set to the disk_i_size field when an inode is
loaded). This happens when btrfs_truncate_inode_items() doesn't find
any file extent items to drop - in this case it never makes a call to
btrfs_ordered_update_i_size() in order to update the inode's disk_i_size.

Example reproducer:

  $ mkfs.btrfs -O no-holes -f /dev/sdd
  $ mount /dev/sdd /mnt

  # Create our test file with some data and durably persist it.
  $ xfs_io -f -c "pwrite -S 0xaa 0 128K" /mnt/foo
  $ sync

  # Append some data to the file, increasing its size, and leave a hole
  # between the old size and the start offset if the following write. So
  # our file gets a hole in the range [128Kb, 256Kb[.
  $ xfs_io -c "truncate 160K" /mnt/foo

  # We expect to see our file with a size of 160Kb, with the first 128Kb
  # of data all having the value 0xaa and the remaining 32Kb of data all
  # having the value 0x00.
  $ od -t x1 /mnt/foo
  0000000 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa
  *
  0400000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  *
  0500000

  # Now cleanly unmount and mount again the filesystem.
  $ umount /mnt
  $ mount /dev/sdd /mnt

  # We expect to get the same result as before, a file with a size of
  # 160Kb, with the first 128Kb of data all having the value 0xaa and the
  # remaining 32Kb of data all having the value 0x00.
  $ od -t x1 /mnt/foo
  0000000 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa
  *
  0400000

In the example above the file size/data do not match what they were before
the remount.

Fix this by always calling btrfs_ordered_update_i_size() with a size
matching the size the file was truncated to if btrfs_truncate_inode_items()
is not called for a log tree and no file extent items were dropped. This
ensures the same behaviour as when the no_holes feature is not enabled.

A test case for fstests follows soon.

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fix warning of bytes_may_use</title>
<updated>2015-07-02T00:17:21+00:00</updated>
<author>
<name>Liu Bo</name>
<email>bo.li.liu@oracle.com</email>
</author>
<published>2015-06-17T08:59:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=ddba1bfc2369cd0566bcfdab47599834a32d1c19'/>
<id>ddba1bfc2369cd0566bcfdab47599834a32d1c19</id>
<content type='text'>
While running generic/019, dmesg got several warnings from
btrfs_free_reserved_data_space().

Test generic/019 produces some disk failures so sumbit dio will get errors,
in which case, btrfs_direct_IO() goes to the error handling and free
bytes_may_use, but the problem is that bytes_may_use has been free'd
during get_block().

This adds a runtime flag to show if we've gone through get_block(), if so,
don't do the cleanup work.

Signed-off-by: Liu Bo &lt;bo.li.liu@oracle.com&gt;
Reviewed-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Tested-by: Filipe Manana &lt;fdmanana@suse.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>
While running generic/019, dmesg got several warnings from
btrfs_free_reserved_data_space().

Test generic/019 produces some disk failures so sumbit dio will get errors,
in which case, btrfs_direct_IO() goes to the error handling and free
bytes_may_use, but the problem is that bytes_may_use has been free'd
during get_block().

This adds a runtime flag to show if we've gone through get_block(), if so,
don't do the cleanup work.

Signed-off-by: Liu Bo &lt;bo.li.liu@oracle.com&gt;
Reviewed-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Tested-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fix hang when failing to submit bio of directIO</title>
<updated>2015-07-02T00:17:20+00:00</updated>
<author>
<name>Liu Bo</name>
<email>bo.li.liu@oracle.com</email>
</author>
<published>2015-06-17T08:59:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=ad9ee2053f3f2babebc09ebc4970daa66c56c7ee'/>
<id>ad9ee2053f3f2babebc09ebc4970daa66c56c7ee</id>
<content type='text'>
The hang is uncoverd by generic/019.

btrfs_endio_direct_write() skips the "finish_ordered_fn" part when it hits
an error, thus those added ordered extents will never get processed, which
block processes that waiting for them via btrfs_start_ordered_extent().

This fixes the above, and meanwhile finish_ordered_fn will do the space
accounting work.

Signed-off-by: Liu Bo &lt;bo.li.liu@oracle.com&gt;
Reviewed-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Tested-by: Filipe Manana &lt;fdmanana@suse.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 hang is uncoverd by generic/019.

btrfs_endio_direct_write() skips the "finish_ordered_fn" part when it hits
an error, thus those added ordered extents will never get processed, which
block processes that waiting for them via btrfs_start_ordered_extent().

This fixes the above, and meanwhile finish_ordered_fn will do the space
accounting work.

Signed-off-by: Liu Bo &lt;bo.li.liu@oracle.com&gt;
Reviewed-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Tested-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fix a comment in inode.c:evict_inode_truncate_pages()</title>
<updated>2015-07-02T00:17:19+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2015-06-10T11:55:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=9c6429d96daec64f6b5b10a1c6b02c7264541ea1'/>
<id>9c6429d96daec64f6b5b10a1c6b02c7264541ea1</id>
<content type='text'>
The comment was not correct about the part where it says the endio
callback of the bio might have not yet been called - update it
to mention that by that time the endio callback execution might
still be in progress only.

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: Liu Bo &lt;bo.li.liu@oracle.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 comment was not correct about the part where it says the endio
callback of the bio might have not yet been called - update it
to mention that by that time the endio callback execution might
still be in progress only.

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: Liu Bo &lt;bo.li.liu@oracle.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fix memory corruption on failure to submit bio for direct IO</title>
<updated>2015-07-02T00:17:18+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2015-07-01T11:13:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=61de718fceb6bc028dafe4d06a1f87a9e0998303'/>
<id>61de718fceb6bc028dafe4d06a1f87a9e0998303</id>
<content type='text'>
If we fail to submit a bio for a direct IO request, we were grabbing the
corresponding ordered extent and decrementing its reference count twice,
once for our lookup reference and once for the ordered tree reference.
This was a problem because it caused the ordered extent to be freed
without removing it from the ordered tree and any lists it might be
attached to, leaving dangling pointers to the ordered extent around.
Example trace with CONFIG_DEBUG_PAGEALLOC=y:

[161779.858707] BUG: unable to handle kernel paging request at 0000000087654330
[161779.859983] IP: [&lt;ffffffff8124ca68&gt;] rb_prev+0x22/0x3b
[161779.860636] PGD 34d818067 PUD 0
[161779.860636] Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
(...)
[161779.860636] Call Trace:
[161779.860636]  [&lt;ffffffffa06b36a6&gt;] __tree_search+0xd9/0xf9 [btrfs]
[161779.860636]  [&lt;ffffffffa06b3708&gt;] tree_search+0x42/0x63 [btrfs]
[161779.860636]  [&lt;ffffffffa06b4868&gt;] ? btrfs_lookup_ordered_range+0x2d/0xa5 [btrfs]
[161779.860636]  [&lt;ffffffffa06b4873&gt;] btrfs_lookup_ordered_range+0x38/0xa5 [btrfs]
[161779.860636]  [&lt;ffffffffa06aab8e&gt;] btrfs_get_blocks_direct+0x11b/0x615 [btrfs]
[161779.860636]  [&lt;ffffffff8119727f&gt;] do_blockdev_direct_IO+0x5ff/0xb43
[161779.860636]  [&lt;ffffffffa06aaa73&gt;] ? btrfs_page_exists_in_range+0x1ad/0x1ad [btrfs]
[161779.860636]  [&lt;ffffffffa06a2c9a&gt;] ? btrfs_get_extent_fiemap+0x1bc/0x1bc [btrfs]
[161779.860636]  [&lt;ffffffff811977f5&gt;] __blockdev_direct_IO+0x32/0x34
[161779.860636]  [&lt;ffffffffa06a2c9a&gt;] ? btrfs_get_extent_fiemap+0x1bc/0x1bc [btrfs]
[161779.860636]  [&lt;ffffffffa06a10ae&gt;] btrfs_direct_IO+0x198/0x21f [btrfs]
[161779.860636]  [&lt;ffffffffa06a2c9a&gt;] ? btrfs_get_extent_fiemap+0x1bc/0x1bc [btrfs]
[161779.860636]  [&lt;ffffffff81112ca1&gt;] generic_file_direct_write+0xb3/0x128
[161779.860636]  [&lt;ffffffffa06affaa&gt;] ? btrfs_file_write_iter+0x15f/0x3e0 [btrfs]
[161779.860636]  [&lt;ffffffffa06b004c&gt;] btrfs_file_write_iter+0x201/0x3e0 [btrfs]
(...)

We were also not freeing the btrfs_dio_private we allocated previously,
which kmemleak reported with the following trace in its sysfs file:

unreferenced object 0xffff8803f553bf80 (size 96):
  comm "xfs_io", pid 4501, jiffies 4295039588 (age 173.936s)
  hex dump (first 32 bytes):
    88 6c 9b f5 02 88 ff ff 00 00 00 00 00 00 00 00  .l..............
    00 00 00 00 00 00 00 00 00 00 c4 00 00 00 00 00  ................
  backtrace:
    [&lt;ffffffff81161ffe&gt;] create_object+0x172/0x29a
    [&lt;ffffffff8145870f&gt;] kmemleak_alloc+0x25/0x41
    [&lt;ffffffff81154e64&gt;] kmemleak_alloc_recursive.constprop.40+0x16/0x18
    [&lt;ffffffff811579ed&gt;] kmem_cache_alloc_trace+0xfb/0x148
    [&lt;ffffffffa03d8cff&gt;] btrfs_submit_direct+0x65/0x16a [btrfs]
    [&lt;ffffffff811968dc&gt;] dio_bio_submit+0x62/0x8f
    [&lt;ffffffff811975fe&gt;] do_blockdev_direct_IO+0x97e/0xb43
    [&lt;ffffffff811977f5&gt;] __blockdev_direct_IO+0x32/0x34
    [&lt;ffffffffa03d70ae&gt;] btrfs_direct_IO+0x198/0x21f [btrfs]
    [&lt;ffffffff81112ca1&gt;] generic_file_direct_write+0xb3/0x128
    [&lt;ffffffffa03e604d&gt;] btrfs_file_write_iter+0x201/0x3e0 [btrfs]
    [&lt;ffffffff8116586a&gt;] __vfs_write+0x7c/0xa5
    [&lt;ffffffff81165da9&gt;] vfs_write+0xa0/0xe4
    [&lt;ffffffff81166675&gt;] SyS_pwrite64+0x64/0x82
    [&lt;ffffffff81464fd7&gt;] system_call_fastpath+0x12/0x6f
    [&lt;ffffffffffffffff&gt;] 0xffffffffffffffff

For read requests we weren't doing any cleanup either (none of the work
done by btrfs_endio_direct_read()), so a failure submitting a bio for a
read request would leave a range in the inode's io_tree locked forever,
blocking any future operations (both reads and writes) against that range.

So fix this by making sure we do the same cleanup that we do for the case
where the bio submission succeeds.

Signed-off-by: Filipe Manana &lt;fdmanana@suse.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>
If we fail to submit a bio for a direct IO request, we were grabbing the
corresponding ordered extent and decrementing its reference count twice,
once for our lookup reference and once for the ordered tree reference.
This was a problem because it caused the ordered extent to be freed
without removing it from the ordered tree and any lists it might be
attached to, leaving dangling pointers to the ordered extent around.
Example trace with CONFIG_DEBUG_PAGEALLOC=y:

[161779.858707] BUG: unable to handle kernel paging request at 0000000087654330
[161779.859983] IP: [&lt;ffffffff8124ca68&gt;] rb_prev+0x22/0x3b
[161779.860636] PGD 34d818067 PUD 0
[161779.860636] Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
(...)
[161779.860636] Call Trace:
[161779.860636]  [&lt;ffffffffa06b36a6&gt;] __tree_search+0xd9/0xf9 [btrfs]
[161779.860636]  [&lt;ffffffffa06b3708&gt;] tree_search+0x42/0x63 [btrfs]
[161779.860636]  [&lt;ffffffffa06b4868&gt;] ? btrfs_lookup_ordered_range+0x2d/0xa5 [btrfs]
[161779.860636]  [&lt;ffffffffa06b4873&gt;] btrfs_lookup_ordered_range+0x38/0xa5 [btrfs]
[161779.860636]  [&lt;ffffffffa06aab8e&gt;] btrfs_get_blocks_direct+0x11b/0x615 [btrfs]
[161779.860636]  [&lt;ffffffff8119727f&gt;] do_blockdev_direct_IO+0x5ff/0xb43
[161779.860636]  [&lt;ffffffffa06aaa73&gt;] ? btrfs_page_exists_in_range+0x1ad/0x1ad [btrfs]
[161779.860636]  [&lt;ffffffffa06a2c9a&gt;] ? btrfs_get_extent_fiemap+0x1bc/0x1bc [btrfs]
[161779.860636]  [&lt;ffffffff811977f5&gt;] __blockdev_direct_IO+0x32/0x34
[161779.860636]  [&lt;ffffffffa06a2c9a&gt;] ? btrfs_get_extent_fiemap+0x1bc/0x1bc [btrfs]
[161779.860636]  [&lt;ffffffffa06a10ae&gt;] btrfs_direct_IO+0x198/0x21f [btrfs]
[161779.860636]  [&lt;ffffffffa06a2c9a&gt;] ? btrfs_get_extent_fiemap+0x1bc/0x1bc [btrfs]
[161779.860636]  [&lt;ffffffff81112ca1&gt;] generic_file_direct_write+0xb3/0x128
[161779.860636]  [&lt;ffffffffa06affaa&gt;] ? btrfs_file_write_iter+0x15f/0x3e0 [btrfs]
[161779.860636]  [&lt;ffffffffa06b004c&gt;] btrfs_file_write_iter+0x201/0x3e0 [btrfs]
(...)

We were also not freeing the btrfs_dio_private we allocated previously,
which kmemleak reported with the following trace in its sysfs file:

unreferenced object 0xffff8803f553bf80 (size 96):
  comm "xfs_io", pid 4501, jiffies 4295039588 (age 173.936s)
  hex dump (first 32 bytes):
    88 6c 9b f5 02 88 ff ff 00 00 00 00 00 00 00 00  .l..............
    00 00 00 00 00 00 00 00 00 00 c4 00 00 00 00 00  ................
  backtrace:
    [&lt;ffffffff81161ffe&gt;] create_object+0x172/0x29a
    [&lt;ffffffff8145870f&gt;] kmemleak_alloc+0x25/0x41
    [&lt;ffffffff81154e64&gt;] kmemleak_alloc_recursive.constprop.40+0x16/0x18
    [&lt;ffffffff811579ed&gt;] kmem_cache_alloc_trace+0xfb/0x148
    [&lt;ffffffffa03d8cff&gt;] btrfs_submit_direct+0x65/0x16a [btrfs]
    [&lt;ffffffff811968dc&gt;] dio_bio_submit+0x62/0x8f
    [&lt;ffffffff811975fe&gt;] do_blockdev_direct_IO+0x97e/0xb43
    [&lt;ffffffff811977f5&gt;] __blockdev_direct_IO+0x32/0x34
    [&lt;ffffffffa03d70ae&gt;] btrfs_direct_IO+0x198/0x21f [btrfs]
    [&lt;ffffffff81112ca1&gt;] generic_file_direct_write+0xb3/0x128
    [&lt;ffffffffa03e604d&gt;] btrfs_file_write_iter+0x201/0x3e0 [btrfs]
    [&lt;ffffffff8116586a&gt;] __vfs_write+0x7c/0xa5
    [&lt;ffffffff81165da9&gt;] vfs_write+0xa0/0xe4
    [&lt;ffffffff81166675&gt;] SyS_pwrite64+0x64/0x82
    [&lt;ffffffff81464fd7&gt;] system_call_fastpath+0x12/0x6f
    [&lt;ffffffffffffffff&gt;] 0xffffffffffffffff

For read requests we weren't doing any cleanup either (none of the work
done by btrfs_endio_direct_read()), so a failure submitting a bio for a
read request would leave a range in the inode's io_tree locked forever,
blocking any future operations (both reads and writes) against that range.

So fix this by making sure we do the same cleanup that we do for the case
where the bio submission succeeds.

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fix hang during inode eviction due to concurrent readahead</title>
<updated>2015-06-03T11:03:09+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2015-05-25T23:55:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=6ca0709756710c47ec604dd08b9fc45929d36390'/>
<id>6ca0709756710c47ec604dd08b9fc45929d36390</id>
<content type='text'>
Zygo Blaxell and other users have reported occasional hangs while an
inode is being evicted, leading to traces like the following:

[ 5281.972322] INFO: task rm:20488 blocked for more than 120 seconds.
[ 5281.973836]       Not tainted 4.0.0-rc5-btrfs-next-9+ #2
[ 5281.974818] "echo 0 &gt; /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 5281.976364] rm              D ffff8800724cfc38     0 20488   7747 0x00000000
[ 5281.977506]  ffff8800724cfc38 ffff8800724cfc38 ffff880065da5c50 0000000000000001
[ 5281.978461]  ffff8800724cffd8 ffff8801540a5f50 0000000000000008 ffff8801540a5f78
[ 5281.979541]  ffff8801540a5f50 ffff8800724cfc58 ffffffff8143107e 0000000000000123
[ 5281.981396] Call Trace:
[ 5281.982066]  [&lt;ffffffff8143107e&gt;] schedule+0x74/0x83
[ 5281.983341]  [&lt;ffffffffa03b33cf&gt;] wait_on_state+0xac/0xcd [btrfs]
[ 5281.985127]  [&lt;ffffffff81075cd6&gt;] ? signal_pending_state+0x31/0x31
[ 5281.986715]  [&lt;ffffffffa03b4b71&gt;] wait_extent_bit.constprop.32+0x7c/0xde [btrfs]
[ 5281.988680]  [&lt;ffffffffa03b540b&gt;] lock_extent_bits+0x5d/0x88 [btrfs]
[ 5281.990200]  [&lt;ffffffffa03a621d&gt;] btrfs_evict_inode+0x24e/0x5be [btrfs]
[ 5281.991781]  [&lt;ffffffff8116964d&gt;] evict+0xa0/0x148
[ 5281.992735]  [&lt;ffffffff8116a43d&gt;] iput+0x18f/0x1e5
[ 5281.993796]  [&lt;ffffffff81160d4a&gt;] do_unlinkat+0x15b/0x1fa
[ 5281.994806]  [&lt;ffffffff81435b54&gt;] ? ret_from_sys_call+0x1d/0x58
[ 5281.996120]  [&lt;ffffffff8107d314&gt;] ? trace_hardirqs_on_caller+0x18f/0x1ab
[ 5281.997562]  [&lt;ffffffff8123960b&gt;] ? trace_hardirqs_on_thunk+0x3a/0x3f
[ 5281.998815]  [&lt;ffffffff81161a16&gt;] SyS_unlinkat+0x29/0x2b
[ 5281.999920]  [&lt;ffffffff81435b32&gt;] system_call_fastpath+0x12/0x17
[ 5282.001299] 1 lock held by rm/20488:
[ 5282.002066]  #0:  (sb_writers#12){.+.+.+}, at: [&lt;ffffffff8116dd81&gt;] mnt_want_write+0x24/0x4b

This happens when we have readahead, which calls readpages(), happening
right before the inode eviction handler is invoked. So the reason is
essentially:

1) readpages() is called while a reference on the inode is held, so
   eviction can not be triggered before readpages() returns. It also
   locks one or more ranges in the inode's io_tree (which is done at
   extent_io.c:__do_contiguous_readpages());

2) readpages() submits several read bios, all with an end io callback
   that runs extent_io.c:end_bio_extent_readpage() and that is executed
   by other task when a bio finishes, corresponding to a work queue
   (fs_info-&gt;end_io_workers) worker kthread. This callback unlocks
   the ranges in the inode's io_tree that were previously locked in
   step 1;

3) readpages() returns, the reference on the inode is dropped;

4) One or more of the read bios previously submitted are still not
   complete (their end io callback was not yet invoked or has not
   yet finished execution);

5) Inode eviction is triggered (through an unlink call for example).
   The inode reference count was not incremented before submitting
   the read bios, therefore this is possible;

6) The eviction handler starts executing and enters the loop that
   iterates over all extent states in the inode's io_tree;

7) The loop picks one extent state record and uses its -&gt;start and
   -&gt;end fields, after releasing the inode's io_tree spinlock, to
   call lock_extent_bits() and clear_extent_bit(). The call to lock
   the range [state-&gt;start, state-&gt;end] blocks because the whole
   range or a part of it was locked by the previous call to
   readpages() and the corresponding end io callback, which unlocks
   the range was not yet executed;

8) The end io callback for the read bio is executed and unlocks the
   range [state-&gt;start, state-&gt;end] (or a superset of that range).
   And at clear_extent_bit() the extent_state record state is used
   as a second argument to split_state(), which sets state-&gt;start to
   a larger value;

9) The task executing the eviction handler is woken up by the task
   executing the bio's end io callback (through clear_state_bit) and
   the eviction handler locks the range
   [old value for state-&gt;start, state-&gt;end]. Shortly after, when
   calling clear_extent_bit(), it unlocks the range
   [new value for state-&gt;start, state-&gt;end], so it ends up unlocking
   only part of the range that it locked, leaving an extent state
   record in the io_tree that represents the unlocked subrange;

10) The eviction handler loop, in its next iteration, gets the
    extent_state record for the subrange that it did not unlock in the
    previous step and then tries to lock it, resulting in an hang.

So fix this by not using the -&gt;start and -&gt;end fields of an existing
extent_state record. This is a simple solution, and an alternative
could be to bump the inode's reference count before submitting each
read bio and having it dropped in the bio's end io callback. But that
would be a more invasive/complex change and would not protect against
other possible places that are not holding a reference on the inode
as well. Something to consider in the future.

Many thanks to Zygo Blaxell for reporting, in the mailing list, the
issue, a set of scripts to trigger it and testing this fix.

Reported-by: Zygo Blaxell &lt;ce3g8jdj@umail.furryterror.org&gt;
Tested-by: Zygo Blaxell &lt;ce3g8jdj@umail.furryterror.org&gt;
Signed-off-by: Filipe Manana &lt;fdmanana@suse.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>
Zygo Blaxell and other users have reported occasional hangs while an
inode is being evicted, leading to traces like the following:

[ 5281.972322] INFO: task rm:20488 blocked for more than 120 seconds.
[ 5281.973836]       Not tainted 4.0.0-rc5-btrfs-next-9+ #2
[ 5281.974818] "echo 0 &gt; /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 5281.976364] rm              D ffff8800724cfc38     0 20488   7747 0x00000000
[ 5281.977506]  ffff8800724cfc38 ffff8800724cfc38 ffff880065da5c50 0000000000000001
[ 5281.978461]  ffff8800724cffd8 ffff8801540a5f50 0000000000000008 ffff8801540a5f78
[ 5281.979541]  ffff8801540a5f50 ffff8800724cfc58 ffffffff8143107e 0000000000000123
[ 5281.981396] Call Trace:
[ 5281.982066]  [&lt;ffffffff8143107e&gt;] schedule+0x74/0x83
[ 5281.983341]  [&lt;ffffffffa03b33cf&gt;] wait_on_state+0xac/0xcd [btrfs]
[ 5281.985127]  [&lt;ffffffff81075cd6&gt;] ? signal_pending_state+0x31/0x31
[ 5281.986715]  [&lt;ffffffffa03b4b71&gt;] wait_extent_bit.constprop.32+0x7c/0xde [btrfs]
[ 5281.988680]  [&lt;ffffffffa03b540b&gt;] lock_extent_bits+0x5d/0x88 [btrfs]
[ 5281.990200]  [&lt;ffffffffa03a621d&gt;] btrfs_evict_inode+0x24e/0x5be [btrfs]
[ 5281.991781]  [&lt;ffffffff8116964d&gt;] evict+0xa0/0x148
[ 5281.992735]  [&lt;ffffffff8116a43d&gt;] iput+0x18f/0x1e5
[ 5281.993796]  [&lt;ffffffff81160d4a&gt;] do_unlinkat+0x15b/0x1fa
[ 5281.994806]  [&lt;ffffffff81435b54&gt;] ? ret_from_sys_call+0x1d/0x58
[ 5281.996120]  [&lt;ffffffff8107d314&gt;] ? trace_hardirqs_on_caller+0x18f/0x1ab
[ 5281.997562]  [&lt;ffffffff8123960b&gt;] ? trace_hardirqs_on_thunk+0x3a/0x3f
[ 5281.998815]  [&lt;ffffffff81161a16&gt;] SyS_unlinkat+0x29/0x2b
[ 5281.999920]  [&lt;ffffffff81435b32&gt;] system_call_fastpath+0x12/0x17
[ 5282.001299] 1 lock held by rm/20488:
[ 5282.002066]  #0:  (sb_writers#12){.+.+.+}, at: [&lt;ffffffff8116dd81&gt;] mnt_want_write+0x24/0x4b

This happens when we have readahead, which calls readpages(), happening
right before the inode eviction handler is invoked. So the reason is
essentially:

1) readpages() is called while a reference on the inode is held, so
   eviction can not be triggered before readpages() returns. It also
   locks one or more ranges in the inode's io_tree (which is done at
   extent_io.c:__do_contiguous_readpages());

2) readpages() submits several read bios, all with an end io callback
   that runs extent_io.c:end_bio_extent_readpage() and that is executed
   by other task when a bio finishes, corresponding to a work queue
   (fs_info-&gt;end_io_workers) worker kthread. This callback unlocks
   the ranges in the inode's io_tree that were previously locked in
   step 1;

3) readpages() returns, the reference on the inode is dropped;

4) One or more of the read bios previously submitted are still not
   complete (their end io callback was not yet invoked or has not
   yet finished execution);

5) Inode eviction is triggered (through an unlink call for example).
   The inode reference count was not incremented before submitting
   the read bios, therefore this is possible;

6) The eviction handler starts executing and enters the loop that
   iterates over all extent states in the inode's io_tree;

7) The loop picks one extent state record and uses its -&gt;start and
   -&gt;end fields, after releasing the inode's io_tree spinlock, to
   call lock_extent_bits() and clear_extent_bit(). The call to lock
   the range [state-&gt;start, state-&gt;end] blocks because the whole
   range or a part of it was locked by the previous call to
   readpages() and the corresponding end io callback, which unlocks
   the range was not yet executed;

8) The end io callback for the read bio is executed and unlocks the
   range [state-&gt;start, state-&gt;end] (or a superset of that range).
   And at clear_extent_bit() the extent_state record state is used
   as a second argument to split_state(), which sets state-&gt;start to
   a larger value;

9) The task executing the eviction handler is woken up by the task
   executing the bio's end io callback (through clear_state_bit) and
   the eviction handler locks the range
   [old value for state-&gt;start, state-&gt;end]. Shortly after, when
   calling clear_extent_bit(), it unlocks the range
   [new value for state-&gt;start, state-&gt;end], so it ends up unlocking
   only part of the range that it locked, leaving an extent state
   record in the io_tree that represents the unlocked subrange;

10) The eviction handler loop, in its next iteration, gets the
    extent_state record for the subrange that it did not unlock in the
    previous step and then tries to lock it, resulting in an hang.

So fix this by not using the -&gt;start and -&gt;end fields of an existing
extent_state record. This is a simple solution, and an alternative
could be to bump the inode's reference count before submitting each
read bio and having it dropped in the bio's end io callback. But that
would be a more invasive/complex change and would not protect against
other possible places that are not holding a reference on the inode
as well. Something to consider in the future.

Many thanks to Zygo Blaxell for reporting, in the mailing list, the
issue, a set of scripts to trigger it and testing this fix.

Reported-by: Zygo Blaxell &lt;ce3g8jdj@umail.furryterror.org&gt;
Tested-by: Zygo Blaxell &lt;ce3g8jdj@umail.furryterror.org&gt;
Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'for-linus-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs</title>
<updated>2015-05-01T14:46:21+00:00</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2015-05-01T14:46:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=64887b6882de36069c18ef2d9623484d6db7cd3a'/>
<id>64887b6882de36069c18ef2d9623484d6db7cd3a</id>
<content type='text'>
Pull btrfs fixes from Chris Mason:
 "A few more btrfs fixes.

  These range from corners Filipe found in the new free space cache
  writeback to a grab bag of fixes from the list"

* 'for-linus-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  Btrfs: btrfs_release_extent_buffer_page didn't free pages of dummy extent
  Btrfs: fill -&gt;last_trans for delayed inode in btrfs_fill_inode.
  btrfs: unlock i_mutex after attempting to delete subvolume during send
  btrfs: check io_ctl_prepare_pages return in __btrfs_write_out_cache
  btrfs: fix race on ENOMEM in alloc_extent_buffer
  btrfs: handle ENOMEM in btrfs_alloc_tree_block
  Btrfs: fix find_free_dev_extent() malfunction in case device tree has hole
  Btrfs: don't check for delalloc_bytes in cache_save_setup
  Btrfs: fix deadlock when starting writeback of bg caches
  Btrfs: fix race between start dirty bg cache writeout and bg deletion
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Pull btrfs fixes from Chris Mason:
 "A few more btrfs fixes.

  These range from corners Filipe found in the new free space cache
  writeback to a grab bag of fixes from the list"

* 'for-linus-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  Btrfs: btrfs_release_extent_buffer_page didn't free pages of dummy extent
  Btrfs: fill -&gt;last_trans for delayed inode in btrfs_fill_inode.
  btrfs: unlock i_mutex after attempting to delete subvolume during send
  btrfs: check io_ctl_prepare_pages return in __btrfs_write_out_cache
  btrfs: fix race on ENOMEM in alloc_extent_buffer
  btrfs: handle ENOMEM in btrfs_alloc_tree_block
  Btrfs: fix find_free_dev_extent() malfunction in case device tree has hole
  Btrfs: don't check for delalloc_bytes in cache_save_setup
  Btrfs: fix deadlock when starting writeback of bg caches
  Btrfs: fix race between start dirty bg cache writeout and bg deletion
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs</title>
<updated>2015-04-27T00:22:07+00:00</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2015-04-26T22:48:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=9ec3a646fe09970f801ab15e0f1694060b9f19af'/>
<id>9ec3a646fe09970f801ab15e0f1694060b9f19af</id>
<content type='text'>
Pull fourth vfs update from Al Viro:
 "d_inode() annotations from David Howells (sat in for-next since before
  the beginning of merge window) + four assorted fixes"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  RCU pathwalk breakage when running into a symlink overmounting something
  fix I_DIO_WAKEUP definition
  direct-io: only inc/dec inode-&gt;i_dio_count for file systems
  fs/9p: fix readdir()
  VFS: assorted d_backing_inode() annotations
  VFS: fs/inode.c helpers: d_inode() annotations
  VFS: fs/cachefiles: d_backing_inode() annotations
  VFS: fs library helpers: d_inode() annotations
  VFS: assorted weird filesystems: d_inode() annotations
  VFS: normal filesystems (and lustre): d_inode() annotations
  VFS: security/: d_inode() annotations
  VFS: security/: d_backing_inode() annotations
  VFS: net/: d_inode() annotations
  VFS: net/unix: d_backing_inode() annotations
  VFS: kernel/: d_inode() annotations
  VFS: audit: d_backing_inode() annotations
  VFS: Fix up some -&gt;d_inode accesses in the chelsio driver
  VFS: Cachefiles should perform fs modifications on the top layer only
  VFS: AF_UNIX sockets should call mknod on the top layer only
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Pull fourth vfs update from Al Viro:
 "d_inode() annotations from David Howells (sat in for-next since before
  the beginning of merge window) + four assorted fixes"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  RCU pathwalk breakage when running into a symlink overmounting something
  fix I_DIO_WAKEUP definition
  direct-io: only inc/dec inode-&gt;i_dio_count for file systems
  fs/9p: fix readdir()
  VFS: assorted d_backing_inode() annotations
  VFS: fs/inode.c helpers: d_inode() annotations
  VFS: fs/cachefiles: d_backing_inode() annotations
  VFS: fs library helpers: d_inode() annotations
  VFS: assorted weird filesystems: d_inode() annotations
  VFS: normal filesystems (and lustre): d_inode() annotations
  VFS: security/: d_inode() annotations
  VFS: security/: d_backing_inode() annotations
  VFS: net/: d_inode() annotations
  VFS: net/unix: d_backing_inode() annotations
  VFS: kernel/: d_inode() annotations
  VFS: audit: d_backing_inode() annotations
  VFS: Fix up some -&gt;d_inode accesses in the chelsio driver
  VFS: Cachefiles should perform fs modifications on the top layer only
  VFS: AF_UNIX sockets should call mknod on the top layer only
</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fill -&gt;last_trans for delayed inode in btrfs_fill_inode.</title>
<updated>2015-04-26T13:27:03+00:00</updated>
<author>
<name>Yang Dongsheng</name>
<email>yangds.fnst@cn.fujitsu.com</email>
</author>
<published>2015-04-09T04:08:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=6e17d30bfaf43e04d991392d8484f1c556810c33'/>
<id>6e17d30bfaf43e04d991392d8484f1c556810c33</id>
<content type='text'>
We need to fill inode when we found a node for it in delayed_nodes_tree.
But we did not fill the -&gt;last_trans currently, it will cause the test
of xfstest/generic/311 fail. Scenario of the 311 is shown as below:

Problem:
	(1). test_fd = open(fname, O_RDWR|O_DIRECT)
	(2). pwrite(test_fd, buf, 4096, 0)
	(3). close(test_fd)
	(4). drop_all_caches()	&lt;-------- "echo 3 &gt; /proc/sys/vm/drop_caches"
	(5). test_fd = open(fname, O_RDWR|O_DIRECT)
	(6). fsync(test_fd);
				&lt;-------- we did not get the correct log entry for the file
Reason:
	When we re-open this file in (5), we would find a node
in delayed_nodes_tree and fill the inode we are lookup with the
information. But the -&gt;last_trans is not filled, then the fsync()
will check the -&gt;last_trans and found it's 0 then say this inode
is already in our tree which is commited, not recording the extents
for it.

Fix:
	This patch fill the -&gt;last_trans properly and set the
runtime_flags if needed in this situation. Then we can get the
log entries we expected after (6) and generic/311 passed.

Signed-off-by: Dongsheng Yang &lt;yangds.fnst@cn.fujitsu.com&gt;
Reviewed-by: Miao Xie &lt;miaoxie@huawei.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>
We need to fill inode when we found a node for it in delayed_nodes_tree.
But we did not fill the -&gt;last_trans currently, it will cause the test
of xfstest/generic/311 fail. Scenario of the 311 is shown as below:

Problem:
	(1). test_fd = open(fname, O_RDWR|O_DIRECT)
	(2). pwrite(test_fd, buf, 4096, 0)
	(3). close(test_fd)
	(4). drop_all_caches()	&lt;-------- "echo 3 &gt; /proc/sys/vm/drop_caches"
	(5). test_fd = open(fname, O_RDWR|O_DIRECT)
	(6). fsync(test_fd);
				&lt;-------- we did not get the correct log entry for the file
Reason:
	When we re-open this file in (5), we would find a node
in delayed_nodes_tree and fill the inode we are lookup with the
information. But the -&gt;last_trans is not filled, then the fsync()
will check the -&gt;last_trans and found it's 0 then say this inode
is already in our tree which is commited, not recording the extents
for it.

Fix:
	This patch fill the -&gt;last_trans properly and set the
runtime_flags if needed in this situation. Then we can get the
log entries we expected after (6) and generic/311 passed.

Signed-off-by: Dongsheng Yang &lt;yangds.fnst@cn.fujitsu.com&gt;
Reviewed-by: Miao Xie &lt;miaoxie@huawei.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>direct-io: only inc/dec inode-&gt;i_dio_count for file systems</title>
<updated>2015-04-24T19:45:28+00:00</updated>
<author>
<name>Jens Axboe</name>
<email>axboe@fb.com</email>
</author>
<published>2015-04-15T23:05:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=fe0f07d08ee35fb13d2cb048970072fe4f71ad14'/>
<id>fe0f07d08ee35fb13d2cb048970072fe4f71ad14</id>
<content type='text'>
do_blockdev_direct_IO() increments and decrements the inode
-&gt;i_dio_count for each IO operation. It does this to protect against
truncate of a file. Block devices don't need this sort of protection.

For a capable multiqueue setup, this atomic int is the only shared
state between applications accessing the device for O_DIRECT, and it
presents a scaling wall for that. In my testing, as much as 30% of
system time is spent incrementing and decrementing this value. A mixed
read/write workload improved from ~2.5M IOPS to ~9.6M IOPS, with
better latencies too. Before:

clat percentiles (usec):
 |  1.00th=[   33],  5.00th=[   34], 10.00th=[   34], 20.00th=[   34],
 | 30.00th=[   34], 40.00th=[   34], 50.00th=[   35], 60.00th=[   35],
 | 70.00th=[   35], 80.00th=[   35], 90.00th=[   37], 95.00th=[   80],
 | 99.00th=[   98], 99.50th=[  151], 99.90th=[  155], 99.95th=[  155],
 | 99.99th=[  165]

After:

clat percentiles (usec):
 |  1.00th=[   95],  5.00th=[  108], 10.00th=[  129], 20.00th=[  149],
 | 30.00th=[  155], 40.00th=[  161], 50.00th=[  167], 60.00th=[  171],
 | 70.00th=[  177], 80.00th=[  185], 90.00th=[  201], 95.00th=[  270],
 | 99.00th=[  390], 99.50th=[  398], 99.90th=[  418], 99.95th=[  422],
 | 99.99th=[  438]

In other setups, Robert Elliott reported seeing good performance
improvements:

https://lkml.org/lkml/2015/4/3/557

The more applications accessing the device, the worse it gets.

Add a new direct-io flags, DIO_SKIP_DIO_COUNT, which tells
do_blockdev_direct_IO() that it need not worry about incrementing
or decrementing the inode i_dio_count for this caller.

Cc: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Cc: Christoph Hellwig &lt;hch@lst.de&gt;
Cc: Theodore Ts'o &lt;tytso@mit.edu&gt;
Cc: Elliott, Robert (Server Storage) &lt;elliott@hp.com&gt;
Cc: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Jens Axboe &lt;axboe@fb.com&gt;
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
do_blockdev_direct_IO() increments and decrements the inode
-&gt;i_dio_count for each IO operation. It does this to protect against
truncate of a file. Block devices don't need this sort of protection.

For a capable multiqueue setup, this atomic int is the only shared
state between applications accessing the device for O_DIRECT, and it
presents a scaling wall for that. In my testing, as much as 30% of
system time is spent incrementing and decrementing this value. A mixed
read/write workload improved from ~2.5M IOPS to ~9.6M IOPS, with
better latencies too. Before:

clat percentiles (usec):
 |  1.00th=[   33],  5.00th=[   34], 10.00th=[   34], 20.00th=[   34],
 | 30.00th=[   34], 40.00th=[   34], 50.00th=[   35], 60.00th=[   35],
 | 70.00th=[   35], 80.00th=[   35], 90.00th=[   37], 95.00th=[   80],
 | 99.00th=[   98], 99.50th=[  151], 99.90th=[  155], 99.95th=[  155],
 | 99.99th=[  165]

After:

clat percentiles (usec):
 |  1.00th=[   95],  5.00th=[  108], 10.00th=[  129], 20.00th=[  149],
 | 30.00th=[  155], 40.00th=[  161], 50.00th=[  167], 60.00th=[  171],
 | 70.00th=[  177], 80.00th=[  185], 90.00th=[  201], 95.00th=[  270],
 | 99.00th=[  390], 99.50th=[  398], 99.90th=[  418], 99.95th=[  422],
 | 99.99th=[  438]

In other setups, Robert Elliott reported seeing good performance
improvements:

https://lkml.org/lkml/2015/4/3/557

The more applications accessing the device, the worse it gets.

Add a new direct-io flags, DIO_SKIP_DIO_COUNT, which tells
do_blockdev_direct_IO() that it need not worry about incrementing
or decrementing the inode i_dio_count for this caller.

Cc: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Cc: Christoph Hellwig &lt;hch@lst.de&gt;
Cc: Theodore Ts'o &lt;tytso@mit.edu&gt;
Cc: Elliott, Robert (Server Storage) &lt;elliott@hp.com&gt;
Cc: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Jens Axboe &lt;axboe@fb.com&gt;
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
</pre>
</div>
</content>
</entry>
</feed>
