No description
Find a file
Filipe Manana ebb929060a Btrfs: avoid fallback to transaction commit during fsync of files with holes
When we are doing a full fsync (bit BTRFS_INODE_NEEDS_FULL_SYNC set) of a
file that has holes and has file extent items spanning two or more leafs,
we can end up falling to back to a full transaction commit due to a logic
bug that leads to failure to insert a duplicate file extent item that is
meant to represent a hole between the last file extent item of a leaf and
the first file extent item in the next leaf. The failure (EEXIST error)
leads to a transaction commit (as most errors when logging an inode do).

For example, we have the two following leafs:

Leaf N:

  -----------------------------------------------
  | ..., ..., ..., (257, FILE_EXTENT_ITEM, 64K) |
  -----------------------------------------------
  The file extent item at the end of leaf N has a length of 4Kb,
  representing the file range from 64K to 68K - 1.

Leaf N + 1:

  -----------------------------------------------
  | (257, FILE_EXTENT_ITEM, 72K), ..., ..., ... |
  -----------------------------------------------
  The file extent item at the first slot of leaf N + 1 has a length of
  4Kb too, representing the file range from 72K to 76K - 1.

During the full fsync path, when we are at tree-log.c:copy_items() with
leaf N as a parameter, after processing the last file extent item, that
represents the extent at offset 64K, we take a look at the first file
extent item at the next leaf (leaf N + 1), and notice there's a 4K hole
between the two extents, and therefore we insert a file extent item
representing that hole, starting at file offset 68K and ending at offset
72K - 1. However we don't update the value of *last_extent, which is used
to represent the end offset (plus 1, non-inclusive end) of the last file
extent item inserted in the log, so it stays with a value of 68K and not
with a value of 72K.

Then, when copy_items() is called for leaf N + 1, because the value of
*last_extent is smaller then the offset of the first extent item in the
leaf (68K < 72K), we look at the last file extent item in the previous
leaf (leaf N) and see it there's a 4K gap between it and our first file
extent item (again, 68K < 72K), so we decide to insert a file extent item
representing the hole, starting at file offset 68K and ending at offset
72K - 1, this insertion will fail with -EEXIST being returned from
btrfs_insert_file_extent() because we already inserted a file extent item
representing a hole for this offset (68K) in the previous call to
copy_items(), when processing leaf N.

The -EEXIST error gets propagated to the fsync callback, btrfs_sync_file(),
which falls back to a full transaction commit.

Fix this by adjusting *last_extent after inserting a hole when we had to
look at the next leaf.

Fixes: 4ee3fad34a ("Btrfs: fix fsync after hole punching when using no-holes feature")
Cc: stable@vger.kernel.org # 4.14+
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2019-05-16 14:31:13 +02:00
arch A small number of ARM fixes 2019-04-28 10:50:57 -07:00
block bfq: update internal depth state when queue depth changes 2019-04-13 19:08:22 -06:00
certs kexec, KEYS: Make use of platform keyring for signature verify 2019-02-04 17:34:07 -05:00
crypto crypto: lrw - Fix atomic sleep when walking skcipher 2019-04-18 22:13:46 +08:00
Documentation mm: do not boost watermarks to avoid fragmentation for the DISCONTIG memory model 2019-04-26 09:18:05 -07:00
drivers 5.1 Third RC pull request 2019-04-28 10:00:45 -07:00
fs Btrfs: avoid fallback to transaction commit during fsync of files with holes 2019-05-16 14:31:13 +02:00
include btrfs: trace: Introduce trace events for all btrfs tree locking events 2019-04-29 19:02:43 +02:00
init init: initialize jump labels before command line option parsing 2019-04-19 09:46:05 -07:00
ipc Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2019-03-12 14:08:19 -07:00
kernel Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2019-04-27 10:18:40 -07:00
lib lib/test_vmalloc.c: do not create cpumask_t variable on stack 2019-04-26 09:18:05 -07:00
LICENSES LICENSES: Add GCC runtime library exception text 2019-01-16 14:54:15 -07:00
mm mm/page_alloc.c: fix never set ALLOC_NOFRAGMENT flag 2019-04-26 09:18:05 -07:00
net Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2019-04-24 16:18:59 -07:00
samples Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2019-03-11 08:54:01 -07:00
scripts locking/atomics: Don't assume that scripts are executable 2019-04-19 14:21:43 +02:00
security Merge branch 'for-5.1-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup 2019-04-19 18:03:55 -07:00
sound ALSA: hda/realtek - add two more pin configuration sets to quirk table 2019-04-17 10:41:38 +02:00
tools Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2019-04-24 16:18:59 -07:00
usr user/Makefile: Fix typo and capitalization in comment section 2018-12-11 00:18:03 +09:00
virt KVM: fix spectrev1 gadgets 2019-04-16 15:38:07 +02:00
.clang-format clang-format: Update with the latest for_each macro list 2019-04-12 12:49:54 +02:00
.cocciconfig
.get_maintainer.ignore
.gitattributes .gitattributes: set git diff driver for C source code files 2016-10-07 18:46:30 -07:00
.gitignore kbuild: Add support for DT binding schema checks 2018-12-13 09:41:32 -06:00
.mailmap Update Nicolas Pitre's email address 2019-04-02 18:12:44 -10:00
COPYING COPYING: use the new text with points to the license files 2018-03-23 12:41:45 -06:00
CREDITS Char/Misc driver patches for 5.1-rc1 2019-03-06 14:18:59 -08:00
Kbuild Kbuild updates for v5.1 2019-03-10 17:48:21 -07:00
Kconfig kconfig: move the "Executable file formats" menu to fs/Kconfig.binfmt 2018-08-02 08:06:55 +09:00
MAINTAINERS LED update for 5.1-rc7. 2019-04-24 16:15:38 -07:00
Makefile Linux 5.1-rc7 2019-04-28 17:04:13 -07:00
README Drop all 00-INDEX files from Documentation/ 2018-09-09 15:08:58 -06:00

Linux kernel
============

There are several guides for kernel developers and users. These guides can
be rendered in a number of formats, like HTML and PDF. Please read
Documentation/admin-guide/README.rst first.

In order to build the documentation, use ``make htmldocs`` or
``make pdfdocs``.  The formatted documentation can also be read online at:

    https://www.kernel.org/doc/html/latest/

There are various text files in the Documentation/ subdirectory,
several of them using the Restructured Text markup notation.

Please read the Documentation/process/changes.rst file, as it contains the
requirements for building and running the kernel, and information about
the problems which may result by upgrading your kernel.