From patchwork Tue Apr 16 13:08:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13631799 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 D360E12C46F for ; Tue, 16 Apr 2024 13:08:16 +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=1713272896; cv=none; b=K1uVGsKcJKUicGblIvfGK1JIhQQTLJG2KF0PUNv84I7H7JA6mJnBaG9mhtMsIR7v370/JmClM7kY6or44dn8l1iMIQxVa4GfljaJnZObzmgxEYnmCN8T6V7rdHL40LD+EH1Ef23ZVshMGg5hmYc8BVUtxZciv14sK/ij1zGOqX0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713272896; c=relaxed/simple; bh=8HfSaAjT/yeLH+ayO4nZ8dl13t3iIuN/O+BrjmMmnAo=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=FvPCyzKjWyrzl/sdVZz0K3JDqFEYEHkKAIoFjwxY5A4ydCZa1E6fr6ZLWkkqvVaocxBMCiDMpmgUPKWvgzYE+atY3MxEa45TkAKz3FIyweVf3R2Vx+NYuiL5mdaINL01OpMQDSBaWG20dnH2NG5SP9lPdiJXVriJRy0+jKheQ2k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bLrKwERt; 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="bLrKwERt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E2FB3C32783 for ; Tue, 16 Apr 2024 13:08:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713272896; bh=8HfSaAjT/yeLH+ayO4nZ8dl13t3iIuN/O+BrjmMmnAo=; h=From:To:Subject:Date:In-Reply-To:References:From; b=bLrKwERtcKFXxJiUqrrrwtAVEe8io+HWDFTWE4tHHhvX0sWBdoW//4hTIH74JCDsR Sto3RQhm1ecujHpGiDd5VGELT8DqQf7B24UxSFHsAHehV4bsJDDnExFKJ0UgLnQZCp +4/0dCp+UFMa3GzKcAd2ldt/OAz5eFevUDdexTQfK1hi8zjJ5xqEL4tmkvVTUE/gUh sDcF07haWcpjBMBmnn9KHJKRx9QS94c9l2qVbjCU5yP6nPGVhxPaAZptsOYbuwElxp MFjuZEz1JB+YKxkpo6ONvMdS8Jr9uTMD/AeTu1Qz4n2vSGezd4k+X3S4NcQcRnzrz4 lqXlhWzxdmdVg== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v3 01/10] btrfs: pass the extent map tree's inode to add_extent_mapping() Date: Tue, 16 Apr 2024 14:08:03 +0100 Message-Id: <2230af95994821e09505d0c1a9b65e93a70383f2.1713267925.git.fdmanana@suse.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-btrfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Filipe Manana Extent maps are always added to an inode's extent map tree, so there's no need to pass the extent map tree explicitly to add_extent_mapping(). In order to facilitate an upcoming change that adds a shrinker for extent maps, change add_extent_mapping() to receive the inode instead of its extent map tree. Reviewed-by: Qu Wenruo Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Reviewed-by: Johannes Thumshirn --- fs/btrfs/extent_map.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index d125d5ab9b1d..d0e0c4e5415e 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -355,21 +355,22 @@ static inline void setup_extent_mapping(struct extent_map_tree *tree, } /* - * Add new extent map to the extent tree + * Add a new extent map to an inode's extent map tree. * - * @tree: tree to insert new map in + * @inode: the target inode * @em: map to insert * @modified: indicate whether the given @em should be added to the * modified list, which indicates the extent needs to be logged * - * Insert @em into @tree or perform a simple forward/backward merge with - * existing mappings. The extent_map struct passed in will be inserted - * into the tree directly, with an additional reference taken, or a - * reference dropped if the merge attempt was successful. + * Insert @em into the @inode's extent map tree or perform a simple + * forward/backward merge with existing mappings. The extent_map struct passed + * in will be inserted into the tree directly, with an additional reference + * taken, or a reference dropped if the merge attempt was successful. */ -static int add_extent_mapping(struct extent_map_tree *tree, +static int add_extent_mapping(struct btrfs_inode *inode, struct extent_map *em, int modified) { + struct extent_map_tree *tree = &inode->extent_tree; int ret; lockdep_assert_held_write(&tree->lock); @@ -508,7 +509,7 @@ static struct extent_map *prev_extent_map(struct extent_map *em) * and an extent that you want to insert, deal with overlap and insert * the best fitted new extent into the tree. */ -static noinline int merge_extent_mapping(struct extent_map_tree *em_tree, +static noinline int merge_extent_mapping(struct btrfs_inode *inode, struct extent_map *existing, struct extent_map *em, u64 map_start) @@ -542,7 +543,7 @@ static noinline int merge_extent_mapping(struct extent_map_tree *em_tree, em->block_start += start_diff; em->block_len = em->len; } - return add_extent_mapping(em_tree, em, 0); + return add_extent_mapping(inode, em, 0); } /* @@ -570,7 +571,6 @@ int btrfs_add_extent_mapping(struct btrfs_inode *inode, { int ret; struct extent_map *em = *em_in; - struct extent_map_tree *em_tree = &inode->extent_tree; struct btrfs_fs_info *fs_info = inode->root->fs_info; /* @@ -580,7 +580,7 @@ int btrfs_add_extent_mapping(struct btrfs_inode *inode, if (em->block_start == EXTENT_MAP_INLINE) ASSERT(em->start == 0); - ret = add_extent_mapping(em_tree, em, 0); + ret = add_extent_mapping(inode, em, 0); /* it is possible that someone inserted the extent into the tree * while we had the lock dropped. It is also possible that * an overlapping map exists in the tree @@ -588,7 +588,7 @@ int btrfs_add_extent_mapping(struct btrfs_inode *inode, if (ret == -EEXIST) { struct extent_map *existing; - existing = search_extent_mapping(em_tree, start, len); + existing = search_extent_mapping(&inode->extent_tree, start, len); trace_btrfs_handle_em_exist(fs_info, existing, em, start, len); @@ -609,8 +609,7 @@ int btrfs_add_extent_mapping(struct btrfs_inode *inode, * The existing extent map is the one nearest to * the [start, start + len) range which overlaps */ - ret = merge_extent_mapping(em_tree, existing, - em, start); + ret = merge_extent_mapping(inode, existing, em, start); if (WARN_ON(ret)) { free_extent_map(em); *em_in = NULL; @@ -818,8 +817,7 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end, } else { int ret; - ret = add_extent_mapping(em_tree, split, - modified); + ret = add_extent_mapping(inode, split, modified); /* Logic error, shouldn't happen. */ ASSERT(ret == 0); if (WARN_ON(ret != 0) && modified) @@ -909,7 +907,7 @@ int btrfs_replace_extent_map_range(struct btrfs_inode *inode, do { btrfs_drop_extent_map_range(inode, new_em->start, end, false); write_lock(&tree->lock); - ret = add_extent_mapping(tree, new_em, modified); + ret = add_extent_mapping(inode, new_em, modified); write_unlock(&tree->lock); } while (ret == -EEXIST); @@ -990,7 +988,7 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre, split_mid->ram_bytes = split_mid->len; split_mid->flags = flags; split_mid->generation = em->generation; - add_extent_mapping(em_tree, split_mid, 1); + add_extent_mapping(inode, split_mid, 1); /* Once for us */ free_extent_map(em); From patchwork Tue Apr 16 13:08:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13631800 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 D7F7012BF2B for ; Tue, 16 Apr 2024 13:08:17 +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=1713272897; cv=none; b=IiqaxgmkIcDpvoMCbAphFBH3WpQ08f+OiZmBVoBLvZRw5ewEDT+sCG/sjOdqP3l1l8qgMG5dmZUmpP3ZWJpWptOOWuAjIOcli/YCkNobZJpllB2B4pfQlU/hPxj9/ifPFkfwGlJOMR8Io2qzGZtkfs+xQR4uPBdSmY3NJvrdGqs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713272897; c=relaxed/simple; bh=Znm6NR+viNsZTmYHkFKTvw+dF9PnpQb/xzVRjKDeds4=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=eqT3nc4TWNbzfRfKeAyQXOzGz0fNTIpx60TdGYUgXqXf9CeQQy+JsX0TmZS2KEismDnf0Yx15hf9C3eyhetry0zVAFnzifchkTwkDhwOpDV7kxcyReuflAK1EJrOEXoJ6jrXurRnb+VjLGo4jgVOi2YCgLJ2R8OlTgLhL0lSAqQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YDoiplLZ; 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="YDoiplLZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DD375C2BD11 for ; Tue, 16 Apr 2024 13:08:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713272897; bh=Znm6NR+viNsZTmYHkFKTvw+dF9PnpQb/xzVRjKDeds4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=YDoiplLZohN08GF0g+6lvAlKs5TKfLD2Q64zEHTgt+eWe0Bb7EhadlyN/HVrV852c tpRI84nkp+hJYiLoRVPs6fkLosmcSTxp+MQWt+n4+zPs4GkUuHE2AcEOcTjg32Ft6c 0wNKiNoyKU53PiDGIoi/vhgG08clfLS8gdOtwHVpmvz3mUhqKCzY5eAa2Vk4HdrMGN fx4DdYCF5iXkxXSLuJcM4ySjOlhKMOaQ4a3X4poUKt09C4FYeH8ziuL4juZuymjMo3 681M8ULVtkmB8ApQ7dAzWtwtc4pbuUaFptfQxCImeOk13G2tNPLyotdvAKiqbsANyI 8HmL+iHAJXV4Q== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v3 02/10] btrfs: pass the extent map tree's inode to clear_em_logging() Date: Tue, 16 Apr 2024 14:08:04 +0100 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-btrfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Filipe Manana Extent maps are always associated to an inode's extent map tree, so there's no need to pass the extent map tree explicitly to clear_em_logging(). In order to facilitate an upcoming change that adds a shrinker for extent maps, change clear_em_logging() to receive the inode instead of its extent map tree. Reviewed-by: Qu Wenruo Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Reviewed-by: Johannes Thumshirn --- fs/btrfs/extent_map.c | 4 +++- fs/btrfs/extent_map.h | 2 +- fs/btrfs/tree-log.c | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index d0e0c4e5415e..7cda78d11d75 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -331,8 +331,10 @@ int unpin_extent_cache(struct btrfs_inode *inode, u64 start, u64 len, u64 gen) } -void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em) +void clear_em_logging(struct btrfs_inode *inode, struct extent_map *em) { + struct extent_map_tree *tree = &inode->extent_tree; + lockdep_assert_held_write(&tree->lock); em->flags &= ~EXTENT_FLAG_LOGGING; diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index f287ab46e368..732fc8d7e534 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h @@ -129,7 +129,7 @@ void free_extent_map(struct extent_map *em); int __init extent_map_init(void); void __cold extent_map_exit(void); int unpin_extent_cache(struct btrfs_inode *inode, u64 start, u64 len, u64 gen); -void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em); +void clear_em_logging(struct btrfs_inode *inode, struct extent_map *em); struct extent_map *search_extent_mapping(struct extent_map_tree *tree, u64 start, u64 len); int btrfs_add_extent_mapping(struct btrfs_inode *inode, diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 1c7efb7c2160..765fbbe3ee30 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -4949,7 +4949,7 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, * private list. */ if (ret) { - clear_em_logging(tree, em); + clear_em_logging(inode, em); free_extent_map(em); continue; } @@ -4958,7 +4958,7 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, ret = log_one_extent(trans, inode, em, path, ctx); write_lock(&tree->lock); - clear_em_logging(tree, em); + clear_em_logging(inode, em); free_extent_map(em); } WARN_ON(!list_empty(&extents)); From patchwork Tue Apr 16 13:08:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13631801 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 D7F3612C485 for ; Tue, 16 Apr 2024 13:08:18 +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=1713272898; cv=none; b=J7n5DuFa4koOdAPr7LLIkV3pMz7mth3UP88fk1VldGlG/jiazs1PwO7EPmXc6Nh+f+qPACxM9cagbheeEaECs92u5aXXwBuVP3U9/nymvUlKr7Bm5lAZRgbJXdFLGhiZiDlkWVCfaSjqAMYpaSnw8gzYwn++Z/wrjhLfNwZeH0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713272898; c=relaxed/simple; bh=D7WN/Nan/6C4UwT+O/48hCiAs3x475ZLUVYGG3graho=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Suo5hQBTXDZX02GDI1XYc6CpGV+lxssxvuQuGff4b/tH0SMrm/lmyYcIEHtFpI8zV8Zx3MrqzSDjHGJCOD0l/LVoMl5nM7+9008deZlJYhWq5gPDA9kYsxxwrpVrls5DpQtwjWJxktb+deNkkLiroekjU4BDsACB/jDE5ALJI8k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=e6HkFSmQ; 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="e6HkFSmQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D84D3C113CE for ; Tue, 16 Apr 2024 13:08:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713272898; bh=D7WN/Nan/6C4UwT+O/48hCiAs3x475ZLUVYGG3graho=; h=From:To:Subject:Date:In-Reply-To:References:From; b=e6HkFSmQmlsycnBusshu8/VqaJRax5i/9ZObcr6OwFCZX1hxZ9RWMM44P5wD8G+ar gpGtb0EX2m+op5M2fvvZaRV7NCd3FASK9p21JbaeUibbp37udaSRa1S37yx7ag1oOl SBMhq+DC3JOYdp7l94PFFe9ShCYQkC9g+ossjh9Bj2hKCiJC+9UHMgTWMdYeAyRQLD 7BR36SrJN/iJZsKcFdHZfRwXfr77t48WBsvzWhgQCClc7epwXTWVTmsIXjXPc/FBXT yXKRBaFXKvwUrzUJA1SCEg81ZHRCwweu0LWB3EQ0HNoFjO4pcBsJL/V5T6dtU/b7eX 0yZpJKipxn3pQ== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v3 03/10] btrfs: pass the extent map tree's inode to remove_extent_mapping() Date: Tue, 16 Apr 2024 14:08:05 +0100 Message-Id: <10d9942cd5349cf6be9f31dbc9a447467df9edf9.1713267925.git.fdmanana@suse.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-btrfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Filipe Manana Extent maps are always associated to an inode's extent map tree, so there's no need to pass the extent map tree explicitly to remove_extent_mapping(). In order to facilitate an upcoming change that adds a shrinker for extent maps, change remove_extent_mapping() to receive the inode instead of its extent map tree. Reviewed-by: Qu Wenruo Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Reviewed-by: Johannes Thumshirn --- fs/btrfs/extent_io.c | 2 +- fs/btrfs/extent_map.c | 22 +++++++++++++--------- fs/btrfs/extent_map.h | 2 +- fs/btrfs/tests/extent-map-tests.c | 19 ++++++++++--------- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 91122817f137..7b10f47d8f83 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -2457,7 +2457,7 @@ int try_release_extent_mapping(struct page *page, gfp_t mask) * hurts the fsync performance for workloads with a data * size that exceeds or is close to the system's memory). */ - remove_extent_mapping(map, em); + remove_extent_mapping(btrfs_inode, em); /* once for the rb tree */ free_extent_map(em); next: diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 7cda78d11d75..289669763965 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -449,16 +449,18 @@ struct extent_map *search_extent_mapping(struct extent_map_tree *tree, } /* - * Remove an extent_map from the extent tree. + * Remove an extent_map from its inode's extent tree. * - * @tree: extent tree to remove from + * @inode: the inode the extent map belongs to * @em: extent map being removed * - * Remove @em from @tree. No reference counts are dropped, and no checks - * are done to see if the range is in use. + * Remove @em from the extent tree of @inode. No reference counts are dropped, + * and no checks are done to see if the range is in use. */ -void remove_extent_mapping(struct extent_map_tree *tree, struct extent_map *em) +void remove_extent_mapping(struct btrfs_inode *inode, struct extent_map *em) { + struct extent_map_tree *tree = &inode->extent_tree; + lockdep_assert_held_write(&tree->lock); WARN_ON(em->flags & EXTENT_FLAG_PINNED); @@ -633,8 +635,10 @@ int btrfs_add_extent_mapping(struct btrfs_inode *inode, * if needed. This avoids searching the tree, from the root down to the first * extent map, before each deletion. */ -static void drop_all_extent_maps_fast(struct extent_map_tree *tree) +static void drop_all_extent_maps_fast(struct btrfs_inode *inode) { + struct extent_map_tree *tree = &inode->extent_tree; + write_lock(&tree->lock); while (!RB_EMPTY_ROOT(&tree->map.rb_root)) { struct extent_map *em; @@ -643,7 +647,7 @@ static void drop_all_extent_maps_fast(struct extent_map_tree *tree) node = rb_first_cached(&tree->map); em = rb_entry(node, struct extent_map, rb_node); em->flags &= ~(EXTENT_FLAG_PINNED | EXTENT_FLAG_LOGGING); - remove_extent_mapping(tree, em); + remove_extent_mapping(inode, em); free_extent_map(em); cond_resched_rwlock_write(&tree->lock); } @@ -676,7 +680,7 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end, WARN_ON(end < start); if (end == (u64)-1) { if (start == 0 && !skip_pinned) { - drop_all_extent_maps_fast(em_tree); + drop_all_extent_maps_fast(inode); return; } len = (u64)-1; @@ -854,7 +858,7 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end, ASSERT(!split); btrfs_set_inode_full_sync(inode); } - remove_extent_mapping(em_tree, em); + remove_extent_mapping(inode, em); } /* diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index 732fc8d7e534..c3707461ff62 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h @@ -120,7 +120,7 @@ static inline u64 extent_map_end(const struct extent_map *em) void extent_map_tree_init(struct extent_map_tree *tree); struct extent_map *lookup_extent_mapping(struct extent_map_tree *tree, u64 start, u64 len); -void remove_extent_mapping(struct extent_map_tree *tree, struct extent_map *em); +void remove_extent_mapping(struct btrfs_inode *inode, struct extent_map *em); int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre, u64 new_logical); diff --git a/fs/btrfs/tests/extent-map-tests.c b/fs/btrfs/tests/extent-map-tests.c index 9e9cb591c0f1..db6fb1a2c78f 100644 --- a/fs/btrfs/tests/extent-map-tests.c +++ b/fs/btrfs/tests/extent-map-tests.c @@ -11,8 +11,9 @@ #include "../disk-io.h" #include "../block-group.h" -static int free_extent_map_tree(struct extent_map_tree *em_tree) +static int free_extent_map_tree(struct btrfs_inode *inode) { + struct extent_map_tree *em_tree = &inode->extent_tree; struct extent_map *em; struct rb_node *node; int ret = 0; @@ -21,7 +22,7 @@ static int free_extent_map_tree(struct extent_map_tree *em_tree) while (!RB_EMPTY_ROOT(&em_tree->map.rb_root)) { node = rb_first_cached(&em_tree->map); em = rb_entry(node, struct extent_map, rb_node); - remove_extent_mapping(em_tree, em); + remove_extent_mapping(inode, em); #ifdef CONFIG_BTRFS_DEBUG if (refcount_read(&em->refs) != 1) { @@ -142,7 +143,7 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) } free_extent_map(em); out: - ret2 = free_extent_map_tree(em_tree); + ret2 = free_extent_map_tree(inode); if (ret == 0) ret = ret2; @@ -237,7 +238,7 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) } free_extent_map(em); out: - ret2 = free_extent_map_tree(em_tree); + ret2 = free_extent_map_tree(inode); if (ret == 0) ret = ret2; @@ -313,7 +314,7 @@ static int __test_case_3(struct btrfs_fs_info *fs_info, } free_extent_map(em); out: - ret2 = free_extent_map_tree(em_tree); + ret2 = free_extent_map_tree(inode); if (ret == 0) ret = ret2; @@ -435,7 +436,7 @@ static int __test_case_4(struct btrfs_fs_info *fs_info, } free_extent_map(em); out: - ret2 = free_extent_map_tree(em_tree); + ret2 = free_extent_map_tree(inode); if (ret == 0) ret = ret2; @@ -679,7 +680,7 @@ static int test_case_5(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) if (ret) goto out; out: - ret2 = free_extent_map_tree(&inode->extent_tree); + ret2 = free_extent_map_tree(inode); if (ret == 0) ret = ret2; @@ -738,7 +739,7 @@ static int test_case_6(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) ret = 0; out: free_extent_map(em); - ret2 = free_extent_map_tree(em_tree); + ret2 = free_extent_map_tree(inode); if (ret == 0) ret = ret2; @@ -871,7 +872,7 @@ static int test_case_7(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) ret2 = unpin_extent_cache(inode, 0, SZ_16K, 0); if (ret == 0) ret = ret2; - ret2 = free_extent_map_tree(em_tree); + ret2 = free_extent_map_tree(inode); if (ret == 0) ret = ret2; From patchwork Tue Apr 16 13:08:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13631802 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 E03E312C462 for ; Tue, 16 Apr 2024 13:08:19 +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=1713272900; cv=none; b=VINUYv8yCql6q9SB48JJS3u3QAPjDqlkVJkNoRAekjnA/t+am5b06IsaB3RDgCwNU5zmpwxPUMP9WDg3qriEEjCXO6QwoFsR5q0GTrPxrHkvfXR5aMLUnCzOa0LXiVrIyVIrW2E48bBUJ6C/m2YHxpT7hRyLSoC3K70Gpu5shvg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713272900; c=relaxed/simple; bh=XhLUtIC4Fe2r6iFznUATOGkB7IZocndkxRdtp63EFlM=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=fMVmkTPzvHkal/c6/ux3KabJUAbV0ODD/V4IXoSj9VrEXKbBtsEMCKJ6T89tP1k3h4stRAxvT42Bk09Ab+SUkuQVNz6R1iI1bgkYA8sTiyntmK0romK9vU4rJfB+dRnDqZboCS1/so8KSyCbep0Xc/lj07c/lFDX4NdwFgNqWig= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=E9yK+yrf; 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="E9yK+yrf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D2424C2BD11 for ; Tue, 16 Apr 2024 13:08:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713272899; bh=XhLUtIC4Fe2r6iFznUATOGkB7IZocndkxRdtp63EFlM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=E9yK+yrfXjQDaHRWEobFyDhG4HMn6UlpPVG9dN45hRCZ3H6QG8DknCNaOwgtkSxbF G0e8vMZiUTYW2P96Povu2cM/j/N0gXn/iDPY/QtW26jBj6a/dKQdoR/Ky+cykCEsH4 ce/DhAcorEbAD4kCW/BAssoiWnIue2EchsV6pLtDdGCAD+dBF7+53ouD/AoQuyJ86x QLgI5TR5MxyVZarnpCWMWbiYEIg1fDJpXwiDwisenq4rqe/DBZqkOIxH48t89NAFUy Fga31jDsKWAOTOmc1trzYUBtx4O1VI+v6UjuDJ6RbJ2Q7GetXHUIca50YzK2/5yFKN WJxVtaiLNXxoA== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v3 04/10] btrfs: pass the extent map tree's inode to replace_extent_mapping() Date: Tue, 16 Apr 2024 14:08:06 +0100 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-btrfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Filipe Manana Extent maps are always associated to an inode's extent map tree, so there's no need to pass the extent map tree explicitly to replace_extent_mapping(). In order to facilitate an upcoming change that adds a shrinker for extent maps, change replace_extent_mapping() to receive the inode instead of its extent map tree. Reviewed-by: Qu Wenruo Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Reviewed-by: Johannes Thumshirn --- fs/btrfs/extent_map.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 289669763965..15817b842c24 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -470,11 +470,13 @@ void remove_extent_mapping(struct btrfs_inode *inode, struct extent_map *em) RB_CLEAR_NODE(&em->rb_node); } -static void replace_extent_mapping(struct extent_map_tree *tree, +static void replace_extent_mapping(struct btrfs_inode *inode, struct extent_map *cur, struct extent_map *new, int modified) { + struct extent_map_tree *tree = &inode->extent_tree; + lockdep_assert_held_write(&tree->lock); WARN_ON(cur->flags & EXTENT_FLAG_PINNED); @@ -777,7 +779,7 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end, split->generation = gen; split->flags = flags; - replace_extent_mapping(em_tree, em, split, modified); + replace_extent_mapping(inode, em, split, modified); free_extent_map(split); split = split2; split2 = NULL; @@ -818,8 +820,7 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end, } if (extent_map_in_tree(em)) { - replace_extent_mapping(em_tree, em, split, - modified); + replace_extent_mapping(inode, em, split, modified); } else { int ret; @@ -977,7 +978,7 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre, split_pre->flags = flags; split_pre->generation = em->generation; - replace_extent_mapping(em_tree, em, split_pre, 1); + replace_extent_mapping(inode, em, split_pre, 1); /* * Now we only have an extent_map at: From patchwork Tue Apr 16 13:08:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13631803 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 D9FF312C466 for ; Tue, 16 Apr 2024 13:08:20 +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=1713272900; cv=none; b=VIV9b+qkURiRXjb3s2XFIq9s3Y9FA/LO4uKWHhZK82kUzEsx1pZNumUOspUmPk7tVtXmglX+IOODuwXN6lhzMqDoL3rvPLJQWSVw59iuXEuUnBW1VPabrdfMYqxhc0RGWQa3vn9aSVt81oKY6eojcH+ZQWKpiRnMYME4CJ8TvIs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713272900; c=relaxed/simple; bh=6XW7G0jQgKqKLZTumOVLMYJVfCa/j+SxU7WxYvkBKj8=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=EI2qiOr/+9aBzewMZBKcHJZTl5ZegpYbYJB0jSrQ2fPzsRsTwLf2iWL9iC9pnUwuFiDWRxmTOoFSxckrVc/Ei41mHTLkti4MQmBEQPiKwpwqYTqbf27FrcRW6e47e/U1G+YwS1facsef3Sg4QwWePxQoDOwvAYUeS3l1YlelER4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VQo1RdLN; 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="VQo1RdLN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CD95BC32783 for ; Tue, 16 Apr 2024 13:08:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713272900; bh=6XW7G0jQgKqKLZTumOVLMYJVfCa/j+SxU7WxYvkBKj8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=VQo1RdLNvGQ32od0rPs58QxdMMrUSo7j3He5wVsZ/Y1UCeV8hQr6daEF5bx1pZo1m JUCwzqBDkKk8PK3prJwVG2zNAyeLl5KcwF/nI23DxRz0v1+ebkIpXE6gNEbPjxCf9G w4OwnA2Uat/pXL3Qy9ktfHgDl7nZ8JATt/u7PmlvB5NmGUBReglJLpm3SHqMeSx18n qcs1tc2Qzb1qapU9vZapB77Zz9xO3El3/EIcji2djg3eHCG+XaA0W9YycVs4Ni4+zU dqEqyA7Qtocz+tynZ09FnBCSLGzWKKJYL79ywe2eGinAOdP5XlP1buRhukqWUpvptt YKKTmfE0qQEyg== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v3 05/10] btrfs: pass the extent map tree's inode to setup_extent_mapping() Date: Tue, 16 Apr 2024 14:08:07 +0100 Message-Id: <29e0cd5f1077fc214aabb5ba1f404d993a670d4d.1713267925.git.fdmanana@suse.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-btrfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Filipe Manana Extent maps are always associated to an inode's extent map tree, so there's no need to pass the extent map tree explicitly to setup_extent_mapping(). In order to facilitate an upcoming change that adds a shrinker for extent maps, change setup_extent_mapping() to receive the inode instead of its extent map tree. Reviewed-by: Qu Wenruo Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Reviewed-by: Johannes Thumshirn --- fs/btrfs/extent_map.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 15817b842c24..2753bf2964cb 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -342,7 +342,7 @@ void clear_em_logging(struct btrfs_inode *inode, struct extent_map *em) try_merge_map(tree, em); } -static inline void setup_extent_mapping(struct extent_map_tree *tree, +static inline void setup_extent_mapping(struct btrfs_inode *inode, struct extent_map *em, int modified) { @@ -351,9 +351,9 @@ static inline void setup_extent_mapping(struct extent_map_tree *tree, ASSERT(list_empty(&em->list)); if (modified) - list_add(&em->list, &tree->modified_extents); + list_add(&em->list, &inode->extent_tree.modified_extents); else - try_merge_map(tree, em); + try_merge_map(&inode->extent_tree, em); } /* @@ -381,7 +381,7 @@ static int add_extent_mapping(struct btrfs_inode *inode, if (ret) return ret; - setup_extent_mapping(tree, em, modified); + setup_extent_mapping(inode, em, modified); return 0; } @@ -486,7 +486,7 @@ static void replace_extent_mapping(struct btrfs_inode *inode, rb_replace_node_cached(&cur->rb_node, &new->rb_node, &tree->map); RB_CLEAR_NODE(&cur->rb_node); - setup_extent_mapping(tree, new, modified); + setup_extent_mapping(inode, new, modified); } static struct extent_map *next_extent_map(const struct extent_map *em) From patchwork Tue Apr 16 13:08:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13631804 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 7BC7312C49D for ; Tue, 16 Apr 2024 13:08:21 +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=1713272901; cv=none; b=eJvUDRYgr/808OaFU8u7y4xXIwLS2wMRzy9qhAqskGnv5Es320O8BmekPzPhRHYVjJBRbyPfilws7Uju4lU9W64UJo5dzjiohgqi3v6m3Kp6fitpvswF17H8tc7o3vaFb2bOxFKZ4hMUT9uz1mXKlLdn80PV3OnoLPWIHIStVWc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713272901; c=relaxed/simple; bh=g91G3/q4bMeb7ReGDD/rMoY+jexL8fbN3ftACf2rvWY=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=HtHQDKlfGUxycAx2BpIHAPq81B68oO9xQlTn7h717M3wfM+zT5SorGevKuxkctegqIPtqopQbDBCfGprV8lcVehHptddu63EyDFtrGbhvHi4RAl9uzfsUWekoncf0S80qIJEqN+46Ho9BGqvDqg/FEW59eVBOhY8pDtEnm5dXu8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Y1O6lA2U; 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="Y1O6lA2U" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C888FC2BD10 for ; Tue, 16 Apr 2024 13:08:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713272901; bh=g91G3/q4bMeb7ReGDD/rMoY+jexL8fbN3ftACf2rvWY=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Y1O6lA2U1glAut8II2mT6oBwAQSDVjLush9NIjxiib5woMXY2XYnjz5tkKHOUe30I CL/iHk5AXCINKqVgiLl9RNbAkD2rkvX82A3r6dIc6CgTLY7HHOHdpT1c9MgcKzh/6m /YKCup9Y7p60Xv3ZmmS21vHDZ11GglgKfEdSBNXB2HDmYZOE/rWM+FxpUPZX3DujOY kQ4VmFEyrIDOp4SDjUNdiYmq4FpwK3ijmX1ZurmrXiBhXLx6myvNgwRabIBjaGvsWp iKJySu6SZZEjWXzAmUb76j6x6Q96PGTG02k93o3g5PcC+1EP06sOPh7+DGV/q8YhZ2 JRZa3lw2WwIzg== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v3 06/10] btrfs: pass the extent map tree's inode to try_merge_map() Date: Tue, 16 Apr 2024 14:08:08 +0100 Message-Id: <7b4df753d47b4efc82769f897708ac146dfaf521.1713267925.git.fdmanana@suse.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-btrfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Filipe Manana Extent maps are always associated to an inode's extent map tree, so there's no need to pass the extent map tree explicitly to try_merge_map(). In order to facilitate an upcoming change that adds a shrinker for extent maps, change try_merge_map() to receive the inode instead of its extent map tree. Reviewed-by: Qu Wenruo Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Reviewed-by: Johannes Thumshirn --- fs/btrfs/extent_map.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 2753bf2964cb..97a8e0484415 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -223,8 +223,9 @@ static bool mergeable_maps(const struct extent_map *prev, const struct extent_ma return next->block_start == prev->block_start; } -static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em) +static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em) { + struct extent_map_tree *tree = &inode->extent_tree; struct extent_map *merge = NULL; struct rb_node *rb; @@ -322,7 +323,7 @@ int unpin_extent_cache(struct btrfs_inode *inode, u64 start, u64 len, u64 gen) em->generation = gen; em->flags &= ~EXTENT_FLAG_PINNED; - try_merge_map(tree, em); + try_merge_map(inode, em); out: write_unlock(&tree->lock); @@ -333,13 +334,11 @@ int unpin_extent_cache(struct btrfs_inode *inode, u64 start, u64 len, u64 gen) void clear_em_logging(struct btrfs_inode *inode, struct extent_map *em) { - struct extent_map_tree *tree = &inode->extent_tree; - - lockdep_assert_held_write(&tree->lock); + lockdep_assert_held_write(&inode->extent_tree.lock); em->flags &= ~EXTENT_FLAG_LOGGING; if (extent_map_in_tree(em)) - try_merge_map(tree, em); + try_merge_map(inode, em); } static inline void setup_extent_mapping(struct btrfs_inode *inode, @@ -353,7 +352,7 @@ static inline void setup_extent_mapping(struct btrfs_inode *inode, if (modified) list_add(&em->list, &inode->extent_tree.modified_extents); else - try_merge_map(&inode->extent_tree, em); + try_merge_map(inode, em); } /* From patchwork Tue Apr 16 13:08:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13631805 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 6D10812C53B for ; Tue, 16 Apr 2024 13:08:22 +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=1713272902; cv=none; b=NoVZSHMU/p7f25a5cqe24UgT8go7m6jlvOSGpTpSD0I7jvIseIg6Vi7WEmWjyheohxUgJsDmRYMF7dEaHnouNrVJ+qOQYkqtG+9i7cALE0MXFFIv6+hRkTsq1PRuydEqANIhZOplRYiSEk8zie0Fzk8yESmd8B3E5Z7Chc+GrZs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713272902; c=relaxed/simple; bh=FyNoDu4578Eve0es0Is8E3lhvf6VxzRe7XHvR7LD2Z0=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WuhRkEMgD8Ipf5nRLNJd64Bc6LxbtLFYSZ7UtGfIODsqIL5TQSnaQ5FnI+u4Idgb5wBTUuxr5pU6uFHyormb/1h5F1a6NMkvxBwnHgG89dCqMJ3xkk3ZLcYpRdlbGr0GKsYdoi23B2pT8oS6medHWZnBhUgKSl6vIWosBEpxNzM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QZo/LGfq; 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="QZo/LGfq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C453CC32783 for ; Tue, 16 Apr 2024 13:08:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713272902; bh=FyNoDu4578Eve0es0Is8E3lhvf6VxzRe7XHvR7LD2Z0=; h=From:To:Subject:Date:In-Reply-To:References:From; b=QZo/LGfqeJHFnkjkHWPEh9JzkoNSvt0bv05purjGQ//DJ1q3yPJPu/izhO8ym/JTi CtBt3er/TiNyM0UNOu7w7ghgv9vBxxoFhIuw8oTXl1D+FWP3/0rItAO2HbwgIt1Avs HSOB4v4/C3y3sOySAmwNENA+jplOpoQB/2VjICk28mtWmzzcpMl0Q6ow8preTnnG3t zLNKiDdCPTkhXv15d/qy50RIsUHEeFNV/Z7hlGdtjTyquJEiEppqWeduV1RE+mrj6I 0QJj1xZIp6mv8ZHJU8C2IcMgnpdTf21DPOTqVd0WyEvm+a7brRJaiorj8Fu3bGWvkb Iwv+r58EgVjTA== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v3 07/10] btrfs: add a global per cpu counter to track number of used extent maps Date: Tue, 16 Apr 2024 14:08:09 +0100 Message-Id: <5148d35a4b3dac4e02f963e59f2154c56edaae29.1713267925.git.fdmanana@suse.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-btrfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Filipe Manana Add a per cpu counter that tracks the total number of extent maps that are in extent trees of inodes that belong to fs trees. This is going to be used in an upcoming change that adds a shrinker for extent maps. Only extent maps for fs trees are considered, because for special trees such as the data relocation tree we don't want to evict their extent maps which are critical for the relocation to work, and since those are limited, it's not a concern to have them in memory during the relocation of a block group. Another case are extent maps for free space cache inodes, which must always remain in memory, but those are limited (there's only one per free space cache inode, which means one per block group). Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Reviewed-by: Johannes Thumshirn --- fs/btrfs/disk-io.c | 9 +++++++++ fs/btrfs/extent_map.c | 17 +++++++++++++++++ fs/btrfs/fs.h | 2 ++ 3 files changed, 28 insertions(+) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 0474e9b6d302..bc9d1b48011e 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1266,9 +1266,14 @@ static void free_global_roots(struct btrfs_fs_info *fs_info) void btrfs_free_fs_info(struct btrfs_fs_info *fs_info) { + struct percpu_counter *em_counter = &fs_info->evictable_extent_maps; + percpu_counter_destroy(&fs_info->dirty_metadata_bytes); percpu_counter_destroy(&fs_info->delalloc_bytes); percpu_counter_destroy(&fs_info->ordered_bytes); + if (percpu_counter_initialized(em_counter)) + ASSERT(percpu_counter_sum_positive(em_counter) == 0); + percpu_counter_destroy(em_counter); percpu_counter_destroy(&fs_info->dev_replace.bio_counter); btrfs_free_csum_hash(fs_info); btrfs_free_stripe_hash_table(fs_info); @@ -2848,6 +2853,10 @@ static int init_mount_fs_info(struct btrfs_fs_info *fs_info, struct super_block if (ret) return ret; + ret = percpu_counter_init(&fs_info->evictable_extent_maps, 0, GFP_KERNEL); + if (ret) + return ret; + ret = percpu_counter_init(&fs_info->dirty_metadata_bytes, 0, GFP_KERNEL); if (ret) return ret; diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 97a8e0484415..2fcf28148a81 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -76,6 +76,14 @@ static u64 range_end(u64 start, u64 len) return start + len; } +static void dec_evictable_extent_maps(struct btrfs_inode *inode) +{ + struct btrfs_fs_info *fs_info = inode->root->fs_info; + + if (!btrfs_is_testing(fs_info) && is_fstree(btrfs_root_id(inode->root))) + percpu_counter_dec(&fs_info->evictable_extent_maps); +} + static int tree_insert(struct rb_root_cached *root, struct extent_map *em) { struct rb_node **p = &root->rb_root.rb_node; @@ -259,6 +267,7 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em) rb_erase_cached(&merge->rb_node, &tree->map); RB_CLEAR_NODE(&merge->rb_node); free_extent_map(merge); + dec_evictable_extent_maps(inode); } } @@ -273,6 +282,7 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em) em->generation = max(em->generation, merge->generation); em->flags |= EXTENT_FLAG_MERGED; free_extent_map(merge); + dec_evictable_extent_maps(inode); } } @@ -372,6 +382,8 @@ static int add_extent_mapping(struct btrfs_inode *inode, struct extent_map *em, int modified) { struct extent_map_tree *tree = &inode->extent_tree; + struct btrfs_root *root = inode->root; + struct btrfs_fs_info *fs_info = root->fs_info; int ret; lockdep_assert_held_write(&tree->lock); @@ -382,6 +394,9 @@ static int add_extent_mapping(struct btrfs_inode *inode, setup_extent_mapping(inode, em, modified); + if (!btrfs_is_testing(fs_info) && is_fstree(btrfs_root_id(root))) + percpu_counter_inc(&fs_info->evictable_extent_maps); + return 0; } @@ -467,6 +482,8 @@ void remove_extent_mapping(struct btrfs_inode *inode, struct extent_map *em) if (!(em->flags & EXTENT_FLAG_LOGGING)) list_del_init(&em->list); RB_CLEAR_NODE(&em->rb_node); + + dec_evictable_extent_maps(inode); } static void replace_extent_mapping(struct btrfs_inode *inode, diff --git a/fs/btrfs/fs.h b/fs/btrfs/fs.h index 93f5c57ea4e3..534d30dafe32 100644 --- a/fs/btrfs/fs.h +++ b/fs/btrfs/fs.h @@ -630,6 +630,8 @@ struct btrfs_fs_info { s32 dirty_metadata_batch; s32 delalloc_batch; + struct percpu_counter evictable_extent_maps; + /* Protected by 'trans_lock'. */ struct list_head dirty_cowonly_roots; From patchwork Tue Apr 16 13:08:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13631806 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 683B812C559 for ; Tue, 16 Apr 2024 13:08:23 +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=1713272903; cv=none; b=NIoJl8OoZ90IUgfVTxDX+wti3N0AX1asDPV4C08Q87SFbBeC2ltJHOdo+8IahjE7E81CgfJ/ZQwfYnvOFDhq2DcUqFIwNgyEtzE1wXtloISdJSS9PxSFwlrbEzl82j1CQpQOEM3N0RSub8FdrD4zpLeD8++luUFlKMf+zX71wwo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713272903; c=relaxed/simple; bh=bpdAynDBPC6x2ztHBO/XyB4YARk/v6jttCB/E/J09kA=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=l67MAoIkboqMMjRE91aV9ZscsAi/T0cczxgoMDxYA8HkHp3+xnJC79qF3kSZJB+xXN41NF0DSY8VBPTOWxZTwafYdm1kfMm/J6fwCH6KGsNrj8yxAWYhlCRJrO8kO7SgNburj6FxaKrzXt230D3xMQlsac93xOUkKCd0pb32M/g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Wbl6xwVF; 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="Wbl6xwVF" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BF1B1C2BD10 for ; Tue, 16 Apr 2024 13:08:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713272903; bh=bpdAynDBPC6x2ztHBO/XyB4YARk/v6jttCB/E/J09kA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Wbl6xwVFeRmD1ww0vMqEAQIP3jdOgmP2w4o/47XwDmM0ST05pcOPer6gqrPG2DFa8 MBpchkwoWivspmV1lmNm2Yl3NNxPHrgXcuFcCa58G3FMwfZF0Vxdkc9YTmvS4uJjOH vWnh5KNJVYDBBosmYhA+wOg+DcKo8Ly3f8Yj6UBA3iFf/sDDkuWLapJH0XeSr/GJKE ev2PVMLyM9GHzRNireMSbwpLx0ptY6RP3Aqp3vzbs+ELxmKaCJtjs1McwBwNEzY0IV Y8KbKbH8sCzPEj7POtEnKTbu5MtDbvJUiQLf5+0B8HUrqjl/iPpqnRER7VOBrnpGEO et6eDgO7H5zIQ== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v3 08/10] btrfs: add a shrinker for extent maps Date: Tue, 16 Apr 2024 14:08:10 +0100 Message-Id: <4bfde54904b5a91a71eb0d86b9c78367865f93d8.1713267925.git.fdmanana@suse.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-btrfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Filipe Manana Extent maps are used either to represent existing file extent items, or to represent new extents that are going to be written and the respective file extent items are created when the ordered extent completes. We currently don't have any limit for how many extent maps we can have, neither per inode nor globally. Most of the time this not too noticeable because extent maps are removed in the following situations: 1) When evicting an inode; 2) When releasing folios (pages) through the btrfs_release_folio() address space operation callback. However we won't release extent maps in the folio range if the folio is either dirty or under writeback or if the inode's i_size is less than or equals to 16M (see try_release_extent_mapping(). This 16M i_size constraint was added back in 2008 with commit 70dec8079d78 ("Btrfs: extent_io and extent_state optimizations"), but there's no explanation about why we have it or why the 16M value. This means that for buffered IO we can reach an OOM situation due to too many extent maps if either of the following happens: 1) There's a set of tasks constantly doing IO on many files with a size not larger than 16M, specially if they keep the files open for very long periods, therefore preventing inode eviction. This requires a really high number of such files, and having many non mergeable extent maps (due to random 4K writes for example) and a machine with very little memory; 2) There's a set tasks constantly doing random write IO (therefore creating many non mergeable extent maps) on files and keeping them open for long periods of time, so inode eviction doesn't happen and there's always a lot of dirty pages or pages under writeback, preventing btrfs_release_folio() from releasing the respective extent maps. This second case was actually reported in the thread pointed by the Link tag below, and it requires a very large file under heavy IO and a machine with very little amount of RAM, which is probably hard to happen in practice in a real world use case. However when using direct IO this is not so hard to happen, because the page cache is not used, and therefore btrfs_release_folio() is never called. Which means extent maps are dropped only when evicting the inode, and that means that if we have tasks that keep a file descriptor open and keep doing IO on a very large file (or files), we can exhaust memory due to an unbounded amount of extent maps. This is especially easy to happen if we have a huge file with millions of small extents and their extent maps are not mergeable (non contiguous offsets and disk locations). This was reported in that thread with the following fio test: $ cat test.sh #!/bin/bash DEV=/dev/sdj MNT=/mnt/sdj MOUNT_OPTIONS="-o ssd" MKFS_OPTIONS="" cat < /tmp/fio-job.ini [global] name=fio-rand-write filename=$MNT/fio-rand-write rw=randwrite bs=4K direct=1 numjobs=16 fallocate=none time_based runtime=90000 [file1] size=300G ioengine=libaio iodepth=16 EOF umount $MNT &> /dev/null mkfs.btrfs -f $MKFS_OPTIONS $DEV mount $MOUNT_OPTIONS $DEV $MNT fio /tmp/fio-job.ini umount $MNT Monitoring the btrfs_extent_map slab while running the test with: $ watch -d -n 1 'cat /sys/kernel/slab/btrfs_extent_map/objects \ /sys/kernel/slab/btrfs_extent_map/total_objects' Shows the number of active and total extent maps skyrocketing to tens of millions, and on systems with a short amount of memory it's easy and quick to get into an OOM situation, as reported in that thread. So to avoid this issue add a shrinker that will remove extents maps, as long as they are not pinned, and takes proper care with any concurrent fsync to avoid missing extents (setting the full sync flag while in the middle of a fast fsync). This shrinker is triggered through the callbacks nr_cached_objects and free_cached_objects of struct super_operations. The shrinker will iterates over all roots and over all inodes of each root, and keeps track of the last scanned root and inode, so that the next time it runs, it starts from that root and from the next inode. This is similar to what xfs does for its inode reclaim (implements those callbacks, and cycles through inodes by starting from where it ended last time). Signed-off-by: Filipe Manana Reviewed-by: Josef Bacik --- fs/btrfs/extent_map.c | 159 ++++++++++++++++++++++++++++++++++++++++++ fs/btrfs/extent_map.h | 1 + fs/btrfs/fs.h | 2 + fs/btrfs/super.c | 17 +++++ 4 files changed, 179 insertions(+) diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 2fcf28148a81..b638d87db500 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -8,6 +8,7 @@ #include "extent_map.h" #include "compression.h" #include "btrfs_inode.h" +#include "disk-io.h" static struct kmem_cache *extent_map_cache; @@ -1026,3 +1027,161 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre, free_extent_map(split_pre); return ret; } + +static long btrfs_scan_inode(struct btrfs_inode *inode, long *scanned, long nr_to_scan) +{ + const u64 cur_fs_gen = btrfs_get_fs_generation(inode->root->fs_info); + struct extent_map_tree *tree = &inode->extent_tree; + long nr_dropped = 0; + struct rb_node *node; + + /* + * Take the mmap lock so that we serialize with the inode logging phase + * of fsync because we may need to set the full sync flag on the inode, + * in case we have to remove extent maps in the tree's list of modified + * extents. If we set the full sync flag in the inode while an fsync is + * in progress, we may risk missing new extents because before the flag + * is set, fsync decides to only wait for writeback to complete and then + * during inode logging it sees the flag set and uses the subvolume tree + * to find new extents, which may not be there yet because ordered + * extents haven't completed yet. + * + * We also do a try lock because otherwise we could deadlock. This is + * because the shrinker for this filesystem may be invoked while we are + * in a path that is holding the mmap lock in write mode. For example in + * a reflink operation while COWing an extent buffer, when allocating + * pages for a new extent buffer and under memory pressure, the shrinker + * may be invoked, and therefore we would deadlock by attempting to read + * lock the mmap lock while we are holding already a write lock on it. + */ + if (!down_read_trylock(&inode->i_mmap_lock)) + return 0; + + write_lock(&tree->lock); + node = rb_first_cached(&tree->map); + while (node) { + struct extent_map *em; + + em = rb_entry(node, struct extent_map, rb_node); + node = rb_next(node); + (*scanned)++; + + if (em->flags & EXTENT_FLAG_PINNED) + goto next; + + /* + * If the inode is in the list of modified extents (new) and its + * generation is the same (or is greater than) the current fs + * generation, it means it was not yet persisted so we have to + * set the full sync flag so that the next fsync will not miss + * it. + */ + if (!list_empty(&em->list) && em->generation >= cur_fs_gen) + btrfs_set_inode_full_sync(inode); + + remove_extent_mapping(inode, em); + /* Drop the reference for the tree. */ + free_extent_map(em); + nr_dropped++; +next: + if (*scanned >= nr_to_scan) + break; + + /* + * Restart if we had to resched, and any extent maps that were + * pinned before may have become unpinned after we released the + * lock and took it again. + */ + if (cond_resched_rwlock_write(&tree->lock)) + node = rb_first_cached(&tree->map); + } + write_unlock(&tree->lock); + up_read(&inode->i_mmap_lock); + + return nr_dropped; +} + +static long btrfs_scan_root(struct btrfs_root *root, long *scanned, long nr_to_scan) +{ + struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_inode *inode; + long nr_dropped = 0; + u64 min_ino = fs_info->extent_map_shrinker_last_ino + 1; + + inode = btrfs_find_first_inode(root, min_ino); + while (inode) { + nr_dropped += btrfs_scan_inode(inode, scanned, nr_to_scan); + + min_ino = btrfs_ino(inode) + 1; + fs_info->extent_map_shrinker_last_ino = btrfs_ino(inode); + iput(&inode->vfs_inode); + + if (*scanned >= nr_to_scan) + break; + + cond_resched(); + inode = btrfs_find_first_inode(root, min_ino); + } + + if (inode) { + /* + * There are still inodes in this root or we happened to process + * the last one and reached the scan limit. In either case set + * the current root to this one, so we'll resume from the next + * inode if there is one or we will find out this was the last + * one and move to the next root. + */ + fs_info->extent_map_shrinker_last_root = btrfs_root_id(root); + } else { + /* + * No more inodes in this root, set extent_map_shrinker_last_ino to 0 so + * that when processing the next root we start from its first inode. + */ + fs_info->extent_map_shrinker_last_ino = 0; + fs_info->extent_map_shrinker_last_root = btrfs_root_id(root) + 1; + } + + return nr_dropped; +} + +long btrfs_free_extent_maps(struct btrfs_fs_info *fs_info, long nr_to_scan) +{ + const u64 start_root_id = fs_info->extent_map_shrinker_last_root; + u64 next_root_id = start_root_id; + bool cycled = false; + long nr_dropped = 0; + long scanned = 0; + + while (scanned < nr_to_scan) { + struct btrfs_root *root; + unsigned long count; + + spin_lock(&fs_info->fs_roots_radix_lock); + count = radix_tree_gang_lookup(&fs_info->fs_roots_radix, + (void **)&root, next_root_id, 1); + if (count == 0) { + spin_unlock(&fs_info->fs_roots_radix_lock); + if (start_root_id > 0 && !cycled) { + next_root_id = 0; + fs_info->extent_map_shrinker_last_root = 0; + fs_info->extent_map_shrinker_last_ino = 0; + cycled = true; + continue; + } + break; + } + next_root_id = btrfs_root_id(root) + 1; + root = btrfs_grab_root(root); + spin_unlock(&fs_info->fs_roots_radix_lock); + + if (!root) + continue; + + if (is_fstree(btrfs_root_id(root))) + nr_dropped += btrfs_scan_root(root, &scanned, nr_to_scan); + + btrfs_put_root(root); + } + + return nr_dropped; +} diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index c3707461ff62..8306a8f294d0 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h @@ -140,5 +140,6 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, int btrfs_replace_extent_map_range(struct btrfs_inode *inode, struct extent_map *new_em, bool modified); +long btrfs_free_extent_maps(struct btrfs_fs_info *fs_info, long nr_to_scan); #endif diff --git a/fs/btrfs/fs.h b/fs/btrfs/fs.h index 534d30dafe32..9711c9c0e78f 100644 --- a/fs/btrfs/fs.h +++ b/fs/btrfs/fs.h @@ -631,6 +631,8 @@ struct btrfs_fs_info { s32 delalloc_batch; struct percpu_counter evictable_extent_maps; + u64 extent_map_shrinker_last_root; + u64 extent_map_shrinker_last_ino; /* Protected by 'trans_lock'. */ struct list_head dirty_cowonly_roots; diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 7e44ccaf348f..a3877e65d3b5 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -2374,6 +2374,21 @@ static int btrfs_show_devname(struct seq_file *m, struct dentry *root) return 0; } +static long btrfs_nr_cached_objects(struct super_block *sb, struct shrink_control *sc) +{ + struct btrfs_fs_info *fs_info = btrfs_sb(sb); + + return percpu_counter_sum_positive(&fs_info->evictable_extent_maps); +} + +static long btrfs_free_cached_objects(struct super_block *sb, struct shrink_control *sc) +{ + const long nr_to_scan = min_t(unsigned long, LONG_MAX, sc->nr_to_scan); + struct btrfs_fs_info *fs_info = btrfs_sb(sb); + + return btrfs_free_extent_maps(fs_info, nr_to_scan); +} + static const struct super_operations btrfs_super_ops = { .drop_inode = btrfs_drop_inode, .evict_inode = btrfs_evict_inode, @@ -2387,6 +2402,8 @@ static const struct super_operations btrfs_super_ops = { .statfs = btrfs_statfs, .freeze_fs = btrfs_freeze, .unfreeze_fs = btrfs_unfreeze, + .nr_cached_objects = btrfs_nr_cached_objects, + .free_cached_objects = btrfs_free_cached_objects, }; static const struct file_operations btrfs_ctl_fops = { From patchwork Tue Apr 16 13:08:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13631807 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 BC69112C819 for ; Tue, 16 Apr 2024 13:08:24 +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=1713272904; cv=none; b=VPwekK3DVmYS7tx3fvk89VChvnv18LhcEeqizIA3w8KcVzv6wgVD52A/3T7IW7KTVWXER+s443mmrgsGRhgPgkgbOBA95LUnwTeBiWDpJORA4J9SF5de+YV6ChsxFVZAXN16EULpSx5RXxKX4ptUTjHu9gpBy1gAPOiTU+RKwe4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713272904; c=relaxed/simple; bh=8N8m0mJg6ZSmycLbpiIAXUegEgLeH4iOu2NjKUBuGVI=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZMhxVYSdMchG/w3dHa3nXI5oAdq9+ldKaoaxsMNqV+X1GcIH9W64R9DtpFrUSY67RFIW54Xnx7E6o24g1GhopHJu8OeCM9Vxozosc5dAsozS7piTZafhr1IaZlUCVPuCPmBfcDjed7Qi5NqRmHsWYcsvOuBlzmXIwMoUYZ+JV6s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JOWrCPR0; 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="JOWrCPR0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B931AC2BD10 for ; Tue, 16 Apr 2024 13:08:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713272904; bh=8N8m0mJg6ZSmycLbpiIAXUegEgLeH4iOu2NjKUBuGVI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=JOWrCPR08JBwe1+VrPVHYY65fcNO2CFq4Win4+mwthhKuow7OgBD602L9fDcE8am4 UOd1Ev2dFD60Co5VwkW2fhWfmrpyB9PuigHBvTjJ7qMWTGpi6runl+tG6OTC6lW/XE QyOReJLwdLm4s5lFXmIvC2Fq8m2QnSBYHFzupecvWfnc1d807N6/c7IEBXyrjYNM5U qM9ZZnLumEWthKCOwf1SIt5kxrJvkBr+yiQft5lu+5uQYsl8TmeIFstMkqj3Lb3Qdh fWQNLACsSobaizcaxxcPopYw96g2a8CpXD58aaR1NtTS3RxrdTWUO/Lh8VZdFEHY1m Q48oG1i1pylbA== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v3 09/10] btrfs: update comment for btrfs_set_inode_full_sync() about locking Date: Tue, 16 Apr 2024 14:08:11 +0100 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-btrfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Filipe Manana Nowadays we have a lock used to synchronize mmap writes with reflink and fsync operations (struct btrfs_inode::i_mmap_lock), so update the comment for btrfs_set_inode_full_sync() to mention that it can also be called while holding that mmap lock. Besides being a valid alternative to the inode's VFS lock, we already have the extent map shrinker using that mmap lock instead. Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana --- fs/btrfs/btrfs_inode.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index 9a87ada7fe52..91c994b569f3 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -381,9 +381,11 @@ static inline void btrfs_set_inode_last_sub_trans(struct btrfs_inode *inode) } /* - * Should be called while holding the inode's VFS lock in exclusive mode or in a - * context where no one else can access the inode concurrently (during inode - * creation or when loading an inode from disk). + * Should be called while holding the inode's VFS lock in exclusive mode, or + * while holding the inode's mmap lock (struct btrfs_inode::i_mmap_lock) in + * either shared or exclusive mode, or in a context where no one else can access + * the inode concurrently (during inode creation or when loading an inode from + * disk). */ static inline void btrfs_set_inode_full_sync(struct btrfs_inode *inode) { From patchwork Tue Apr 16 13:08:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13631808 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 A76D412CD8C for ; Tue, 16 Apr 2024 13:08:25 +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=1713272905; cv=none; b=i3Qlj/oburaxSNvpVPsii7o71zgdf6uCG7afO/LzI65B8+BflDwZiINYeSXjfkufdmXRtdd0i9siNI2EsrfD8tq+nuYYerPUbHTmoAuVOccC+RK4CvP7MQTOHvk80PaoitcndUvvl+3njz0qg4dg8l26VBgLm+pyexYSK6kIj+8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713272905; c=relaxed/simple; bh=CnF0TlW1MdISiGc6Pb32Gfocqps+xZ7JI3Umg1IrJmo=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=aC+0LzOah53az2OK3aUThpZE2TW55DnMQDZcXfPPr9tT2T77pZNgU+v7WIbJJ2haJ7Eh4q44GjwUpy4KgiFAxeeFDCUOuriS0x04VTqA318eIbcNMKDT0rHKadV5rwPqbQ23khUWyYUbI4+kOVsUvm7Dwb9W46moVRGbUWl27Kw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RfoWc41J; 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="RfoWc41J" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B3D3DC32783 for ; Tue, 16 Apr 2024 13:08:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713272905; bh=CnF0TlW1MdISiGc6Pb32Gfocqps+xZ7JI3Umg1IrJmo=; h=From:To:Subject:Date:In-Reply-To:References:From; b=RfoWc41JisSw8gl9R1D/Cwa//9kp1mslbzRQSu7AAWsXxBYfj/qicRUUZfm9URc35 XY2ZTOja3zzrxlnAUW44wFmpxtbadKWL47GPDz6AXhIIttMABoiMtAWzcXpcTuOoyy BfLcGdO5P0AQ6PIac43BtIDuYSs/4hUCub6b/1qm3jVY6Cl10mUnysNOOga4rWAjiZ hbFUGdJoyTPfWOQqDcC3LgGRsNeDeYlXHgyrLXz1QBt+IVufyf2HS3e0XDIzlb5b6H sfhaR2zwOG3CtL3ytgAYMtKycc3Q2SY1RFWPKeruJU4V6n1ZsfsBsOgABt27+zrAiA Bzr7RRH8lryaQ== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v3 10/10] btrfs: add tracepoints for extent map shrinker events Date: Tue, 16 Apr 2024 14:08:12 +0100 Message-Id: <1f936e6053adef193d57f9ca87c68797c88fae1e.1713267925.git.fdmanana@suse.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-btrfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Filipe Manana Add some tracepoints for the extent map shrinker to help debug and analyse main events. These have proved useful during development of the shrinker. Signed-off-by: Filipe Manana Reviewed-by: Josef Bacik Reviewed-by: Johannes Thumshirn --- fs/btrfs/extent_map.c | 13 +++++ fs/btrfs/super.c | 5 +- include/trace/events/btrfs.h | 99 ++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index b638d87db500..2967b3d78399 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -1080,6 +1080,7 @@ static long btrfs_scan_inode(struct btrfs_inode *inode, long *scanned, long nr_t btrfs_set_inode_full_sync(inode); remove_extent_mapping(inode, em); + trace_btrfs_extent_map_shrinker_remove_em(inode, em); /* Drop the reference for the tree. */ free_extent_map(em); nr_dropped++; @@ -1152,6 +1153,12 @@ long btrfs_free_extent_maps(struct btrfs_fs_info *fs_info, long nr_to_scan) long nr_dropped = 0; long scanned = 0; + if (trace_btrfs_extent_map_shrinker_scan_enter_enabled()) { + s64 nr = percpu_counter_sum_positive(&fs_info->evictable_extent_maps); + + trace_btrfs_extent_map_shrinker_scan_enter(fs_info, nr_to_scan, nr); + } + while (scanned < nr_to_scan) { struct btrfs_root *root; unsigned long count; @@ -1183,5 +1190,11 @@ long btrfs_free_extent_maps(struct btrfs_fs_info *fs_info, long nr_to_scan) btrfs_put_root(root); } + if (trace_btrfs_extent_map_shrinker_scan_exit_enabled()) { + s64 nr = percpu_counter_sum_positive(&fs_info->evictable_extent_maps); + + trace_btrfs_extent_map_shrinker_scan_exit(fs_info, nr_dropped, nr); + } + return nr_dropped; } diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index a3877e65d3b5..670914835d8a 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -2377,8 +2377,11 @@ static int btrfs_show_devname(struct seq_file *m, struct dentry *root) static long btrfs_nr_cached_objects(struct super_block *sb, struct shrink_control *sc) { struct btrfs_fs_info *fs_info = btrfs_sb(sb); + const s64 nr = percpu_counter_sum_positive(&fs_info->evictable_extent_maps); - return percpu_counter_sum_positive(&fs_info->evictable_extent_maps); + trace_btrfs_extent_map_shrinker_count(fs_info, nr); + + return nr; } static long btrfs_free_cached_objects(struct super_block *sb, struct shrink_control *sc) diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h index 8f2497603cb5..d2d94d7c3fb5 100644 --- a/include/trace/events/btrfs.h +++ b/include/trace/events/btrfs.h @@ -2537,6 +2537,105 @@ TRACE_EVENT(btrfs_get_raid_extent_offset, __entry->devid) ); +TRACE_EVENT(btrfs_extent_map_shrinker_count, + + TP_PROTO(const struct btrfs_fs_info *fs_info, long nr), + + TP_ARGS(fs_info, nr), + + TP_STRUCT__entry_btrfs( + __field( long, nr ) + ), + + TP_fast_assign_btrfs(fs_info, + __entry->nr = nr; + ), + + TP_printk_btrfs("nr=%ld", __entry->nr) +); + +TRACE_EVENT(btrfs_extent_map_shrinker_scan_enter, + + TP_PROTO(const struct btrfs_fs_info *fs_info, long nr_to_scan, long nr), + + TP_ARGS(fs_info, nr_to_scan, nr), + + TP_STRUCT__entry_btrfs( + __field( long, nr_to_scan ) + __field( long, nr ) + __field( u64, last_root_id ) + __field( u64, last_ino ) + ), + + TP_fast_assign_btrfs(fs_info, + __entry->nr_to_scan = nr_to_scan; + __entry->nr = nr; + __entry->last_root_id = fs_info->extent_map_shrinker_last_root; + __entry->last_ino = fs_info->extent_map_shrinker_last_ino; + ), + + TP_printk_btrfs("nr_to_scan=%ld nr=%ld last_root=%llu(%s) last_ino=%llu", + __entry->nr_to_scan, __entry->nr, + show_root_type(__entry->last_root_id), __entry->last_ino) +); + +TRACE_EVENT(btrfs_extent_map_shrinker_scan_exit, + + TP_PROTO(const struct btrfs_fs_info *fs_info, long nr_dropped, long nr), + + TP_ARGS(fs_info, nr_dropped, nr), + + TP_STRUCT__entry_btrfs( + __field( long, nr_dropped ) + __field( long, nr ) + __field( u64, last_root_id ) + __field( u64, last_ino ) + ), + + TP_fast_assign_btrfs(fs_info, + __entry->nr_dropped = nr_dropped; + __entry->nr = nr; + __entry->last_root_id = fs_info->extent_map_shrinker_last_root; + __entry->last_ino = fs_info->extent_map_shrinker_last_ino; + ), + + TP_printk_btrfs("nr_dropped=%ld nr=%ld last_root=%llu(%s) last_ino=%llu", + __entry->nr_dropped, __entry->nr, + show_root_type(__entry->last_root_id), __entry->last_ino) +); + +TRACE_EVENT(btrfs_extent_map_shrinker_remove_em, + + TP_PROTO(const struct btrfs_inode *inode, const struct extent_map *em), + + TP_ARGS(inode, em), + + TP_STRUCT__entry_btrfs( + __field( u64, ino ) + __field( u64, root_id ) + __field( u64, start ) + __field( u64, len ) + __field( u64, block_start ) + __field( u32, flags ) + ), + + TP_fast_assign_btrfs(inode->root->fs_info, + __entry->ino = btrfs_ino(inode); + __entry->root_id = inode->root->root_key.objectid; + __entry->start = em->start; + __entry->len = em->len; + __entry->block_start = em->block_start; + __entry->flags = em->flags; + ), + + TP_printk_btrfs( +"ino=%llu root=%llu(%s) start=%llu len=%llu block_start=%llu(%s) flags=%s", + __entry->ino, show_root_type(__entry->root_id), + __entry->start, __entry->len, + show_map_type(__entry->block_start), + show_map_flags(__entry->flags)) +); + #endif /* _TRACE_BTRFS_H */ /* This part must be outside protection */