From patchwork Thu May 4 10:12:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13230992 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C2A04C77B78 for ; Thu, 4 May 2023 10:12:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230169AbjEDKMX (ORCPT ); Thu, 4 May 2023 06:12:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44368 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230116AbjEDKMT (ORCPT ); Thu, 4 May 2023 06:12:19 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3E4524C26; Thu, 4 May 2023 03:12:16 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 660A0632D4; Thu, 4 May 2023 10:12:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D97E4C433D2; Thu, 4 May 2023 10:12:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1683195135; bh=onvVQ3+1KpThaLhopBbyOqMFIiqDs9AO5jNZlwVbH8c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DkbyU9ry46ovyngXuBT//AFYDo8oI14c6vKqLk8bR+ekurqBSN4JeeDF9LPPwLKqz mz1HGe4ETPGa6LftRurkFPAI+sw+ptJaYSZ3Sut+4mwkIEJMQ3NY/uqJ/goarZPpEG 6FPm6xm6zR3RvywYpEVMhc0zBCuMsl6x2IjOjK9PgE5JFymlUZiu4ZtT+z8/HZMw0G xrpjHKhbOgMkt7v5plBffKhYjdLboSjZ8NzJjDU9boqZAsVSmqVkkC2fMy783j3sR5 F8g3hNWEUTgTKJF3CtK8YBsGWLUTFjhBdsEMi2nCVF5fuDb4Qhw9yNgSyRtWuY1Vbj q01FZs7l5SXDQ== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Cc: git@vladimir.panteleev.md, Filipe Manana , stable@vger.kernel.org Subject: [PATCH v2] btrfs: fix backref walking not returning all inode refs Date: Thu, 4 May 2023 11:12:03 +0100 Message-Id: X-Mailer: git-send-email 2.25.1 In-Reply-To: <77994dd9ede2084d45dd0a36938c67de70d8e859.1683123587.git.fdmanana@suse.com> References: <77994dd9ede2084d45dd0a36938c67de70d8e859.1683123587.git.fdmanana@suse.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Filipe Manana When using the logical to ino ioctl v2, if the flag to ignore offsets of file extent items (BTRFS_LOGICAL_INO_ARGS_IGNORE_OFFSET) is given, the backref walking code ends up not returning references for all file offsets of an inode that point to the given logical bytenr. This happens since kernel 6.2, commit 6ce6ba534418 ("btrfs: use a single argument for extent offset in backref walking functions"), as it mistakenly skipped the search for file extent items in a leaf that point to the target extent if that flag is given. Instead it should only skip the filtering done by check_extent_in_eb() - that is, it should not avoid the calls to that function (or find_extent_in_eb(), which uses it). So fix this by always calling check_extent_in_eb() and find_extent_in_eb() and have check_extent_in_eb() do the filtering only if the flag to ignore offsets is set. Fixes: 6ce6ba534418 ("btrfs: use a single argument for extent offset in backref walking functions") Reported-by: Vladimir Panteleev Link: https://lore.kernel.org/linux-btrfs/CAHhfkvwo=nmzrJSqZ2qMfF-rZB-ab6ahHnCD_sq9h4o8v+M7QQ@mail.gmail.com/ Tested-by: Vladimir Panteleev CC: stable@vger.kernel.org # 6.2+ Signed-off-by: Filipe Manana --- V2: Remove wrong check for a non-zero extent item offset. Apply the same logic at find_parent_nodes(), that is, search for file extent items on a leaf if the ignore flag is given - the filtering will be done later at check_extent_in_eb(). Spotted by Vladimir Panteleev in the thread mentioned above. fs/btrfs/backref.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index e54f0884802a..787417f9893c 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -45,7 +45,8 @@ static int check_extent_in_eb(struct btrfs_backref_walk_ctx *ctx, int root_count; bool cached; - if (!btrfs_file_extent_compression(eb, fi) && + if (!ctx->ignore_extent_item_pos && + !btrfs_file_extent_compression(eb, fi) && !btrfs_file_extent_encryption(eb, fi) && !btrfs_file_extent_other_encoding(eb, fi)) { u64 data_offset; @@ -552,13 +553,10 @@ static int add_all_parents(struct btrfs_backref_walk_ctx *ctx, count++; else goto next; - if (!ctx->ignore_extent_item_pos) { - ret = check_extent_in_eb(ctx, &key, eb, fi, &eie); - if (ret == BTRFS_ITERATE_EXTENT_INODES_STOP || - ret < 0) - break; - } - if (ret > 0) + ret = check_extent_in_eb(ctx, &key, eb, fi, &eie); + if (ret == BTRFS_ITERATE_EXTENT_INODES_STOP || ret < 0) + break; + else if (ret > 0) goto next; ret = ulist_add_merge_ptr(parents, eb->start, eie, (void **)&old, GFP_NOFS); @@ -1606,8 +1604,7 @@ static int find_parent_nodes(struct btrfs_backref_walk_ctx *ctx, goto out; } if (ref->count && ref->parent) { - if (!ctx->ignore_extent_item_pos && !ref->inode_list && - ref->level == 0) { + if (!ref->inode_list && ref->level == 0) { struct btrfs_tree_parent_check check = { 0 }; struct extent_buffer *eb;