]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commit
Btrfs: don't clean dirty pages during buffered writes
authorChris Mason <clm@fb.com>
Wed, 20 Jun 2018 14:56:11 +0000 (07:56 -0700)
committerJuerg Haefliger <juergh@canonical.com>
Wed, 24 Jul 2019 01:58:32 +0000 (19:58 -0600)
commit835e0a9c9b0266aad4bb6261e3307c3e8f6f2773
tree7cc01e5e1496cf2c7e5ae90cc49d61deb44cce9f
parent81e7e768a9b847b60cf66d9bc97a581f82feeeb9
Btrfs: don't clean dirty pages during buffered writes

BugLink: https://bugs.launchpad.net/bugs/1836802
commit 7703bdd8d23e6ef057af3253958a793ec6066b28 upstream.

During buffered writes, we follow this basic series of steps:

again:
lock all the pages
wait for writeback on all the pages
Take the extent range lock
wait for ordered extents on the whole range
clean all the pages

if (copy_from_user_in_atomic() hits a fault) {
drop our locks
goto again;
}

dirty all the pages
release all the locks

The extra waiting, cleaning and locking are there to make sure we don't
modify pages in flight to the drive, after they've been crc'd.

If some of the pages in the range were already dirty when the write
began, and we need to goto again, we create a window where a dirty page
has been cleaned and unlocked.  It may be reclaimed before we're able to
lock it again, which means we'll read the old contents off the drive and
lose any modifications that had been pending writeback.

We don't actually need to clean the pages.  All of the other locking in
place makes sure we don't start IO on the pages, so we can just leave
them dirty for the duration of the write.

Fixes: 73d59314e6ed (the original btrfs merge)
CC: stable@vger.kernel.org # v4.4+
Signed-off-by: Chris Mason <clm@fb.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
fs/btrfs/file.c