From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Anand Jain <anand.jain@oracle.com>,
Josef Bacik <josef@toxicpanda.com>,
Filipe Manana <fdmanana@suse.com>,
David Sterba <dsterba@suse.com>
Subject: [PATCH 5.10 09/42] btrfs: fix race between swap file activation and snapshot creation
Date: Mon, 8 Mar 2021 13:30:35 +0100 [thread overview]
Message-ID: <20210308122718.589190577@linuxfoundation.org> (raw)
In-Reply-To: <20210308122718.120213856@linuxfoundation.org>
From: Filipe Manana <fdmanana@suse.com>
commit dd0734f2a866f9d619d4abf97c3d71bcdee40ea9 upstream.
When creating a snapshot we check if the current number of swap files, in
the root, is non-zero, and if it is, we error out and warn that we can not
create the snapshot because there are active swap files.
However this is racy because when a task started activation of a swap
file, another task might have started already snapshot creation and might
have seen the counter for the number of swap files as zero. This means
that after the swap file is activated we may end up with a snapshot of the
same root successfully created, and therefore when the first write to the
swap file happens it has to fall back into COW mode, which should never
happen for active swap files.
Basically what can happen is:
1) Task A starts snapshot creation and enters ioctl.c:create_snapshot().
There it sees that root->nr_swapfiles has a value of 0 so it continues;
2) Task B enters btrfs_swap_activate(). It is not aware that another task
started snapshot creation but it did not finish yet. It increments
root->nr_swapfiles from 0 to 1;
3) Task B checks that the file meets all requirements to be an active
swap file - it has NOCOW set, there are no snapshots for the inode's
root at the moment, no file holes, no reflinked extents, etc;
4) Task B returns success and now the file is an active swap file;
5) Task A commits the transaction to create the snapshot and finishes.
The swap file's extents are now shared between the original root and
the snapshot;
6) A write into an extent of the swap file is attempted - there is a
snapshot of the file's root, so we fall back to COW mode and therefore
the physical location of the extent changes on disk.
So fix this by taking the snapshot lock during swap file activation before
locking the extent range, as that is the order in which we lock these
during buffered writes.
Fixes: ed46ff3d42378 ("Btrfs: support swap files")
CC: stable@vger.kernel.org # 5.4+
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/btrfs/inode.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -10099,7 +10099,8 @@ static int btrfs_swap_activate(struct sw
sector_t *span)
{
struct inode *inode = file_inode(file);
- struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info;
+ struct btrfs_root *root = BTRFS_I(inode)->root;
+ struct btrfs_fs_info *fs_info = root->fs_info;
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
struct extent_state *cached_state = NULL;
struct extent_map *em = NULL;
@@ -10150,13 +10151,27 @@ static int btrfs_swap_activate(struct sw
"cannot activate swapfile while exclusive operation is running");
return -EBUSY;
}
+
+ /*
+ * Prevent snapshot creation while we are activating the swap file.
+ * We do not want to race with snapshot creation. If snapshot creation
+ * already started before we bumped nr_swapfiles from 0 to 1 and
+ * completes before the first write into the swap file after it is
+ * activated, than that write would fallback to COW.
+ */
+ if (!btrfs_drew_try_write_lock(&root->snapshot_lock)) {
+ btrfs_exclop_finish(fs_info);
+ btrfs_warn(fs_info,
+ "cannot activate swapfile because snapshot creation is in progress");
+ return -EINVAL;
+ }
/*
* Snapshots can create extents which require COW even if NODATACOW is
* set. We use this counter to prevent snapshots. We must increment it
* before walking the extents because we don't want a concurrent
* snapshot to run after we've already checked the extents.
*/
- atomic_inc(&BTRFS_I(inode)->root->nr_swapfiles);
+ atomic_inc(&root->nr_swapfiles);
isize = ALIGN_DOWN(inode->i_size, fs_info->sectorsize);
@@ -10302,6 +10317,8 @@ out:
if (ret)
btrfs_swap_deactivate(file);
+ btrfs_drew_write_unlock(&root->snapshot_lock);
+
btrfs_exclop_finish(fs_info);
if (ret)
next prev parent reply other threads:[~2021-03-08 12:34 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-08 12:30 [PATCH 5.10 00/42] 5.10.22-rc1 review Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 01/42] ALSA: hda/realtek: Enable headset mic of Acer SWIFT with ALC256 Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 02/42] ALSA: usb-audio: use Corsair Virtuoso mapping for Corsair Virtuoso SE Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 03/42] ALSA: usb-audio: Drop bogus dB range in too low level Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 04/42] tpm, tpm_tis: Decorate tpm_tis_gen_interrupt() with request_locality() Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 05/42] tpm, tpm_tis: Decorate tpm_get_timeouts() " Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 06/42] btrfs: avoid double put of block group when emptying cluster Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 07/42] btrfs: fix raid6 qstripe kmap Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 08/42] btrfs: fix race between writes to swap files and scrub Greg Kroah-Hartman
2021-03-08 12:30 ` Greg Kroah-Hartman [this message]
2021-03-08 12:30 ` [PATCH 5.10 10/42] btrfs: fix stale data exposure after cloning a hole with NO_HOLES enabled Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 11/42] btrfs: fix race between extent freeing/allocation when using bitmaps Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 12/42] btrfs: validate qgroup inherit for SNAP_CREATE_V2 ioctl Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 13/42] btrfs: free correct amount of space in btrfs_delayed_inode_reserve_metadata Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 14/42] btrfs: unlock extents in btrfs_zero_range in case of quota reservation errors Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 15/42] btrfs: fix warning when creating a directory with smack enabled Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 16/42] PM: runtime: Update device status before letting suppliers suspend Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 17/42] ring-buffer: Force before_stamp and write_stamp to be different on discard Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 18/42] io_uring: ignore double poll add on the same waitqueue head Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 19/42] dm bufio: subtract the number of initial sectors in dm_bufio_get_device_size Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 20/42] dm verity: fix FEC for RS roots unaligned to block size Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 21/42] drm/amdgpu:disable VCN for Navi12 SKU Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 22/42] drm/amdgpu: fix parameter error of RREG32_PCIE() in amdgpu_regs_pcie Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 23/42] crypto - shash: reduce minimum alignment of shash_desc structure Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 24/42] arm64: mm: Move reserve_crashkernel() into mem_init() Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 25/42] arm64: mm: Move zone_dma_bits initialization into zone_sizes_init() Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 26/42] of/address: Introduce of_dma_get_max_cpu_address() Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 27/42] of: unittest: Add test for of_dma_get_max_cpu_address() Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 28/42] arm64: mm: Set ZONE_DMA size based on devicetrees dma-ranges Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 29/42] arm64: mm: Set ZONE_DMA size based on early IORT scan Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 30/42] mm: Remove examples from enum zone_type comment Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 31/42] ALSA: ctxfi: cthw20k2: fix mask on conf to allow 4 bits Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 32/42] RDMA/cm: Fix IRQ restore in ib_send_cm_sidr_rep Greg Kroah-Hartman
2021-03-08 12:30 ` [PATCH 5.10 33/42] RDMA/rxe: Fix missing kconfig dependency on CRYPTO Greg Kroah-Hartman
2021-03-08 12:31 ` [PATCH 5.10 34/42] IB/mlx5: Add missing error code Greg Kroah-Hartman
2021-03-08 12:31 ` [PATCH 5.10 35/42] ALSA: hda: intel-nhlt: verify config type Greg Kroah-Hartman
2021-03-08 12:31 ` [PATCH 5.10 36/42] ftrace: Have recordmcount use w8 to read relp->r_info in arm64_is_fake_mcount Greg Kroah-Hartman
2021-03-08 12:31 ` [PATCH 5.10 37/42] rsxx: Return -EFAULT if copy_to_user() fails Greg Kroah-Hartman
2021-03-08 12:31 ` [PATCH 5.10 38/42] iommu/vt-d: Fix status code for Allocate/Free PASID command Greg Kroah-Hartman
2021-03-08 12:31 ` [PATCH 5.10 39/42] Revert "arm64: dts: amlogic: add missing ethernet reset ID" Greg Kroah-Hartman
2021-03-08 12:31 ` [PATCH 5.10 40/42] of: unittest: Fix build on architectures without CONFIG_OF_ADDRESS Greg Kroah-Hartman
2021-03-08 12:31 ` [PATCH 5.10 41/42] tomoyo: recognize kernel threads correctly Greg Kroah-Hartman
2021-03-08 12:31 ` [PATCH 5.10 42/42] r8169: fix resuming from suspend on RTL8105e if machine runs on battery Greg Kroah-Hartman
2021-03-08 17:50 ` [PATCH 5.10 00/42] 5.10.22-rc1 review Florian Fainelli
2021-03-08 20:35 ` Pavel Machek
2021-03-08 22:29 ` Guenter Roeck
2021-03-09 1:08 ` Samuel Zou
2021-03-09 10:27 ` Greg Kroah-Hartman
2021-03-09 10:27 ` Greg Kroah-Hartman
2021-03-09 4:43 ` Naresh Kamboju
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210308122718.589190577@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=anand.jain@oracle.com \
--cc=dsterba@suse.com \
--cc=fdmanana@suse.com \
--cc=josef@toxicpanda.com \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox