From patchwork Thu Apr 11 16:18:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13626363 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 3260F17B51F for ; Thu, 11 Apr 2024 16:19: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=1712852357; cv=none; b=ivvKvztcmI3mE6ieNsSjsc7L81/6pj03L1fRy6pBKwcxjJUjsgwuIlS2RFpqttOjZEOu0oBWAi1vPNnbbqy9tIRekheEKNimFggjKDaN4cfIM5wphCxR9BDHWoSBJ0ozHgkCr7M/V0uHX1DLvbhfZH2bt26XV3sWp50sqBhPzFM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712852357; c=relaxed/simple; bh=Du1XmvhhU+hwU0pYyS6CHZEkaD0eg4tPGLHcf8JXZiM=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tlHeuw+W1wG5nZGgHs0oNPxvErT3+YGUanuN04dQ0+87pzDg3S6Pg6pepwFz/CBXlRpxsSdClBaSmcp39Rl+66OMFBmQx1r3pssqI5HLe0AJLODEqvX8V8fA4uc5UJsHk8MhAgRiYHVH8aGUHRtWB/NB9ae/fCnpyfcCnOeIUCA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WfnSl5+6; 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="WfnSl5+6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1298BC113CD for ; Thu, 11 Apr 2024 16:19:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712852356; bh=Du1XmvhhU+hwU0pYyS6CHZEkaD0eg4tPGLHcf8JXZiM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=WfnSl5+6syvjnfpWSBQQLgiO3M3PTi3/LyP/n9S5JcYwh4MDeP10iToD0E7pbp5nt CvaTeDSDgZH7nujjBb8O9jROVo6TICnNRJCNe8/GgFw0hPTx4oJ2GShDLrqTBjhH8u 1m1GQESfSjas31Wn+HaDPyASYhwn64dgupboSxBA67smF2H785Rf/1hboW3b9huARS WCcmY3zQA1EHcYwB/jFZD3wmuhf57VCndJGTrOf4GcJMGcnJ3Q0GJTWjOSGIsiQYfE 3RzrtU62x2GbPgcY/YUKdX6lAjJIrjyar0CcwNj5e1iay0jBwxaMQjcn8PnWP0EpOa hsb2Dfs60Bb2Q== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 01/15] btrfs: pass an inode to btrfs_add_extent_mapping() Date: Thu, 11 Apr 2024 17:18:55 +0100 Message-Id: <5d73f6d4be625596575dbd2ba50d71ddc6546c40.1712837044.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 Instead of passing fs_info and extent map tree arguments to btrfs_add_extent_mapping(), we can pass an inode instead, as extent maps are always inserted in the extent map tree of an inode, and the fs_info can be extracted from the inode (inode->root->fs_info). The only exception is in the self tests where we allocate an extent map tree and then use it to insert/update/remove extent maps. However the tests can be changed to use a test inode and then use the inode's extent map tree. So change btrfs_add_extent_mapping() to have an inode as an argument instead of a fs_info and an extent map tree. This reduces the number of parameters and will also be needed for an upcoming change. Reviewed-by: Qu Wenruo Signed-off-by: Filipe Manana --- fs/btrfs/extent_map.c | 14 +-- fs/btrfs/extent_map.h | 3 +- fs/btrfs/inode.c | 2 +- fs/btrfs/tests/extent-map-tests.c | 174 +++++++++++++++--------------- 4 files changed, 95 insertions(+), 98 deletions(-) diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 471654cb65b0..840be23d2c0a 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -546,10 +546,9 @@ static noinline int merge_extent_mapping(struct extent_map_tree *em_tree, } /* - * Add extent mapping into em_tree. + * Add extent mapping into an inode's extent map tree. * - * @fs_info: the filesystem - * @em_tree: extent tree into which we want to insert the extent mapping + * @inode: target inode * @em_in: extent we are inserting * @start: start of the logical range btrfs_get_extent() is requesting * @len: length of the logical range btrfs_get_extent() is requesting @@ -557,8 +556,8 @@ static noinline int merge_extent_mapping(struct extent_map_tree *em_tree, * Note that @em_in's range may be different from [start, start+len), * but they must be overlapped. * - * Insert @em_in into @em_tree. In case there is an overlapping range, handle - * the -EEXIST by either: + * Insert @em_in into the inode's extent map tree. In case there is an + * overlapping range, handle the -EEXIST by either: * a) Returning the existing extent in @em_in if @start is within the * existing em. * b) Merge the existing extent with @em_in passed in. @@ -566,12 +565,13 @@ static noinline int merge_extent_mapping(struct extent_map_tree *em_tree, * Return 0 on success, otherwise -EEXIST. * */ -int btrfs_add_extent_mapping(struct btrfs_fs_info *fs_info, - struct extent_map_tree *em_tree, +int btrfs_add_extent_mapping(struct btrfs_inode *inode, struct extent_map **em_in, u64 start, u64 len) { 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; /* * Tree-checker should have rejected any inline extent with non-zero diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index 10e9491865c9..f287ab46e368 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h @@ -132,8 +132,7 @@ 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); struct extent_map *search_extent_mapping(struct extent_map_tree *tree, u64 start, u64 len); -int btrfs_add_extent_mapping(struct btrfs_fs_info *fs_info, - struct extent_map_tree *em_tree, +int btrfs_add_extent_mapping(struct btrfs_inode *inode, struct extent_map **em_in, u64 start, u64 len); void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end, diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 1a1a4b6d33ed..d4539b4b8148 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6992,7 +6992,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode, } write_lock(&em_tree->lock); - ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, start, len); + ret = btrfs_add_extent_mapping(inode, &em, start, len); write_unlock(&em_tree->lock); out: btrfs_free_path(path); diff --git a/fs/btrfs/tests/extent-map-tests.c b/fs/btrfs/tests/extent-map-tests.c index 253cce7ffecf..96089c4c38a5 100644 --- a/fs/btrfs/tests/extent-map-tests.c +++ b/fs/btrfs/tests/extent-map-tests.c @@ -53,9 +53,9 @@ static void free_extent_map_tree(struct extent_map_tree *em_tree) * ->add_extent_mapping(0, 16K) * -> #handle -EEXIST */ -static int test_case_1(struct btrfs_fs_info *fs_info, - struct extent_map_tree *em_tree) +static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) { + struct extent_map_tree *em_tree = &inode->extent_tree; struct extent_map *em; u64 start = 0; u64 len = SZ_8K; @@ -73,7 +73,7 @@ static int test_case_1(struct btrfs_fs_info *fs_info, em->block_start = 0; em->block_len = SZ_16K; write_lock(&em_tree->lock); - ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len); + ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len); write_unlock(&em_tree->lock); if (ret < 0) { test_err("cannot add extent range [0, 16K)"); @@ -94,7 +94,7 @@ static int test_case_1(struct btrfs_fs_info *fs_info, em->block_start = SZ_32K; /* avoid merging */ em->block_len = SZ_4K; write_lock(&em_tree->lock); - ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len); + ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len); write_unlock(&em_tree->lock); if (ret < 0) { test_err("cannot add extent range [16K, 20K)"); @@ -115,7 +115,7 @@ static int test_case_1(struct btrfs_fs_info *fs_info, em->block_start = start; em->block_len = len; write_lock(&em_tree->lock); - ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len); + ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len); write_unlock(&em_tree->lock); if (ret) { test_err("case1 [%llu %llu]: ret %d", start, start + len, ret); @@ -148,9 +148,9 @@ static int test_case_1(struct btrfs_fs_info *fs_info, * Reading the inline ending up with EEXIST, ie. read an inline * extent and discard page cache and read it again. */ -static int test_case_2(struct btrfs_fs_info *fs_info, - struct extent_map_tree *em_tree) +static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) { + struct extent_map_tree *em_tree = &inode->extent_tree; struct extent_map *em; int ret; @@ -166,7 +166,7 @@ static int test_case_2(struct btrfs_fs_info *fs_info, em->block_start = EXTENT_MAP_INLINE; em->block_len = (u64)-1; write_lock(&em_tree->lock); - ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len); + ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len); write_unlock(&em_tree->lock); if (ret < 0) { test_err("cannot add extent range [0, 1K)"); @@ -187,7 +187,7 @@ static int test_case_2(struct btrfs_fs_info *fs_info, em->block_start = SZ_4K; em->block_len = SZ_4K; write_lock(&em_tree->lock); - ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len); + ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len); write_unlock(&em_tree->lock); if (ret < 0) { test_err("cannot add extent range [4K, 8K)"); @@ -208,7 +208,7 @@ static int test_case_2(struct btrfs_fs_info *fs_info, em->block_start = EXTENT_MAP_INLINE; em->block_len = (u64)-1; write_lock(&em_tree->lock); - ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len); + ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len); write_unlock(&em_tree->lock); if (ret) { test_err("case2 [0 1K]: ret %d", ret); @@ -235,8 +235,9 @@ static int test_case_2(struct btrfs_fs_info *fs_info, } static int __test_case_3(struct btrfs_fs_info *fs_info, - struct extent_map_tree *em_tree, u64 start) + struct btrfs_inode *inode, u64 start) { + struct extent_map_tree *em_tree = &inode->extent_tree; struct extent_map *em; u64 len = SZ_4K; int ret; @@ -253,7 +254,7 @@ static int __test_case_3(struct btrfs_fs_info *fs_info, em->block_start = SZ_4K; em->block_len = SZ_4K; write_lock(&em_tree->lock); - ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len); + ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len); write_unlock(&em_tree->lock); if (ret < 0) { test_err("cannot add extent range [4K, 8K)"); @@ -274,7 +275,7 @@ static int __test_case_3(struct btrfs_fs_info *fs_info, em->block_start = 0; em->block_len = SZ_16K; write_lock(&em_tree->lock); - ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, start, len); + ret = btrfs_add_extent_mapping(inode, &em, start, len); write_unlock(&em_tree->lock); if (ret) { test_err("case3 [%llu %llu): ret %d", @@ -322,25 +323,25 @@ static int __test_case_3(struct btrfs_fs_info *fs_info, * -> add_extent_mapping() * -> add_extent_mapping() */ -static int test_case_3(struct btrfs_fs_info *fs_info, - struct extent_map_tree *em_tree) +static int test_case_3(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) { int ret; - ret = __test_case_3(fs_info, em_tree, 0); + ret = __test_case_3(fs_info, inode, 0); if (ret) return ret; - ret = __test_case_3(fs_info, em_tree, SZ_8K); + ret = __test_case_3(fs_info, inode, SZ_8K); if (ret) return ret; - ret = __test_case_3(fs_info, em_tree, (12 * SZ_1K)); + ret = __test_case_3(fs_info, inode, (12 * SZ_1K)); return ret; } static int __test_case_4(struct btrfs_fs_info *fs_info, - struct extent_map_tree *em_tree, u64 start) + struct btrfs_inode *inode, u64 start) { + struct extent_map_tree *em_tree = &inode->extent_tree; struct extent_map *em; u64 len = SZ_4K; int ret; @@ -357,7 +358,7 @@ static int __test_case_4(struct btrfs_fs_info *fs_info, em->block_start = 0; em->block_len = SZ_8K; write_lock(&em_tree->lock); - ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len); + ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len); write_unlock(&em_tree->lock); if (ret < 0) { test_err("cannot add extent range [0, 8K)"); @@ -378,7 +379,7 @@ static int __test_case_4(struct btrfs_fs_info *fs_info, em->block_start = SZ_16K; /* avoid merging */ em->block_len = 24 * SZ_1K; write_lock(&em_tree->lock); - ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len); + ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len); write_unlock(&em_tree->lock); if (ret < 0) { test_err("cannot add extent range [8K, 32K)"); @@ -398,7 +399,7 @@ static int __test_case_4(struct btrfs_fs_info *fs_info, em->block_start = 0; em->block_len = SZ_32K; write_lock(&em_tree->lock); - ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, start, len); + ret = btrfs_add_extent_mapping(inode, &em, start, len); write_unlock(&em_tree->lock); if (ret) { test_err("case4 [%llu %llu): ret %d", @@ -450,23 +451,22 @@ static int __test_case_4(struct btrfs_fs_info *fs_info, * # handle -EEXIST when adding * # [0, 32K) */ -static int test_case_4(struct btrfs_fs_info *fs_info, - struct extent_map_tree *em_tree) +static int test_case_4(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) { int ret; - ret = __test_case_4(fs_info, em_tree, 0); + ret = __test_case_4(fs_info, inode, 0); if (ret) return ret; - ret = __test_case_4(fs_info, em_tree, SZ_4K); + ret = __test_case_4(fs_info, inode, SZ_4K); return ret; } -static int add_compressed_extent(struct btrfs_fs_info *fs_info, - struct extent_map_tree *em_tree, +static int add_compressed_extent(struct btrfs_inode *inode, u64 start, u64 len, u64 block_start) { + struct extent_map_tree *em_tree = &inode->extent_tree; struct extent_map *em; int ret; @@ -482,7 +482,7 @@ static int add_compressed_extent(struct btrfs_fs_info *fs_info, em->block_len = SZ_4K; em->flags |= EXTENT_FLAG_COMPRESS_ZLIB; write_lock(&em_tree->lock); - ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len); + ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len); write_unlock(&em_tree->lock); free_extent_map(em); if (ret < 0) { @@ -588,53 +588,43 @@ static int validate_range(struct extent_map_tree *em_tree, int index) * They'll have the EXTENT_FLAG_COMPRESSED flag set to keep the em tree from * merging the em's. */ -static int test_case_5(struct btrfs_fs_info *fs_info) +static int test_case_5(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) { - struct extent_map_tree *em_tree; - struct inode *inode; u64 start, end; int ret; test_msg("Running btrfs_drop_extent_map_range tests"); - inode = btrfs_new_test_inode(); - if (!inode) { - test_std_err(TEST_ALLOC_INODE); - return -ENOMEM; - } - - em_tree = &BTRFS_I(inode)->extent_tree; - /* [0, 12k) */ - ret = add_compressed_extent(fs_info, em_tree, 0, SZ_4K * 3, 0); + ret = add_compressed_extent(inode, 0, SZ_4K * 3, 0); if (ret) { test_err("cannot add extent range [0, 12K)"); goto out; } /* [12k, 24k) */ - ret = add_compressed_extent(fs_info, em_tree, SZ_4K * 3, SZ_4K * 3, SZ_4K); + ret = add_compressed_extent(inode, SZ_4K * 3, SZ_4K * 3, SZ_4K); if (ret) { test_err("cannot add extent range [12k, 24k)"); goto out; } /* [24k, 36k) */ - ret = add_compressed_extent(fs_info, em_tree, SZ_4K * 6, SZ_4K * 3, SZ_8K); + ret = add_compressed_extent(inode, SZ_4K * 6, SZ_4K * 3, SZ_8K); if (ret) { test_err("cannot add extent range [12k, 24k)"); goto out; } /* [36k, 40k) */ - ret = add_compressed_extent(fs_info, em_tree, SZ_32K + SZ_4K, SZ_4K, SZ_4K * 3); + ret = add_compressed_extent(inode, SZ_32K + SZ_4K, SZ_4K, SZ_4K * 3); if (ret) { test_err("cannot add extent range [12k, 24k)"); goto out; } /* [40k, 64k) */ - ret = add_compressed_extent(fs_info, em_tree, SZ_4K * 10, SZ_4K * 6, SZ_16K); + ret = add_compressed_extent(inode, SZ_4K * 10, SZ_4K * 6, SZ_16K); if (ret) { test_err("cannot add extent range [12k, 24k)"); goto out; @@ -643,36 +633,36 @@ static int test_case_5(struct btrfs_fs_info *fs_info) /* Drop [8k, 12k) */ start = SZ_8K; end = (3 * SZ_4K) - 1; - btrfs_drop_extent_map_range(BTRFS_I(inode), start, end, false); - ret = validate_range(&BTRFS_I(inode)->extent_tree, 0); + btrfs_drop_extent_map_range(inode, start, end, false); + ret = validate_range(&inode->extent_tree, 0); if (ret) goto out; /* Drop [12k, 20k) */ start = SZ_4K * 3; end = SZ_16K + SZ_4K - 1; - btrfs_drop_extent_map_range(BTRFS_I(inode), start, end, false); - ret = validate_range(&BTRFS_I(inode)->extent_tree, 1); + btrfs_drop_extent_map_range(inode, start, end, false); + ret = validate_range(&inode->extent_tree, 1); if (ret) goto out; /* Drop [28k, 32k) */ start = SZ_32K - SZ_4K; end = SZ_32K - 1; - btrfs_drop_extent_map_range(BTRFS_I(inode), start, end, false); - ret = validate_range(&BTRFS_I(inode)->extent_tree, 2); + btrfs_drop_extent_map_range(inode, start, end, false); + ret = validate_range(&inode->extent_tree, 2); if (ret) goto out; /* Drop [32k, 64k) */ start = SZ_32K; end = SZ_64K - 1; - btrfs_drop_extent_map_range(BTRFS_I(inode), start, end, false); - ret = validate_range(&BTRFS_I(inode)->extent_tree, 3); + btrfs_drop_extent_map_range(inode, start, end, false); + ret = validate_range(&inode->extent_tree, 3); if (ret) goto out; out: - iput(inode); + free_extent_map_tree(&inode->extent_tree); return ret; } @@ -681,23 +671,25 @@ static int test_case_5(struct btrfs_fs_info *fs_info) * for areas between two existing ems. Validate it doesn't do this when there * are two unmerged em's side by side. */ -static int test_case_6(struct btrfs_fs_info *fs_info, struct extent_map_tree *em_tree) +static int test_case_6(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) { + struct extent_map_tree *em_tree = &inode->extent_tree; struct extent_map *em = NULL; int ret; - ret = add_compressed_extent(fs_info, em_tree, 0, SZ_4K, 0); + ret = add_compressed_extent(inode, 0, SZ_4K, 0); if (ret) goto out; - ret = add_compressed_extent(fs_info, em_tree, SZ_4K, SZ_4K, 0); + ret = add_compressed_extent(inode, SZ_4K, SZ_4K, 0); if (ret) goto out; em = alloc_extent_map(); if (!em) { test_std_err(TEST_ALLOC_EXTENT_MAP); - return -ENOMEM; + ret = -ENOMEM; + goto out; } em->start = SZ_4K; @@ -705,7 +697,7 @@ static int test_case_6(struct btrfs_fs_info *fs_info, struct extent_map_tree *em em->block_start = SZ_16K; em->block_len = SZ_16K; write_lock(&em_tree->lock); - ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, 0, SZ_8K); + ret = btrfs_add_extent_mapping(inode, &em, 0, SZ_8K); write_unlock(&em_tree->lock); if (ret != 0) { @@ -734,28 +726,19 @@ static int test_case_6(struct btrfs_fs_info *fs_info, struct extent_map_tree *em * true would mess up the start/end calculations and subsequent splits would be * incorrect. */ -static int test_case_7(struct btrfs_fs_info *fs_info) +static int test_case_7(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) { - struct extent_map_tree *em_tree; + struct extent_map_tree *em_tree = &inode->extent_tree; struct extent_map *em; - struct inode *inode; int ret; + int ret2; test_msg("Running btrfs_drop_extent_cache with pinned"); - inode = btrfs_new_test_inode(); - if (!inode) { - test_std_err(TEST_ALLOC_INODE); - return -ENOMEM; - } - - em_tree = &BTRFS_I(inode)->extent_tree; - em = alloc_extent_map(); if (!em) { test_std_err(TEST_ALLOC_EXTENT_MAP); - ret = -ENOMEM; - goto out; + return -ENOMEM; } /* [0, 16K), pinned */ @@ -765,7 +748,7 @@ static int test_case_7(struct btrfs_fs_info *fs_info) em->block_len = SZ_4K; em->flags |= EXTENT_FLAG_PINNED; write_lock(&em_tree->lock); - ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len); + ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len); write_unlock(&em_tree->lock); if (ret < 0) { test_err("couldn't add extent map"); @@ -786,7 +769,7 @@ static int test_case_7(struct btrfs_fs_info *fs_info) em->block_start = SZ_32K; em->block_len = SZ_16K; write_lock(&em_tree->lock); - ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len); + ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len); write_unlock(&em_tree->lock); if (ret < 0) { test_err("couldn't add extent map"); @@ -798,7 +781,7 @@ static int test_case_7(struct btrfs_fs_info *fs_info) * Drop [0, 36K) This should skip the [0, 4K) extent and then split the * [32K, 48K) extent. */ - btrfs_drop_extent_map_range(BTRFS_I(inode), 0, (36 * SZ_1K) - 1, true); + btrfs_drop_extent_map_range(inode, 0, (36 * SZ_1K) - 1, true); /* Make sure our extent maps look sane. */ ret = -EINVAL; @@ -860,7 +843,11 @@ static int test_case_7(struct btrfs_fs_info *fs_info) ret = 0; out: free_extent_map(em); - iput(inode); + /* Unpin our extent to prevent warning when removing it below. */ + ret2 = unpin_extent_cache(inode, 0, SZ_16K, 0); + if (ret == 0) + ret = ret2; + free_extent_map_tree(em_tree); return ret; } @@ -954,7 +941,8 @@ static int test_rmap_block(struct btrfs_fs_info *fs_info, int btrfs_test_extent_map(void) { struct btrfs_fs_info *fs_info = NULL; - struct extent_map_tree *em_tree; + struct inode *inode; + struct btrfs_root *root = NULL; int ret = 0, i; struct rmap_test_vector rmap_tests[] = { { @@ -1003,33 +991,42 @@ int btrfs_test_extent_map(void) return -ENOMEM; } - em_tree = kzalloc(sizeof(*em_tree), GFP_KERNEL); - if (!em_tree) { + inode = btrfs_new_test_inode(); + if (!inode) { + test_std_err(TEST_ALLOC_INODE); ret = -ENOMEM; goto out; } - extent_map_tree_init(em_tree); + root = btrfs_alloc_dummy_root(fs_info); + if (IS_ERR(root)) { + test_std_err(TEST_ALLOC_ROOT); + ret = PTR_ERR(root); + root = NULL; + goto out; + } - ret = test_case_1(fs_info, em_tree); + BTRFS_I(inode)->root = root; + + ret = test_case_1(fs_info, BTRFS_I(inode)); if (ret) goto out; - ret = test_case_2(fs_info, em_tree); + ret = test_case_2(fs_info, BTRFS_I(inode)); if (ret) goto out; - ret = test_case_3(fs_info, em_tree); + ret = test_case_3(fs_info, BTRFS_I(inode)); if (ret) goto out; - ret = test_case_4(fs_info, em_tree); + ret = test_case_4(fs_info, BTRFS_I(inode)); if (ret) goto out; - ret = test_case_5(fs_info); + ret = test_case_5(fs_info, BTRFS_I(inode)); if (ret) goto out; - ret = test_case_6(fs_info, em_tree); + ret = test_case_6(fs_info, BTRFS_I(inode)); if (ret) goto out; - ret = test_case_7(fs_info); + ret = test_case_7(fs_info, BTRFS_I(inode)); if (ret) goto out; @@ -1041,7 +1038,8 @@ int btrfs_test_extent_map(void) } out: - kfree(em_tree); + iput(inode); + btrfs_free_dummy_root(root); btrfs_free_dummy_fs_info(fs_info); return ret; From patchwork Thu Apr 11 16:18:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13626364 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 2706317BB2C for ; Thu, 11 Apr 2024 16:19: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=1712852358; cv=none; b=cdATf+vY3DZY+i97QttgO5MwkhJvgTl6IJpVxvTFqZrK/aavdM8ys+F2LHkcF8Su21pETE73PWbPRkJszlFNwNzGFHRE6/9JS9gqJA6lwA3cmMQeD7G65dYiAg3uWCEhiAJ8LctgwoLQF1vU5IFAReGvQnT4T1HeTSZPJIpJ4I4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712852358; c=relaxed/simple; bh=ElXTtYwr0evUF7MEkZ4QqAbDqJ+GbVZQhjOcpVi3h3A=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=q34PNh6I6h/ub1g3gBIO0pF2tKWavQ0/sBDNfS3QPusYtBinNgZZ5YdUKviPKVca91Caz4JyTYpuYqQJgqHmcMn3apnQnh6D27ncAPMWf2/qMyKi/OlGq56JMDCdOu4dTO9hKm8pPzC+1q1Q9PUYOzn/6cV5Fcic54Pi9jtgEws= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hli1Oxg4; 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="hli1Oxg4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 191B1C072AA for ; Thu, 11 Apr 2024 16:19:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712852357; bh=ElXTtYwr0evUF7MEkZ4QqAbDqJ+GbVZQhjOcpVi3h3A=; h=From:To:Subject:Date:In-Reply-To:References:From; b=hli1Oxg4a0H4ZZTUL9D5CAy/s0g70VddUGC3REtZybdYw0F+7/67hxErw3D0/jitN 8mOFZL0LyWuwe62gqGjAsQY67Wm8mG4GjXJafeOtgem9Cf6EUSopKI2m/3yqaBR7OW 8DDZ52dhUZzQB96zbKDIAPKOiqgEcZvE3ZSKsSiWlyC/32d3Nzt4wNCChfpCiV/6Ni x+D1Oa9PUcZf3kJarrKiqCYv8Y/4l1HaWUl0gh4otxnwSFGHDyluZmAAITafyukK7H u/hggojpVh0U1vlJY5nQCN6YO7jpOl9SW4BNqhOK2Kgj6/2TBOxVy5TjMHSWzjwWHn Uhn9vj6jIavWA== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 02/15] btrfs: tests: error out on unexpected extent map reference count Date: Thu, 11 Apr 2024 17:18:56 +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 In the extent map self tests, when freeing all extent maps from a test extent map tree we are not expecting to find any extent map with a reference count different from 1 (the tree reference). If we find any, we just log a message but we don't fail the test, which makes it very easy to miss any bug/regression - no one reads the test messages unless a test fails. So change the behaviour to make a test fail if we find an extent map in the tree with a reference count different from 1. Make the failure happen only after removing all extent maps, so that we don't leak memory. Reviewed-by: Qu Wenruo Signed-off-by: Filipe Manana --- fs/btrfs/tests/extent-map-tests.c | 43 +++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/fs/btrfs/tests/extent-map-tests.c b/fs/btrfs/tests/extent-map-tests.c index 96089c4c38a5..9e9cb591c0f1 100644 --- a/fs/btrfs/tests/extent-map-tests.c +++ b/fs/btrfs/tests/extent-map-tests.c @@ -11,10 +11,11 @@ #include "../disk-io.h" #include "../block-group.h" -static void free_extent_map_tree(struct extent_map_tree *em_tree) +static int free_extent_map_tree(struct extent_map_tree *em_tree) { struct extent_map *em; struct rb_node *node; + int ret = 0; write_lock(&em_tree->lock); while (!RB_EMPTY_ROOT(&em_tree->map.rb_root)) { @@ -24,6 +25,7 @@ static void free_extent_map_tree(struct extent_map_tree *em_tree) #ifdef CONFIG_BTRFS_DEBUG if (refcount_read(&em->refs) != 1) { + ret = -EINVAL; test_err( "em leak: em (start %llu len %llu block_start %llu block_len %llu) refs %d", em->start, em->len, em->block_start, @@ -35,6 +37,8 @@ static void free_extent_map_tree(struct extent_map_tree *em_tree) free_extent_map(em); } write_unlock(&em_tree->lock); + + return ret; } /* @@ -60,6 +64,7 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) u64 start = 0; u64 len = SZ_8K; int ret; + int ret2; em = alloc_extent_map(); if (!em) { @@ -137,7 +142,9 @@ static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) } free_extent_map(em); out: - free_extent_map_tree(em_tree); + ret2 = free_extent_map_tree(em_tree); + if (ret == 0) + ret = ret2; return ret; } @@ -153,6 +160,7 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) struct extent_map_tree *em_tree = &inode->extent_tree; struct extent_map *em; int ret; + int ret2; em = alloc_extent_map(); if (!em) { @@ -229,7 +237,9 @@ static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) } free_extent_map(em); out: - free_extent_map_tree(em_tree); + ret2 = free_extent_map_tree(em_tree); + if (ret == 0) + ret = ret2; return ret; } @@ -241,6 +251,7 @@ static int __test_case_3(struct btrfs_fs_info *fs_info, struct extent_map *em; u64 len = SZ_4K; int ret; + int ret2; em = alloc_extent_map(); if (!em) { @@ -302,7 +313,9 @@ static int __test_case_3(struct btrfs_fs_info *fs_info, } free_extent_map(em); out: - free_extent_map_tree(em_tree); + ret2 = free_extent_map_tree(em_tree); + if (ret == 0) + ret = ret2; return ret; } @@ -345,6 +358,7 @@ static int __test_case_4(struct btrfs_fs_info *fs_info, struct extent_map *em; u64 len = SZ_4K; int ret; + int ret2; em = alloc_extent_map(); if (!em) { @@ -421,7 +435,9 @@ static int __test_case_4(struct btrfs_fs_info *fs_info, } free_extent_map(em); out: - free_extent_map_tree(em_tree); + ret2 = free_extent_map_tree(em_tree); + if (ret == 0) + ret = ret2; return ret; } @@ -592,6 +608,7 @@ static int test_case_5(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) { u64 start, end; int ret; + int ret2; test_msg("Running btrfs_drop_extent_map_range tests"); @@ -662,7 +679,10 @@ static int test_case_5(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) if (ret) goto out; out: - free_extent_map_tree(&inode->extent_tree); + ret2 = free_extent_map_tree(&inode->extent_tree); + if (ret == 0) + ret = ret2; + return ret; } @@ -676,6 +696,7 @@ static int test_case_6(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) struct extent_map_tree *em_tree = &inode->extent_tree; struct extent_map *em = NULL; int ret; + int ret2; ret = add_compressed_extent(inode, 0, SZ_4K, 0); if (ret) @@ -717,7 +738,10 @@ static int test_case_6(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode) ret = 0; out: free_extent_map(em); - free_extent_map_tree(em_tree); + ret2 = free_extent_map_tree(em_tree); + if (ret == 0) + ret = ret2; + return ret; } @@ -847,7 +871,10 @@ 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; - free_extent_map_tree(em_tree); + ret2 = free_extent_map_tree(em_tree); + if (ret == 0) + ret = ret2; + return ret; } From patchwork Thu Apr 11 16:18:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13626365 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 2F8351802C5 for ; Thu, 11 Apr 2024 16:19: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=1712852359; cv=none; b=I9Ooj9FJ8U1HRka098Pjz5Xq7dL1N2jGAN4JuxHYprERfPAiTERV62KcCmHcZJHYFT1IvNreABiWNsUgsT8wtxD5cinfsboN5jjrSPgvd43/RMDOzFjVmEPvqSTRId/m4/HmIZS0GKgjyXcJygyTXJf6IDwWI5h7K9r1J54h0k4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712852359; c=relaxed/simple; bh=focZnBDtmmUYi/Uho+3AOABt2zAcbR+hASsQDbTj3KA=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=OMlFWsr7aLMzFfhmJ9T7Zu7pKxiZsAQ39pQUnUmkiE+uwnrn23/GToGLkamF0GsvIP1DO9F85FY721DfI4O+Pz9HuFSfpPpomz1ojlW/nmAO0ZGyQtK8Y3p8vdfpGoUq43cST0nK1Ui3ScDIOf430DDuDSQ7GoiKKAdYSyyDZmw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iOjfhVN4; 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="iOjfhVN4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1D53AC113CE for ; Thu, 11 Apr 2024 16:19:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712852358; bh=focZnBDtmmUYi/Uho+3AOABt2zAcbR+hASsQDbTj3KA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=iOjfhVN4OwHcKJC01mz70oJbtPh+v+Atf2Kl5EEh9RofouBa8VkVXOQ6Edzw/4zCn RjHbKWKx3Ps0Pi8en6fsCdk2wsQUmsp6VL/5WDPpwsUSnoMwsCWAHbKhevwcpeHhr4 8Cw223XKtJUG06JRuAFGSehnXL1EP/gCnpN8wfA7ROJx1/51v2rW+pOY9eV0VbS/nh jb39XqVC7F6ffMP1BYXeSV7m+Qo8HiOsnx7MmTnX2K1bXRotcDiV/jr1niWfA46P8w MXPTChzUUlppbFikvCFRTesmeGr9XMuRD1o/MVH/BEyk+FeQziCWy2S8vWGbVOmwlV h1DxAR5F+nkgw== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 03/15] btrfs: simplify add_extent_mapping() by removing pointless label Date: Thu, 11 Apr 2024 17:18:57 +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 The add_extent_mapping() function is short and trivial, there's no need to have a label for a quick exit in case of an error, even because there's no error handling needed, we just need to return the error. So remove that label and return directly. Also while at it remove the redundant initialization of 'ret', as that may help avoid some warnings with clang tools such as the one reported/fixed by commit 966de47ff0c9 ("btrfs: remove redundant initialization of variables in log_new_ancestors"). Reviewed-by: Qu Wenruo Signed-off-by: Filipe Manana --- fs/btrfs/extent_map.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 840be23d2c0a..d125d5ab9b1d 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -370,17 +370,17 @@ static inline void setup_extent_mapping(struct extent_map_tree *tree, static int add_extent_mapping(struct extent_map_tree *tree, struct extent_map *em, int modified) { - int ret = 0; + int ret; lockdep_assert_held_write(&tree->lock); ret = tree_insert(&tree->map, em); if (ret) - goto out; + return ret; setup_extent_mapping(tree, em, modified); -out: - return ret; + + return 0; } static struct extent_map * From patchwork Thu Apr 11 16:18:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13626366 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 496A518131D for ; Thu, 11 Apr 2024 16:19: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=1712852360; cv=none; b=A+ttWm+nw6h10kFM9as/M5fVKw7gxlr1gJDqmLwUFVqFrKHraHdFu+/dqNqI70OO3zMvTj8wX8VnBoC8CtN+zdJCG8gHAxz4Ybdj/y9cqI0IRbIZevDSIy/mZNT6NxqnvlQpsdJzWe9xTmYQL9offTsO7fF7CkKVJ1FZfnEyTJQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712852360; c=relaxed/simple; bh=ybJKcvABlDMDGPfu0ASvTAVEtaTvUZ920RS41uamk10=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=OPupO8UNGIxsHKNHpoQpyEMudh9zgm/V7MEIO+8GghyuU6tgGmDK7nnyDtTSnbZdwXOvU3biD3AYo8DZDHrG007QshsE3n8HkGHmzMmLxMegfMG9EWvnj+L98yb+iKHrBvIXuMLTqt881fMKYHTYARW2Vxw/jorUMp/56MhxKME= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bupx62BT; 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="bupx62BT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 22E64C072AA for ; Thu, 11 Apr 2024 16:19:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712852359; bh=ybJKcvABlDMDGPfu0ASvTAVEtaTvUZ920RS41uamk10=; h=From:To:Subject:Date:In-Reply-To:References:From; b=bupx62BT3iej80v4yHpJeIxRnEig5bt0dUPQbOwDcC3QTghWdCrtW0dIOqKumhXXt BpXZlNTlIpws5FbqfUVM4MYjg6uiPE+fJuO41ryOY7RAmqUmzLhXVQZ2Ebm5DBWb7H O39Vh8oWpHsnYEQhSAJlpe1X4RjTFMDsTdLd7zFzZB8jdMcSSrxUw6AjVFes1UriCJ m9x+hS24+3NG7+QCXiBypLUbMKLb3gzbrNJ0UJPuCFWPAB2zFPqNvl3rxPtw6dGiw4 ErVNesiG5dyG2gSVAL3heP6P7bXFb6oDk3HjpLxsQG7PxsTozAyMK62QK0+sz5+cI2 YitysE2nKOs0g== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 04/15] btrfs: pass the extent map tree's inode to add_extent_mapping() Date: Thu, 11 Apr 2024 17:18:58 +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 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 Signed-off-by: Filipe Manana --- 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 Thu Apr 11 16:18:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13626367 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 8FD0617A92C for ; Thu, 11 Apr 2024 16:19: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=1712852361; cv=none; b=oUIHBZTLUFn0ErvwK0YzbW16rOOvHkbdlmsVKuvb2s/EZo4dWhrI1BCoBCQR0I4VviGaMzGgsAYkc4r2+HkHCyAMnFLkKdsFITXk/vKw5as1QZchbeN2Qvis3blsEco+5QiG6QAfNDDs14StVl2rVNANxSs5JrZpfGMfx5VwaSs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712852361; c=relaxed/simple; bh=O0Z5um7QpcTBedjY24YaUsXBJtWtbkRdf9MDiLMcJEI=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=J9quUzAbRhvNwQg63aG3gC/gEosj4vj3cA8zWx5IzphPX/HL+YVnw6pJmlMjQCF2i5ksmrw8+kunvE0tTCMMBFywFfCP4SdhTcn7LKQixy9wmRSObIxsF79ti/GVjEF7eN/4F26FD5g4yIG2xPSldRwLCz4YE2MPQt8MIUEOwKg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VNUUCIhn; 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="VNUUCIhn" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 87733C113CE for ; Thu, 11 Apr 2024 16:19:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712852361; bh=O0Z5um7QpcTBedjY24YaUsXBJtWtbkRdf9MDiLMcJEI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=VNUUCIhnO0vQvdbumcHpMYzRxvBKjaqoVAzfCMrz1T7e0dkO7u3EmhrwHaBj18ibY DIAb/k8J/vEt9gt7Jh/SUlA9mc0xkLL3YO2SyFdfHgNt6PiGxYUyVXcAsdaQFIr5qG mENa1Hg+DBu4HoHly40n+LQIebradvwFvCuA2DUmF1bo3z2ffQwnBYwPy7dI2qAT83 1u0cbxNlNBs2WgpOH206JqS8/ROTv+TDkSVkN1M1HlG+pLzv//YaJWA8ySqlshqwwU tierQenfEYfLSY5pKdfzWPh7JnoSZsFCMTT3PnhH/vD3MbLCoBRnqaXW/syo08aUiZ xzxkYrAslX3lQ== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 05/15] btrfs: pass the extent map tree's inode to clear_em_logging() Date: Thu, 11 Apr 2024 17:18:59 +0100 Message-Id: <90d5c3c334dabaefb26b58488074213840434336.1712837044.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 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 Signed-off-by: Filipe Manana --- 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 d9777649e170..4a4fca841510 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -4945,7 +4945,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; } @@ -4954,7 +4954,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 Thu Apr 11 16:19:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13626368 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 B2A4217A920 for ; Thu, 11 Apr 2024 16:19: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=1712852362; cv=none; b=EnoN5jRl/H3HvMFGp4WBO9jcmBdO39FIUVVKFZE88OwBLXYkLnryva2AYNlBTqtBbX5HR3lHa1AWmxsgIvVPaITKdIFXYggICsBKKRygDZRUeiRMf6cfG4Ign+MRLbuBBSXUfO4GMyoaG2ZwTXwO3oc8k2VqQ3QM+czpAU+55yE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712852362; c=relaxed/simple; bh=tYs55B/TO+QMshxCMeKKXmlZaXCxoxcHaQjEdMD6QG8=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rFxiD8fb1ZmJrLDcYNOwtwSHKyj+wY1/+f9wpwjHEo4TMVo+W0/TH3E3kQkD91fv5tmohXEKi/DA3aXUUqwWkJTwfxN+t4R95IcsRL6Tzwfad0Sc4+uu6BM4ffhI0FroC3uVJhsKicnsfvJcQ3T0QbxPBWBN+afQl5AgN7JdJF4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ekgf/w1F; 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="Ekgf/w1F" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8DDB7C2BBFC for ; Thu, 11 Apr 2024 16:19:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712852362; bh=tYs55B/TO+QMshxCMeKKXmlZaXCxoxcHaQjEdMD6QG8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Ekgf/w1FLIF8mtAhLaFLrB3bhhyXMPVwXEz8yBkRBJw59qnmF1+JN3ri6rmjO4IKE f8pF3kXXkCvHvGbMaLtbjcAPJxw1B7hUZ47iPK11m8ljWRWFKpiVdTyn+Ov4jP5TYB t+fqPruLw4LYqyAo9yLfvGtn43CRql0He+8hKwv9dL8E8PvLgcIddZ9y65jPRH3DOv hcjmGzMr71XBj8mX1NDvdI4XEp8siz4v0PCtRat9+QyaaLzBN21OshYTCMgpv7R7yl bzYWaZm9J9nyw4Oq+crSOM5lJG45N9GU4kI1LWdGFjiyFwGqbeN22AbDlxK7cExzz9 5i7CSVDtgI16w== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 06/15] btrfs: pass the extent map tree's inode to remove_extent_mapping() Date: Thu, 11 Apr 2024 17:19:00 +0100 Message-Id: <86e4cadc222ba2d404afa5d174809f78151d12a4.1712837044.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 Signed-off-by: Filipe Manana --- 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 d90330f26827..1b236fc3f411 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 Thu Apr 11 16:19:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13626369 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 33B161802BC for ; Thu, 11 Apr 2024 16:19: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=1712852364; cv=none; b=jd5+OzAgHJPmFWE2AXTmhAwpk8hFVEGR1PcJys9+DYh3J2wT2tnAh8ofO4NNI/3Rb5fJqf5mb2zOoPhCKGqx4WLs++RLX1alDzfnQU57sUytE03HULH3p0vjkBNtzngbvvdeFAvcOFSlRkS0AZOZ4+CtbkFg5NBaJnGHSLk7lE4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712852364; c=relaxed/simple; bh=d5RtO4GKFnslwjophoD9TBH6WRnICgUt5M4cljtjlC0=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=LXtIxTWGqeUvEYPZHZBMHCFl1TNPH3WF0f8bcIq1eAHyFp2Czcc0Wjm2vuCVYnn16xgdezCgbPoD2wqmYoGxottMGrq1jsN9afgzccf0uydd2sxAjjkK+3NX0pNwakAISHxKHRZ4lvlIDSQRfqc5LtItZGgmB2YiCjcCrb9GeuY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=H8vO8gKG; 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="H8vO8gKG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 924E7C113CD for ; Thu, 11 Apr 2024 16:19:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712852363; bh=d5RtO4GKFnslwjophoD9TBH6WRnICgUt5M4cljtjlC0=; h=From:To:Subject:Date:In-Reply-To:References:From; b=H8vO8gKGAso6wMdp9Dv4ZIrb9VsgYOwG5oEph7aR1hjzxGmEwVzis0zrqk7BCHpO1 X5T+LDWK9V8eE6v7p/vMxjPa24DHLhS6wMvVgCXBEEjyL+wy9o/SbcLA0AYCHDKQ2S 8tqSgknpc9RN7SX+9rZsZ+wxcflmBGqxeCTddqUCaKFbBe2Yd3RYMOKPDLltx7wgxn YkCfSZKN/6Yc2BW0Z2QoS4brB9kawJztnev/g0L7bT/5KQHrXT20By+UpN1H2r4GlC EUJj1CFbxnfQksPBvefOBWpYgyJGTDJpJFM7+raQMEYU/QrY/fj/qVuZMm+jlQ09l6 AeN1MmptLZhaw== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 07/15] btrfs: pass the extent map tree's inode to replace_extent_mapping() Date: Thu, 11 Apr 2024 17:19:01 +0100 Message-Id: <6ad630fcc72febd6057d098268427e3c610af5ba.1712837044.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 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 Signed-off-by: Filipe Manana --- 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 Thu Apr 11 16:19:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13626370 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 25540184113 for ; Thu, 11 Apr 2024 16:19: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=1712852365; cv=none; b=aajBPyPZwVoVZsl+k4RgUYvxMNQ0HDdaG3Ka2e9b2eYnfyGALNDHJ7U3oXnrMZCTvT252eiGrNfBtHtm25fXGlIStynP8DetcMSvLJkde64aR7kT+CMWH1VNwjtSGEJoMVaIhoG2ODAvLI1LD+gjn1x4LTRYsj9A8m3HgBAfHA8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712852365; c=relaxed/simple; bh=WEOs238PXlFyLYxlpU8huS8p/TvCwvsSg+SMm+wz+Oc=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NWMQP3yr8ucHPVNxhpUjDx0ptpjpFdceAFDmRVBAbsKMBKC9Sx5CsQ46tEkI9aW0CItvOpxT9c6V+c8l3fZmGRQZjMWDBEtpi0H1PmBWr60PBGegDKvHemXwZE0FZMdyoWCcHOAFQwSZ7lpGDOkivEC/ihW+pcdKnZbZ6dxsW8s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=q+MchUYV; 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="q+MchUYV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 00369C072AA for ; Thu, 11 Apr 2024 16:19:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712852364; bh=WEOs238PXlFyLYxlpU8huS8p/TvCwvsSg+SMm+wz+Oc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=q+MchUYVJJU+B05npPx87x828Xqva7W/NEPCMpbeLe31Qol9esWO8rZfw8gwPQj3H y/1IIJWuenrJHwsbp+74eaw+UL2rI/ftNxTNUFHVBUxwojnktZGCdmYtnx9KSj07GB 1A7tNwshtd5fI1G/gdf4G7H8l47SteMOr8+JFWDICplKNHOQqM1D14qC7IwOFpUE4p pZdN81sc7NxDhIdYZdTGaPf2YXbcJ3pcDOYkN+m3Iy/WP9Snvh8U3luhAz/GbYVLcx aiW7yBRhZ8i5W2FleEeQY72e79LhPDMHcOXB9yALsi1GQ9NITMPwraxNRh165Dk6vH hcPqCKP1aCCJw== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 08/15] btrfs: pass the extent map tree's inode to setup_extent_mapping() Date: Thu, 11 Apr 2024 17:19:02 +0100 Message-Id: <7e8a8cc96cc25b31df62ce8a3492c690dc25608d.1712837044.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. Signed-off-by: Filipe Manana Reviewed-by: Qu Wenruo --- 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 Thu Apr 11 16:19: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: 13626371 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 29B3B180A73 for ; Thu, 11 Apr 2024 16:19: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=1712852366; cv=none; b=j3B27USezwuPdDb0wWmCWnAsMrWc+qRnYeReaZAdrjroRh2gWlOBSCZY1kRW1idVpGiGKb2Ubairr3fnUeeIxDHcE3bageS9YnvWYF8Y87j9pYvA0IPTjIr1y7pzLd9k606QYAhLAYl6n594FWKYgeY/LcD8fB/mYVEVBb7YOls= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712852366; c=relaxed/simple; bh=TJwFNHUjYoJ+JCI3wVQ+01oev1ZWlC8DHs1UdVlyE/M=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QquEq8YClqYTwZ1Ij6py6jYAIRAsKsdKpzsnrzTw33JAhwWmJJptrg/RB+ZFnINOquyS5EWN9stGuymYdCiBvXB4Jm7Hk6YIERsug1hFx3TaM0aXKEROR8W0evgkPThqGUspd1NYE3r0O8qpU/Ua65F9s5UwmeZ/5rrGdaiFmkE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NdiPxl5B; 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="NdiPxl5B" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0F77FC113CE for ; Thu, 11 Apr 2024 16:19:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712852365; bh=TJwFNHUjYoJ+JCI3wVQ+01oev1ZWlC8DHs1UdVlyE/M=; h=From:To:Subject:Date:In-Reply-To:References:From; b=NdiPxl5BFWa0j9O9MrEH0d4SniN6KMx0DfkcSU0FMHhiJ4NZBom3gvUyuyObyKi6z OMJiFN7+48AtrSIrz3BpGyP60yyNkgIBW0Eea907Ra0hvznJzAUz25xzEHRqgVMrEt cPMQjxyjQL7uKTPuH94hO7M6Yk6NdfMvGTNkzrGSFN4uLlePh7fNtaCi2nxNgrIcvI IaM3DlwK6gnKiO2yadC4UNeaB2BJ9PFszctspnV95hL/KxkY/PrRZMSLOEFLIo7htK O+eFqaSP6kCN3dk3VSutziC0mmL6ISX+5TceiiM5p8TEAwsv5XcuhBkC+TROJKPMcS XbL9gTQ8fCRGQ== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 09/15] btrfs: pass the extent map tree's inode to try_merge_map() Date: Thu, 11 Apr 2024 17:19:03 +0100 Message-Id: <81628b9abb3ece8fd7e35a521068cfa958aca112.1712837044.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. Signed-off-by: Filipe Manana Reviewed-by: Qu Wenruo --- 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 Thu Apr 11 16:19: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: 13626372 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 323FD181B8E for ; Thu, 11 Apr 2024 16:19:26 +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=1712852367; cv=none; b=V7VGv1GmZpY5lNAOHAn88tabLgVkkTqyAaVeQo23VAmZSRio0Uf74WGoFt7i0QBqIb24ttT4K8EysBKXfgRF+hwft9OtqokY6PQgKeKiYW+PzQHwmg0qU9jng9O4CphJaQasFkupB418PHgHUqAd1MzZNaLWYR3juydmyPj70HQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712852367; c=relaxed/simple; bh=W3ZrSkEIOCAmSrBiQ65Y4/u2Cs1ghVFKcH7aPeqFWkc=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=CnZRLHxqpTvvZcFW61lQsVRN5mQQrNLRs7c9kTSA0q0mkur1r5Jr0WaUq6lIQbHiWUPB+Ok4j9gFxbk0b01oGOe90WJ8gJJbC0wUcb+lxHnEf6v2hRkoWTBTyB/K4Dr5xa5UWVv6tsTQOTvP8XxYZK5LeDupWR8KcACBlKU8SCA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FS0BcBf/; 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="FS0BcBf/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 10680C072AA for ; Thu, 11 Apr 2024 16:19:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712852366; bh=W3ZrSkEIOCAmSrBiQ65Y4/u2Cs1ghVFKcH7aPeqFWkc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=FS0BcBf/FSl90Amd2NNhYC53H0p4eSVtp3tJXtAR/Ubp8FCN2H3qipC9tyqZdGj3L U2WqkZfyBzAW1g2tNw4VIiR2/MMmI/Sr73MQBKDISweCpT8OqYvBygEEzz3iqMf2rr yu6LvnS0Sg6DxQN2qm8ixM+xxnpRhOQmSolllPxH1StxRUpUc7O5KW/NpPxGff1/Xe M6BNu2ML5z8aqc3A4C2C6qA2Lt94qUQfgnMmECm/Y8K/bVtQDa8DeH+cKHiCSkrs+U oqi7LOJRFujQ6wt+3lPme9rm4qOp255+QjQYqtCpm43YGf5BUF+MVX8f2iMtllH/TI JAnHJhqxWFJpQ== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 10/15] btrfs: add a global per cpu counter to track number of used extent maps Date: Thu, 11 Apr 2024 17:19: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 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). Signed-off-by: Filipe Manana --- fs/btrfs/disk-io.c | 6 ++++++ fs/btrfs/extent_map.c | 17 +++++++++++++++++ fs/btrfs/fs.h | 2 ++ 3 files changed, 25 insertions(+) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 0474e9b6d302..3c2d35b2062e 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1269,6 +1269,8 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info) percpu_counter_destroy(&fs_info->dirty_metadata_bytes); percpu_counter_destroy(&fs_info->delalloc_bytes); percpu_counter_destroy(&fs_info->ordered_bytes); + ASSERT(percpu_counter_sum_positive(&fs_info->evictable_extent_maps) == 0); + percpu_counter_destroy(&fs_info->evictable_extent_maps); percpu_counter_destroy(&fs_info->dev_replace.bio_counter); btrfs_free_csum_hash(fs_info); btrfs_free_stripe_hash_table(fs_info); @@ -2848,6 +2850,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 Thu Apr 11 16:19: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: 13626373 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 DAC6C17A92F for ; Thu, 11 Apr 2024 16:19:27 +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=1712852367; cv=none; b=aImGbt0baivUDsaVjHtbP3bD06n+hZN1skcT8ND2maMu6rfIcNpu/hv+gEW7nYJHkY4GINJCCkMr/se4HlRBGDR0mdmOlpVNKhO/Gf1wD2SDopNAgQjcz2qFow7gKTzcsbUoa+J+RrnD+Z1pozZhKjQsBqmyTMcoFbNXdde8QU8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712852367; c=relaxed/simple; bh=966eCP3YqZdY6wqX5xS05eAKsKK7bCQiOk1fU2YpjCc=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=LV80+gCNN+vOVUPFIUk5X9U//WbD4yvK5HnIKqb0aGvTwu+qDa91ADgAaK7AZHFalRlEwMjXi5yAEhuYpznzzG0phzlnK0k7NR4PVuXl8Ik5qHx5Tk50roqqu/uYkQraQ44v5q6VacYbn9gEa/cc7B8u3kjUfliMrOzqhnPCuIw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YuE61IYO; 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="YuE61IYO" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 149EDC113CD for ; Thu, 11 Apr 2024 16:19:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712852367; bh=966eCP3YqZdY6wqX5xS05eAKsKK7bCQiOk1fU2YpjCc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=YuE61IYOex5gHlOHw+oheS/rt7J4Z16Wn7DNLZa4v6iBVtrVxwpzC4ztOza906nfa V/48hkV9Lt5cnqygS7H/E13l2NsInUsVxyCiydUPT1ZY/FmHcyXEQnMoBhQzsG2D3f /9eSF2kRCxTSySxpm5hEWs7FH75gciesDJLls9WzUi1q6MefpbIMmPM+Ila5YOQ+7y vdB1IvZtWFHzeXuN2vlx3oHD23RBwDcbi189Hpt1owgLmisZ4fTK2FBNCyOuf8YZNd W1bJEkPW8AWtB1XzFShqderV7/BTRt3pJQQVnr8wLgSUBoJlnfSLOJi9VrYk/yW110 nbRkRjDFMSm6g== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 11/15] btrfs: export find_next_inode() as btrfs_find_first_inode() Date: Thu, 11 Apr 2024 17:19:05 +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 Export the relocation private helper find_next_inode() to inode.c, as this same logic is also used at btrfs_prune_dentries() and will be used by an upcoming change that adds an extent map shrinker. The next patch will change btrfs_prune_dentries() to use this helper. Signed-off-by: Filipe Manana Reviewed-by: Qu Wenruo --- fs/btrfs/btrfs_inode.h | 1 + fs/btrfs/inode.c | 58 +++++++++++++++++++++++ fs/btrfs/relocation.c | 105 ++++++++++------------------------------- 3 files changed, 84 insertions(+), 80 deletions(-) diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index ed8bd15aa3e2..9a87ada7fe52 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -543,6 +543,7 @@ ssize_t btrfs_dio_read(struct kiocb *iocb, struct iov_iter *iter, size_t done_before); struct iomap_dio *btrfs_dio_write(struct kiocb *iocb, struct iov_iter *iter, size_t done_before); +struct btrfs_inode *btrfs_find_first_inode(struct btrfs_root *root, u64 min_ino); extern const struct dentry_operations btrfs_dentry_operations; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d4539b4b8148..9dc41334c3a3 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -10827,6 +10827,64 @@ void btrfs_assert_inode_range_clean(struct btrfs_inode *inode, u64 start, u64 en ASSERT(ordered == NULL); } +/* + * Find the first inode with a minimum number. + * + * @root: The root to search for. + * @min_ino: The minimum inode number. + * + * Find the first inode in the @root with a number >= @min_ino and return it. + * Returns NULL if no such inode found. + */ +struct btrfs_inode *btrfs_find_first_inode(struct btrfs_root *root, u64 min_ino) +{ + struct rb_node *node; + struct rb_node *prev = NULL; + struct btrfs_inode *inode; + + spin_lock(&root->inode_lock); +again: + node = root->inode_tree.rb_node; + while (node) { + prev = node; + inode = rb_entry(node, struct btrfs_inode, rb_node); + if (min_ino < btrfs_ino(inode)) + node = node->rb_left; + else if (min_ino > btrfs_ino(inode)) + node = node->rb_right; + else + break; + } + + if (!node) { + while (prev) { + inode = rb_entry(prev, struct btrfs_inode, rb_node); + if (min_ino <= btrfs_ino(inode)) { + node = prev; + break; + } + prev = rb_next(prev); + } + } + + while (node) { + inode = rb_entry(prev, struct btrfs_inode, rb_node); + if (igrab(&inode->vfs_inode)) { + spin_unlock(&root->inode_lock); + return inode; + } + + min_ino = btrfs_ino(inode) + 1; + if (cond_resched_lock(&root->inode_lock)) + goto again; + + node = rb_next(node); + } + spin_unlock(&root->inode_lock); + + return NULL; +} + static const struct inode_operations btrfs_dir_inode_operations = { .getattr = btrfs_getattr, .lookup = btrfs_lookup, diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 5c9ef6717f84..5b19b41f64a2 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -951,60 +951,6 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans, return ret; } -/* - * helper to find first cached inode with inode number >= objectid - * in a subvolume - */ -static struct inode *find_next_inode(struct btrfs_root *root, u64 objectid) -{ - struct rb_node *node; - struct rb_node *prev; - struct btrfs_inode *entry; - struct inode *inode; - - spin_lock(&root->inode_lock); -again: - node = root->inode_tree.rb_node; - prev = NULL; - while (node) { - prev = node; - entry = rb_entry(node, struct btrfs_inode, rb_node); - - if (objectid < btrfs_ino(entry)) - node = node->rb_left; - else if (objectid > btrfs_ino(entry)) - node = node->rb_right; - else - break; - } - if (!node) { - while (prev) { - entry = rb_entry(prev, struct btrfs_inode, rb_node); - if (objectid <= btrfs_ino(entry)) { - node = prev; - break; - } - prev = rb_next(prev); - } - } - while (node) { - entry = rb_entry(node, struct btrfs_inode, rb_node); - inode = igrab(&entry->vfs_inode); - if (inode) { - spin_unlock(&root->inode_lock); - return inode; - } - - objectid = btrfs_ino(entry) + 1; - if (cond_resched_lock(&root->inode_lock)) - goto again; - - node = rb_next(node); - } - spin_unlock(&root->inode_lock); - return NULL; -} - /* * get new location of data */ @@ -1065,7 +1011,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_key key; struct btrfs_file_extent_item *fi; - struct inode *inode = NULL; + struct btrfs_inode *inode = NULL; u64 parent; u64 bytenr; u64 new_bytenr = 0; @@ -1112,13 +1058,13 @@ int replace_file_extents(struct btrfs_trans_handle *trans, */ if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) { if (first) { - inode = find_next_inode(root, key.objectid); + inode = btrfs_find_first_inode(root, key.objectid); first = 0; - } else if (inode && btrfs_ino(BTRFS_I(inode)) < key.objectid) { - btrfs_add_delayed_iput(BTRFS_I(inode)); - inode = find_next_inode(root, key.objectid); + } else if (inode && btrfs_ino(inode) < key.objectid) { + btrfs_add_delayed_iput(inode); + inode = btrfs_find_first_inode(root, key.objectid); } - if (inode && btrfs_ino(BTRFS_I(inode)) == key.objectid) { + if (inode && btrfs_ino(inode) == key.objectid) { struct extent_state *cached_state = NULL; end = key.offset + @@ -1128,21 +1074,19 @@ int replace_file_extents(struct btrfs_trans_handle *trans, WARN_ON(!IS_ALIGNED(end, fs_info->sectorsize)); end--; /* Take mmap lock to serialize with reflinks. */ - if (!down_read_trylock(&BTRFS_I(inode)->i_mmap_lock)) + if (!down_read_trylock(&inode->i_mmap_lock)) continue; - ret = try_lock_extent(&BTRFS_I(inode)->io_tree, - key.offset, end, - &cached_state); + ret = try_lock_extent(&inode->io_tree, key.offset, + end, &cached_state); if (!ret) { - up_read(&BTRFS_I(inode)->i_mmap_lock); + up_read(&inode->i_mmap_lock); continue; } - btrfs_drop_extent_map_range(BTRFS_I(inode), - key.offset, end, true); - unlock_extent(&BTRFS_I(inode)->io_tree, - key.offset, end, &cached_state); - up_read(&BTRFS_I(inode)->i_mmap_lock); + btrfs_drop_extent_map_range(inode, key.offset, end, true); + unlock_extent(&inode->io_tree, key.offset, end, + &cached_state); + up_read(&inode->i_mmap_lock); } } @@ -1185,7 +1129,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans, if (dirty) btrfs_mark_buffer_dirty(trans, leaf); if (inode) - btrfs_add_delayed_iput(BTRFS_I(inode)); + btrfs_add_delayed_iput(inode); return ret; } @@ -1527,7 +1471,7 @@ static int invalidate_extent_cache(struct btrfs_root *root, const struct btrfs_key *max_key) { struct btrfs_fs_info *fs_info = root->fs_info; - struct inode *inode = NULL; + struct btrfs_inode *inode = NULL; u64 objectid; u64 start, end; u64 ino; @@ -1537,23 +1481,24 @@ static int invalidate_extent_cache(struct btrfs_root *root, struct extent_state *cached_state = NULL; cond_resched(); - iput(inode); + if (inode) + iput(&inode->vfs_inode); if (objectid > max_key->objectid) break; - inode = find_next_inode(root, objectid); + inode = btrfs_find_first_inode(root, objectid); if (!inode) break; - ino = btrfs_ino(BTRFS_I(inode)); + ino = btrfs_ino(inode); if (ino > max_key->objectid) { - iput(inode); + iput(&inode->vfs_inode); break; } objectid = ino + 1; - if (!S_ISREG(inode->i_mode)) + if (!S_ISREG(inode->vfs_inode.i_mode)) continue; if (unlikely(min_key->objectid == ino)) { @@ -1586,9 +1531,9 @@ static int invalidate_extent_cache(struct btrfs_root *root, } /* the lock_extent waits for read_folio to complete */ - lock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached_state); - btrfs_drop_extent_map_range(BTRFS_I(inode), start, end, true); - unlock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached_state); + lock_extent(&inode->io_tree, start, end, &cached_state); + btrfs_drop_extent_map_range(inode, start, end, true); + unlock_extent(&inode->io_tree, start, end, &cached_state); } return 0; } From patchwork Thu Apr 11 16:19: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: 13626374 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 2A6BE190663 for ; Thu, 11 Apr 2024 16:19:28 +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=1712852369; cv=none; b=Y4XRrhb8Koaj7WgMnCAXR8JqttSmSejsUEdbzT+bdPbceHXPyC07JcU+RGW9q7IGeHGboF0iX3AY6HehCCp0JgoIjVFrLL6gsix/3z+Bn2Qotp9rEpzXfpw6LbPrn/qvHF2YntJG1hw85oQSxMxk+adxONobHvYuVGQolO5ZgSs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712852369; c=relaxed/simple; bh=NemHQ9dJLema+Q1gJaRd1Fr6pp32bOpl6bIlFbNkJNE=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ogeClzCYHYRqxyflS5NR+NoU1Nycz4lk85LCoTfWg1urtgsWd4HhnXMb5GPaxFyzw3zkzY/EWt3Ke6oGfuUdI8Fl7sE6egqjkyKugYB/uoF2ZJ8kzSOGkSoB1f67R3zGUqzPilZSpv5rZyYYOS3F1KbNSaegX00xwkJUaCIUUFQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mzRIclpW; 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="mzRIclpW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 15445C072AA for ; Thu, 11 Apr 2024 16:19:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712852368; bh=NemHQ9dJLema+Q1gJaRd1Fr6pp32bOpl6bIlFbNkJNE=; h=From:To:Subject:Date:In-Reply-To:References:From; b=mzRIclpWGNIK0GqMKftqr/Qo04yDmM5tr1jWBIt3mde9obvoQssNZMMWs6CY3yvUl 5c0k3tewrGz6aVw913XUTVHqC/ndt27/s8lzJoVHFR9YfnwpmQbvwEsJw2tcBvLLHO +7bY6YX8qSXefbsa5YFmCaM7mzULaF04qWIZFhdOD7uxrjSF6be2FUKvXyi+59aLL5 yJhJqbclhN2kbnVnL5ee7d+1dXOWHlynKyQGbrh/xEhT1ivMPsLcO6awF1Zj1D+FFz 8foAMleDdf+7hgLeD1C14Ip6VDJJCaEAUy3i/ioR8pe4Cp5PU44ZC7zH33ftLKf5Tl X8QaQ6TslLqtA== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 12/15] btrfs: use btrfs_find_first_inode() at btrfs_prune_dentries() Date: Thu, 11 Apr 2024 17:19:06 +0100 Message-Id: <787204cda3fa8259bb7763c558a910cf7a2e609b.1712837044.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 Currently btrfs_prune_dentries() has open code to find the first inode in a root with a minimum inode number. Remove that code and make it use the helper btrfs_find_first_inode() for that task. Signed-off-by: Filipe Manana Reviewed-by: Qu Wenruo --- fs/btrfs/inode.c | 66 ++++++++++-------------------------------------- 1 file changed, 14 insertions(+), 52 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9dc41334c3a3..2dae4e975e80 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4436,64 +4436,26 @@ static noinline int may_destroy_subvol(struct btrfs_root *root) static void btrfs_prune_dentries(struct btrfs_root *root) { struct btrfs_fs_info *fs_info = root->fs_info; - struct rb_node *node; - struct rb_node *prev; - struct btrfs_inode *entry; - struct inode *inode; - u64 objectid = 0; + struct btrfs_inode *inode; + u64 min_ino = 0; if (!BTRFS_FS_ERROR(fs_info)) WARN_ON(btrfs_root_refs(&root->root_item) != 0); - spin_lock(&root->inode_lock); -again: - node = root->inode_tree.rb_node; - prev = NULL; - while (node) { - prev = node; - entry = rb_entry(node, struct btrfs_inode, rb_node); - - if (objectid < btrfs_ino(entry)) - node = node->rb_left; - else if (objectid > btrfs_ino(entry)) - node = node->rb_right; - else - break; - } - if (!node) { - while (prev) { - entry = rb_entry(prev, struct btrfs_inode, rb_node); - if (objectid <= btrfs_ino(entry)) { - node = prev; - break; - } - prev = rb_next(prev); - } - } - while (node) { - entry = rb_entry(node, struct btrfs_inode, rb_node); - objectid = btrfs_ino(entry) + 1; - inode = igrab(&entry->vfs_inode); - if (inode) { - spin_unlock(&root->inode_lock); - if (atomic_read(&inode->i_count) > 1) - d_prune_aliases(inode); - /* - * btrfs_drop_inode will have it removed from the inode - * cache when its usage count hits zero. - */ - iput(inode); - cond_resched(); - spin_lock(&root->inode_lock); - goto again; - } - - if (cond_resched_lock(&root->inode_lock)) - goto again; + inode = btrfs_find_first_inode(root, min_ino); + while (inode) { + if (atomic_read(&inode->vfs_inode.i_count) > 1) + d_prune_aliases(&inode->vfs_inode); - node = rb_next(node); + min_ino = btrfs_ino(inode) + 1; + /* + * btrfs_drop_inode() will have it removed from the inode + * cache when its usage count hits zero. + */ + iput(&inode->vfs_inode); + cond_resched(); + inode = btrfs_find_first_inode(root, min_ino); } - spin_unlock(&root->inode_lock); } int btrfs_delete_subvolume(struct btrfs_inode *dir, struct dentry *dentry) From patchwork Thu Apr 11 16:19: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: 13626375 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 01A5A18412C for ; Thu, 11 Apr 2024 16:19:29 +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=1712852370; cv=none; b=ufXGxhqR6tCO7gYjrG19aOqCIEkOqoyVAAA0nll3MsJgnaZaS+vl3Dpj6ogpme8fHvB53k2dHtstrERsWK7UX2j6x4no4mTtJ79ryNYQ6aVCCGKlL7bZsGWQ07s68TGglQm068MEfP+CzLDPhvx6n0y3C3d+Dvdi38nAkIjhmnc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712852370; c=relaxed/simple; bh=9I0a4Xww6gAPTiXPED9QC5SFtk80nyL3MojG8Y6Tr8I=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QHhQfEjW+rvgzBHeZ1Zgfd3IhgxXpzHNogoD3r4d0b2wgQq3yy3tWcMmbaAwyFxCcwNM8XTVMLaMJl8o4SlxuJ9dmPReu5oSeK1n8mnDBufXgq/1NjWN+HFiRXYK9hO78ErsIiiFEOXi9eUBn8UcZaSIox1x4Hnou/PgR4vvNcY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VKjEbILr; 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="VKjEbILr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1B702C113CD for ; Thu, 11 Apr 2024 16:19:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712852369; bh=9I0a4Xww6gAPTiXPED9QC5SFtk80nyL3MojG8Y6Tr8I=; h=From:To:Subject:Date:In-Reply-To:References:From; b=VKjEbILrOoLGLj+3bjKP9vKX9uDBFodeZ1A/nwnrGa2MtP91v0qBzts6uWEi5RVad Lsn9I3krsg1EIVLGRxVNG5I/7U3NJ1FBnfio/pqY4Llimj0S7BYBxsKDPCdTkcWpL3 m0eP+6dQMhKWs3ua8ooO7nWz+VYw9vOR5fT2CwKekxBRQOfn18VWH0vCQtoA1di1ts 3JDKeuTPsLm+07kaDq0F/OWjWcsi/Zitq0fZqQBLh3Azc6+010j/MiwA9Vw9T6XgVR SeIH+hKzN7QDhjTaujRnhsItz9uxQkQV/fE1g/QhgHudCVPhPWOMXBhY0BEVyjKe/p 1RklIN/nJBIrg== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 13/15] btrfs: add a shrinker for extent maps Date: Thu, 11 Apr 2024 17:19:07 +0100 Message-Id: <1cb649870b6cad4411da7998735ab1141bb9f2f0.1712837044.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 similar to the one ext4 uses for its extent_status structure, which is analogous to btrfs' extent_map structure. Link: https://lore.kernel.org/linux-btrfs/13f94633dcf04d29aaf1f0a43d42c55e@amazon.com/ Signed-off-by: Filipe Manana Reviewed-by: Josef Bacik --- fs/btrfs/disk-io.c | 7 +- fs/btrfs/extent_map.c | 156 ++++++++++++++++++++++++++++++++++++++++++ fs/btrfs/extent_map.h | 2 + fs/btrfs/fs.h | 2 + 4 files changed, 163 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 3c2d35b2062e..8bb295eaf3d7 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1266,11 +1266,10 @@ static void free_global_roots(struct btrfs_fs_info *fs_info) void btrfs_free_fs_info(struct btrfs_fs_info *fs_info) { + btrfs_unregister_extent_map_shrinker(fs_info); percpu_counter_destroy(&fs_info->dirty_metadata_bytes); percpu_counter_destroy(&fs_info->delalloc_bytes); percpu_counter_destroy(&fs_info->ordered_bytes); - ASSERT(percpu_counter_sum_positive(&fs_info->evictable_extent_maps) == 0); - percpu_counter_destroy(&fs_info->evictable_extent_maps); percpu_counter_destroy(&fs_info->dev_replace.bio_counter); btrfs_free_csum_hash(fs_info); btrfs_free_stripe_hash_table(fs_info); @@ -2846,11 +2845,11 @@ static int init_mount_fs_info(struct btrfs_fs_info *fs_info, struct super_block sb->s_blocksize = BTRFS_BDEV_BLOCKSIZE; sb->s_blocksize_bits = blksize_bits(BTRFS_BDEV_BLOCKSIZE); - ret = percpu_counter_init(&fs_info->ordered_bytes, 0, GFP_KERNEL); + ret = btrfs_register_extent_map_shrinker(fs_info); if (ret) return ret; - ret = percpu_counter_init(&fs_info->evictable_extent_maps, 0, GFP_KERNEL); + ret = percpu_counter_init(&fs_info->ordered_bytes, 0, GFP_KERNEL); if (ret) return ret; diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 2fcf28148a81..9791acda5b57 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,158 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre, free_extent_map(split_pre); return ret; } + +static unsigned long btrfs_scan_inode(struct btrfs_inode *inode, + unsigned long *scanned, + unsigned long nr_to_scan) +{ + struct extent_map_tree *tree = &inode->extent_tree; + unsigned 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. + */ + down_read(&inode->i_mmap_lock); + 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 (!list_empty(&em->list)) + 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 unsigned long btrfs_scan_root(struct btrfs_root *root, + unsigned long *scanned, + unsigned long nr_to_scan) +{ + struct btrfs_inode *inode; + unsigned long nr_dropped = 0; + u64 min_ino = 0; + + 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; + iput(&inode->vfs_inode); + + if (*scanned >= nr_to_scan) + break; + + cond_resched(); + inode = btrfs_find_first_inode(root, min_ino); + } + + return nr_dropped; +} + +static unsigned long btrfs_extent_maps_scan(struct shrinker *shrinker, + struct shrink_control *sc) +{ + struct btrfs_fs_info *fs_info = shrinker->private_data; + unsigned long nr_dropped = 0; + unsigned long scanned = 0; + u64 next_root_id = 0; + + while (scanned < sc->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); + 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, sc->nr_to_scan); + + btrfs_put_root(root); + } + + return nr_dropped; +} + +static unsigned long btrfs_extent_maps_count(struct shrinker *shrinker, + struct shrink_control *sc) +{ + struct btrfs_fs_info *fs_info = shrinker->private_data; + + return percpu_counter_sum_positive(&fs_info->evictable_extent_maps); +} + +int btrfs_register_extent_map_shrinker(struct btrfs_fs_info *fs_info) +{ + int ret; + + ret = percpu_counter_init(&fs_info->evictable_extent_maps, 0, GFP_KERNEL); + if (ret) + return ret; + + fs_info->extent_map_shrinker = shrinker_alloc(0, "em-btrfs:%s", fs_info->sb->s_id); + if (!fs_info->extent_map_shrinker) { + percpu_counter_destroy(&fs_info->evictable_extent_maps); + return -ENOMEM; + } + + fs_info->extent_map_shrinker->scan_objects = btrfs_extent_maps_scan; + fs_info->extent_map_shrinker->count_objects = btrfs_extent_maps_count; + fs_info->extent_map_shrinker->private_data = fs_info; + + shrinker_register(fs_info->extent_map_shrinker); + + return 0; +} + +void btrfs_unregister_extent_map_shrinker(struct btrfs_fs_info *fs_info) +{ + shrinker_free(fs_info->extent_map_shrinker); + ASSERT(percpu_counter_sum_positive(&fs_info->evictable_extent_maps) == 0); + percpu_counter_destroy(&fs_info->evictable_extent_maps); +} diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index c3707461ff62..8a6be2f7a0e2 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h @@ -140,5 +140,7 @@ 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); +int btrfs_register_extent_map_shrinker(struct btrfs_fs_info *fs_info); +void btrfs_unregister_extent_map_shrinker(struct btrfs_fs_info *fs_info); #endif diff --git a/fs/btrfs/fs.h b/fs/btrfs/fs.h index 534d30dafe32..f1414814bd69 100644 --- a/fs/btrfs/fs.h +++ b/fs/btrfs/fs.h @@ -857,6 +857,8 @@ struct btrfs_fs_info { struct lockdep_map btrfs_trans_pending_ordered_map; struct lockdep_map btrfs_ordered_extent_map; + struct shrinker *extent_map_shrinker; + #ifdef CONFIG_BTRFS_FS_REF_VERIFY spinlock_t ref_verify_lock; struct rb_root block_tree; From patchwork Thu Apr 11 16:19: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: 13626376 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 68E7F18412C for ; Thu, 11 Apr 2024 16:19:31 +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=1712852371; cv=none; b=fcqpjFBDLVrfesVlW+Ag2DxUzeSeMliMiqtBAkAlqtaB3j/eFtsaZ1Zo3gE00NGa0PM9Lm+gvm/2PFkkQSr7EG+dDJB2krC1XHLbvZHcIp0eO6+agwge9XUvC2jcKo549rFgTk2JcvV1qXjZo2oPW0oKgahljuxUjTFFQlLXin0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712852371; c=relaxed/simple; bh=HI3YUCV6ogY701l3EzQE6IVpXTuw0BhgDGgGeTU6C8Q=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=duJCEbj4tu9ZNVWKhVjTj9l83iwXZPILk6GVyt80cK62v4jyHvTdG+1eJfpfsocUaIQV8LfmaP6Smt9RlWT2XLAaIZ6aNYAiFaIlC9c953lVTHaNGyiJfIzKgVXei6awPXSODWnNjZ1eeDK+udKtyqa2xDgN2jJEzbufDhoOF3o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tCvcPIkd; 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="tCvcPIkd" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6C5B3C072AA for ; Thu, 11 Apr 2024 16:19:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712852371; bh=HI3YUCV6ogY701l3EzQE6IVpXTuw0BhgDGgGeTU6C8Q=; h=From:To:Subject:Date:In-Reply-To:References:From; b=tCvcPIkdv5JZV9mgcb+Q1ShPBtW1qZBS6SzsEJwWGtxrkcqGgLb9xcjaFbzIA9vvn ijzjanDHooUmnwmnmjYAK/MyfrsT91r+dbcVTQjk1qUbtlfXVcrIKY9xiTaQAHLAjU HjyTa4xin+ABUx/KZCelC32EUDpYycPvAHuRgvdTYW7JOOQcEwYMjkEAUnI9ZAPHel /ZE8NSPt8FOh3qc/LUkRCRui1CemjU3k+s7Aga2T94ff75qiM4v4zMsPPadXv+Gmhc XQlc4bYPVZazyoBHvP2j0Xs36dJxJGNpvujkLOb9We6PymzbxExLpPu/V3/ZfyIGHp ed+KkQiKV3KGg== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 14/15] btrfs: update comment for btrfs_set_inode_full_sync() about locking Date: Thu, 11 Apr 2024 17:19:08 +0100 Message-Id: <301cd211de3cb3854c65f937b94791d1f1dcc2ae.1712837044.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 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. 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 Thu Apr 11 16:19: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: 13626377 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 67341190684 for ; Thu, 11 Apr 2024 16:19:32 +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=1712852372; cv=none; b=FbfmLzLCNT0IBgD/45IapJ9fJVB6bb4XmqZCknJa6hDLn4sgmVbX9EfOlCpPKdaJaYE5Yi8NjtjwOvyIYopVU3+cziNKpHhHsfC2QFy728zjZ6dAU61YeAGUzAp8Tq4oSxOkTO9EcnY8LsVp2LW4Jb4tLYomNiiBY6f4ISi2jp8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712852372; c=relaxed/simple; bh=Zzh8G9Ktno/CPunpZz99wWJA9ns+H0V6qjxJUzvCzVo=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=TehdeTM1Nf0cMxpva3Crg6+gEJnzN72A3IKP6KQGJW3Wrrn+EXGpaVIU6h+8KW0g/UpTi/KOJDxWRBZoub20QPnSZ53AnppWgBFb2yMg3ibrbdxv7q4lGC35vf0K51RlTKONHMlK8Rrc797tyMfkGHkfSdCEHT6Bi8ou9HLadDw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aoEK7XGM; 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="aoEK7XGM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 700F4C113CD for ; Thu, 11 Apr 2024 16:19:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712852372; bh=Zzh8G9Ktno/CPunpZz99wWJA9ns+H0V6qjxJUzvCzVo=; h=From:To:Subject:Date:In-Reply-To:References:From; b=aoEK7XGMzVCVYFgafzh7qlX+K3EZmEgBE/5VOMG0ma3q7xpwC5Fe4pec9EamBZcFT VJH72EqvNozKO5q7EyvnTHBAka08XAQ2SGbygdRaWWAVGW+p9xgw4IrHIswww0yRQT gOhKvGumKqoE9T3bvfxmkdqirLreT3AzAVzvJxYe6d6HVKJNNBiJfAOusoBVNoiaGK zjzX15g3H+H3t6Am9S6DcTZaRVgHoOVE/jqjlYCh5RityTM+zmGaeNf3j8FcXleWzJ PStPFNXzk5SOTMzOEEZdFURfC+2pb8kAdHzx8Bp+rUX7BZxHrmKMvxOCgIcDIp9Yny L4pqdkCzBxcpA== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 15/15] btrfs: add tracepoints for extent map shrinker events Date: Thu, 11 Apr 2024 17:19:09 +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 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 --- fs/btrfs/extent_map.c | 18 ++++++- include/trace/events/btrfs.h | 92 ++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 9791acda5b57..5c40efe39e70 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -1064,6 +1064,7 @@ static unsigned long btrfs_scan_inode(struct btrfs_inode *inode, 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++; @@ -1118,6 +1119,12 @@ static unsigned long btrfs_extent_maps_scan(struct shrinker *shrinker, unsigned long scanned = 0; u64 next_root_id = 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, sc->nr_to_scan, nr); + } + while (scanned < sc->nr_to_scan) { struct btrfs_root *root; unsigned long count; @@ -1142,6 +1149,12 @@ static unsigned long btrfs_extent_maps_scan(struct shrinker *shrinker, 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; } @@ -1149,8 +1162,11 @@ static unsigned long btrfs_extent_maps_count(struct shrinker *shrinker, struct shrink_control *sc) { struct btrfs_fs_info *fs_info = shrinker->private_data; + const s64 nr = percpu_counter_sum_positive(&fs_info->evictable_extent_maps); + + trace_btrfs_extent_map_shrinker_count(fs_info, sc->nr_to_scan, nr); - return percpu_counter_sum_positive(&fs_info->evictable_extent_maps); + return nr; } int btrfs_register_extent_map_shrinker(struct btrfs_fs_info *fs_info) diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h index 766cfd48386c..ba49efa2bc74 100644 --- a/include/trace/events/btrfs.h +++ b/include/trace/events/btrfs.h @@ -2551,6 +2551,98 @@ 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, u64 nr_to_scan, u64 nr), + + TP_ARGS(fs_info, nr_to_scan, nr), + + TP_STRUCT__entry_btrfs( + __field( u64, nr_to_scan ) + __field( u64, nr ) + ), + + TP_fast_assign_btrfs(fs_info, + __entry->nr_to_scan = nr_to_scan; + __entry->nr = nr; + ), + + TP_printk_btrfs("nr_to_scan=%llu nr=%llu", + __entry->nr_to_scan, __entry->nr) +); + +TRACE_EVENT(btrfs_extent_map_shrinker_scan_enter, + + TP_PROTO(const struct btrfs_fs_info *fs_info, u64 nr_to_scan, u64 nr), + + TP_ARGS(fs_info, nr_to_scan, nr), + + TP_STRUCT__entry_btrfs( + __field( u64, nr_to_scan ) + __field( u64, nr ) + ), + + TP_fast_assign_btrfs(fs_info, + __entry->nr_to_scan = nr_to_scan; + __entry->nr = nr; + ), + + TP_printk_btrfs("nr_to_scan=%llu nr=%llu", + __entry->nr_to_scan, __entry->nr) +); + +TRACE_EVENT(btrfs_extent_map_shrinker_scan_exit, + + TP_PROTO(const struct btrfs_fs_info *fs_info, u64 nr_dropped, u64 nr), + + TP_ARGS(fs_info, nr_dropped, nr), + + TP_STRUCT__entry_btrfs( + __field( u64, nr_dropped ) + __field( u64, nr ) + ), + + TP_fast_assign_btrfs(fs_info, + __entry->nr_dropped = nr_dropped; + __entry->nr = nr; + ), + + TP_printk_btrfs("nr_dropped=%llu nr=%llu", + __entry->nr_dropped, __entry->nr) +); + +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 */