From nobody Sun Nov 24 11:52:13 2024 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 546921CC887; Wed, 6 Nov 2024 02:09:45 +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=1730858985; cv=none; b=HlXibSL0qTWao268hMR9+0Ddrh/Y+geDkKGaYc38H8Xq6oM38LBpHf1EbXbayAeXgp6XuUnblAHIl1rUxi6rsKLUdX7v1IpJFX8dBBx5I1jxRxkdTtltvbFAJn4q8FM+2DglLGhJD0QpxGbQdNTvznhkdXsIeaGZIaACSDzuorc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730858985; c=relaxed/simple; bh=UYVVTwzIzZVes1NNOPT6nwoHhvCAcSGlPc0j0APmPZE=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=jMbs/v5eNFSZfGuNXYR6mxW1ixOb8Wv5khcvD1fM5/AmeEk3cQqwZzA0nBYA8D+Y7Q8Nw6Q5mwgnFlrjK5jZGWZOejj/giSvaN7uc7pG5V1bB6xMyudsw4Y7R7SThp89tBSiESUYzwxuSx6V+2pJJV/zyguhjwkH+BA+zi/3amA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=feB1JIKm; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="feB1JIKm" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F16D6C4CECF; Wed, 6 Nov 2024 02:09:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1730858984; bh=UYVVTwzIzZVes1NNOPT6nwoHhvCAcSGlPc0j0APmPZE=; h=From:To:Cc:Subject:Date:From; b=feB1JIKmQDOrU7vXrAnP/z2DBrHvhlpbpd0vw9D60WH56i//lg8ZzmRSIvkhVpzSp s8KBeYHNR2PvCq33Vd1idBBuU8wKmXDAg43ebQ/V22YsxO6DarRBUndW5O4iRWN44N uVbpu7mitsuWVfQ9ZayuUqJHgxxJWHbY7qCO7H8mYsd6hfNSY3WOmQIL3uE74JcczN NYAcA0r0Oe5z5eVM7N2Rg5Hb+wWPvXwr0+1uEbfoKJRWuwJvTbyZCK2fCVPz8RV8By xIwRBv23YtFt21BPN7h/HpxH5JdcJWRU918mnXfDURd+D8qkSmdE/mXQlltXdzuJl5 gh0wykJXkzs2Q== From: Sasha Levin To: stable@vger.kernel.org, fdmanana@suse.com Cc: Qu Wenruo , David Sterba , linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org Subject: FAILED: Patch "btrfs: fix defrag not merging contiguous extents due to merged extent maps" failed to apply to v6.6-stable tree Date: Tue, 5 Nov 2024 21:09:41 -0500 Message-ID: <20241106020942.170673-1-sashal@kernel.org> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Hint: ignore X-stable: review Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The patch below does not apply to the v6.6-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to . Thanks, Sasha Reviewed-by: Qu Wenruo ------------------ original commit in Linus's tree ------------------ From 77b0d113eec49a7390ff1a08ca1923e89f5f86c6 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Tue, 29 Oct 2024 15:18:45 +0000 Subject: [PATCH] btrfs: fix defrag not merging contiguous extents due to merged extent maps When running defrag (manual defrag) against a file that has extents that are contiguous and we already have the respective extent maps loaded and merged, we end up not defragging the range covered by those contiguous extents. This happens when we have an extent map that was the result of merging multiple extent maps for contiguous extents and the length of the merged extent map is greater than or equals to the defrag threshold length. The script below reproduces this scenario: $ cat test.sh #!/bin/bash DEV=3D/dev/sdi MNT=3D/mnt/sdi mkfs.btrfs -f $DEV mount $DEV $MNT # Create a 256K file with 4 extents of 64K each. xfs_io -f -c "falloc 0 64K" \ -c "pwrite 0 64K" \ -c "falloc 64K 64K" \ -c "pwrite 64K 64K" \ -c "falloc 128K 64K" \ -c "pwrite 128K 64K" \ -c "falloc 192K 64K" \ -c "pwrite 192K 64K" \ $MNT/foo umount $MNT echo -n "Initial number of file extent items: " btrfs inspect-internal dump-tree -t 5 $DEV | grep EXTENT_DATA | wc -l mount $DEV $MNT # Read the whole file in order to load and merge extent maps. cat $MNT/foo > /dev/null btrfs filesystem defragment -t 128K $MNT/foo umount $MNT echo -n "Number of file extent items after defrag with 128K threshold: " btrfs inspect-internal dump-tree -t 5 $DEV | grep EXTENT_DATA | wc -l mount $DEV $MNT # Read the whole file in order to load and merge extent maps. cat $MNT/foo > /dev/null btrfs filesystem defragment -t 256K $MNT/foo umount $MNT echo -n "Number of file extent items after defrag with 256K threshold: " btrfs inspect-internal dump-tree -t 5 $DEV | grep EXTENT_DATA | wc -l Running it: $ ./test.sh Initial number of file extent items: 4 Number of file extent items after defrag with 128K threshold: 4 Number of file extent items after defrag with 256K threshold: 4 The 4 extents don't get merged because we have an extent map with a size of 256K that is the result of merging the individual extent maps for each of the four 64K extents and at defrag_lookup_extent() we have a value of zero for the generation threshold ('newer_than' argument) since this is a manual defrag. As a consequence we don't call defrag_get_extent() to get an extent map representing a single file extent item in the inode's subvolume tree, so we end up using the merged extent map at defrag_collect_targets() and decide not to defrag. Fix this by updating defrag_lookup_extent() to always discard extent maps that were merged and call defrag_get_extent() regardless of the minimum generation threshold ('newer_than' argument). A test case for fstests will be sent along soon. CC: stable@vger.kernel.org # 6.1+ Fixes: 199257a78bb0 ("btrfs: defrag: don't use merged extent map for their = generation check") Reviewed-by: Qu Wenruo Signed-off-by: Filipe Manana Signed-off-by: David Sterba --- fs/btrfs/defrag.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c index b95ef44c326bd..968dae9539482 100644 --- a/fs/btrfs/defrag.c +++ b/fs/btrfs/defrag.c @@ -763,12 +763,12 @@ static struct extent_map *defrag_lookup_extent(struct= inode *inode, u64 start, * We can get a merged extent, in that case, we need to re-search * tree to get the original em for defrag. * - * If @newer_than is 0 or em::generation < newer_than, we can trust - * this em, as either we don't care about the generation, or the - * merged extent map will be rejected anyway. + * This is because even if we have adjacent extents that are contiguous + * and compatible (same type and flags), we still want to defrag them + * so that we use less metadata (extent items in the extent tree and + * file extent items in the inode's subvolume tree). */ - if (em && (em->flags & EXTENT_FLAG_MERGED) && - newer_than && em->generation >=3D newer_than) { + if (em && (em->flags & EXTENT_FLAG_MERGED)) { free_extent_map(em); em =3D NULL; } --=20 2.43.0