From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B84C915E8B; Mon, 30 Dec 2024 15:58:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735574316; cv=none; b=CJ70c3kN3H8ekhC3X4Z2jLGlu/fucd3PBIl8URhcJ6b/xBUFAxQgBx9q2iQP94pHlxG0DdUWM3Y4wRaTgZv23grCo6414a/lJnBR5U0ej5T9jjuEjFrTCGf0iSSTSExRhDj2gx5s1WVah/2uiyT868chrwpxs3R75eYUtu7TqwI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735574316; c=relaxed/simple; bh=brmaUkivyv+8jOgzCC4bDDovv4vj2hvhg5Is+ZYoerg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tEtXrfWrZhKMecZ3+1t88IaJqkFwrn9nIfTL9nLh8h1GRkYACwDa5z6F8vKPkwQtTdSwVEQiTj/vOPqxhiNnBb1+aouegxGJpuKDJ9x3CF4JcAEzFrk0GjYCj9bzphnRUEMc1w6coYn5KbVjJ1PfzIhCXCUhtgCZxxqIxkzKCqQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=sOHiK+eC; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="sOHiK+eC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 396D2C4CED0; Mon, 30 Dec 2024 15:58:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1735574316; bh=brmaUkivyv+8jOgzCC4bDDovv4vj2hvhg5Is+ZYoerg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sOHiK+eC7LJ9akmJhldFhwwyJVdug1M49FWkWVUjDqA4Lg8jDj1emuxCpd4icjWX9 Dj7oHIvCBdRudDGJocAe3mgYIYFrmG/fix1sRiRFrDeamqiTj1UfzJgT3jS+v7oFJ4 vbNtTKqIla4tM//1Nh/c3/G6Brg68jGNKKFoeNwU= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Qu Wenruo , Filipe Manana , David Sterba Subject: [PATCH 6.12 101/114] btrfs: fix race with memory mapped writes when activating swap file Date: Mon, 30 Dec 2024 16:43:38 +0100 Message-ID: <20241230154222.006242065@linuxfoundation.org> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20241230154218.044787220@linuxfoundation.org> References: <20241230154218.044787220@linuxfoundation.org> User-Agent: quilt/0.68 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Filipe Manana commit 0525064bb82e50d59543b62b9d41a606198a4a44 upstream. When activating the swap file we flush all delalloc and wait for ordered extent completion, so that we don't miss any delalloc and extents before we check that the file's extent layout is usable for a swap file and activate the swap file. We are called with the inode's VFS lock acquired, so we won't race with buffered and direct IO writes, however we can still race with memory mapped writes since they don't acquire the inode's VFS lock. The race window is between flushing all delalloc and locking the whole file's extent range, since memory mapped writes lock an extent range with the length of a page. Fix this by acquiring the inode's mmap lock before we flush delalloc. CC: stable@vger.kernel.org # 5.4+ Reviewed-by: Qu Wenruo Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/inode.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -9791,28 +9791,40 @@ static int btrfs_swap_activate(struct sw u64 start; /* + * Acquire the inode's mmap lock to prevent races with memory mapped + * writes, as they could happen after we flush delalloc below and before + * we lock the extent range further below. The inode was already locked + * up in the call chain. + */ + btrfs_assert_inode_locked(BTRFS_I(inode)); + down_write(&BTRFS_I(inode)->i_mmap_lock); + + /* * If the swap file was just created, make sure delalloc is done. If the * file changes again after this, the user is doing something stupid and * we don't really care. */ ret = btrfs_wait_ordered_range(BTRFS_I(inode), 0, (u64)-1); if (ret) - return ret; + goto out_unlock_mmap; /* * The inode is locked, so these flags won't change after we check them. */ if (BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS) { btrfs_warn(fs_info, "swapfile must not be compressed"); - return -EINVAL; + ret = -EINVAL; + goto out_unlock_mmap; } if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW)) { btrfs_warn(fs_info, "swapfile must not be copy-on-write"); - return -EINVAL; + ret = -EINVAL; + goto out_unlock_mmap; } if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) { btrfs_warn(fs_info, "swapfile must not be checksummed"); - return -EINVAL; + ret = -EINVAL; + goto out_unlock_mmap; } /* @@ -9827,7 +9839,8 @@ static int btrfs_swap_activate(struct sw if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_SWAP_ACTIVATE)) { btrfs_warn(fs_info, "cannot activate swapfile while exclusive operation is running"); - return -EBUSY; + ret = -EBUSY; + goto out_unlock_mmap; } /* @@ -9841,7 +9854,8 @@ static int btrfs_swap_activate(struct sw btrfs_exclop_finish(fs_info); btrfs_warn(fs_info, "cannot activate swapfile because snapshot creation is in progress"); - return -EINVAL; + ret = -EINVAL; + goto out_unlock_mmap; } /* * Snapshots can create extents which require COW even if NODATACOW is @@ -9862,7 +9876,8 @@ static int btrfs_swap_activate(struct sw btrfs_warn(fs_info, "cannot activate swapfile because subvolume %llu is being deleted", btrfs_root_id(root)); - return -EPERM; + ret = -EPERM; + goto out_unlock_mmap; } atomic_inc(&root->nr_swapfiles); spin_unlock(&root->root_item_lock); @@ -10017,6 +10032,8 @@ out: btrfs_exclop_finish(fs_info); +out_unlock_mmap: + up_write(&BTRFS_I(inode)->i_mmap_lock); if (ret) return ret;