public inbox for linux-btrfs@vger.kernel.org
 help / color / mirror / Atom feed
From: David Sterba <dsterba@suse.cz>
To: Qu Wenruo <wqu@suse.com>
Cc: linux-btrfs@vger.kernel.org
Subject: Re: [PATCH v2 2/6] btrfs-progs: fix a bug in btrfs_find_item()
Date: Fri, 30 May 2025 13:11:41 +0200	[thread overview]
Message-ID: <20250530111141.GR4037@twin.jikos.cz> (raw)
In-Reply-To: <7c72856dd5939761a9dd34a4554fddf94389090d.1747295965.git.wqu@suse.com>

On Thu, May 15, 2025 at 05:30:17PM +0930, Qu Wenruo wrote:
> [BUG]
> There is a seldomly utilized function, btrfs_find_item(), which has no
> document and is not behaving correctly.
> 
> Inside backref.c, iterate_inode_refs() and btrfs_ref_to_path() both
> utilize this function, to find the parent inode.
> 
> However btrfs_find_item() will never return 0 if @ioff is passed as 0
> for such usage, result early failure for all kinds of inode iteration
> functions.
> 
> [CAUSE]
> Both functions pass 0 as the @ioff parameter initially, e.g:
> 
>  We have the following fs tree root:
> 
>   	item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160
> 		generation 3 transid 9 size 6 nbytes 16384
> 		block group 0 mode 40755 links 1 uid 0 gid 0 rdev 0
> 		sequence 1 flags 0x0(none)
> 	item 1 key (256 INODE_REF 256) itemoff 16111 itemsize 12
> 		index 0 namelen 2 name: ..
> 	item 2 key (256 DIR_ITEM 2507850652) itemoff 16078 itemsize 33
> 		location key (257 INODE_ITEM 0) type FILE
> 		transid 9 data_len 0 name_len 3
> 		name: foo
> 	item 3 key (256 DIR_INDEX 2) itemoff 16045 itemsize 33
> 		location key (257 INODE_ITEM 0) type FILE
> 		transid 9 data_len 0 name_len 3
> 		name: foo
> 	item 4 key (257 INODE_ITEM 0) itemoff 15885 itemsize 160
> 		generation 9 transid 9 size 16384 nbytes 16384
> 		block group 0 mode 100600 links 1 uid 0 gid 0 rdev 0
> 		sequence 4 flags 0x0(none)
> 	item 5 key (257 INODE_REF 256) itemoff 15872 itemsize 13
> 		index 2 namelen 3 name: foo
> 	item 6 key (257 EXTENT_DATA 0) itemoff 15819 itemsize 53
> 		generation 9 type 1 (regular)
> 		extent data disk byte 13631488 nr 16384
> 		extent data offset 0 nr 16384 ram 16384
> 		extent compression 0 (none)
> 
>   Then we call paths_from_inode() with:
>   - @inum = 257
>   - ipath = {.fs_root = 5}
> 
>   Then we got the following sequence:
> 
>   iterate_irefs(257, fs_root, inode_to_path)
>   |- iterate_inode_refs()
>      |- inode_ref_info()
>         |- btrfs_find_item(257, 0, fs_root)
> 	|  Returned 1, with @found_key updated to
> 	|  (257, INODE_REF, 256).
> 
>   This makes iterate_irefs() exit immediately, but obviously that
>   btrfs_find_item() call is to find any INODE_REF, not to find the
>   exact match.
> 
> [FIX]
> If btrfs_find_item() found an item matching the objectid and type, then
> it should return 0 other than 1.
> 
> Fix it and keep the behavior the same across btrfs-progs and the kernel.
> 
> Since we're here, also add some comments explaining the function.
> 
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> ---
>  kernel-shared/ctree.c | 17 ++++++++++++++---
>  1 file changed, 14 insertions(+), 3 deletions(-)
> 
> diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c
> index 3184c916175e..f90de606e7b1 100644
> --- a/kernel-shared/ctree.c
> +++ b/kernel-shared/ctree.c
> @@ -1246,6 +1246,17 @@ static void reada_for_search(struct btrfs_fs_info *fs_info,
>  	}
>  }
>  
> +/*
> + * Find the first key in @fs_root that matches all the following conditions:
> + *
> + * - key.obojectid == @iobjectid
> + * - key.type == @key_type
> + * - key.offset >= ioff
> + *
> + * Return 0 if such key can be found, and @found_key is updated.
> + * Return >0 if no such key can be found.
> + * Return <0 for critical errors.
> + */
>  int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path,
>  		u64 iobjectid, u64 ioff, u8 key_type,
>  		struct btrfs_key *found_key)
> @@ -1280,10 +1291,10 @@ int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path,
>  
>  	btrfs_item_key_to_cpu(eb, found_key, path->slots[0]);
>  	if (found_key->type != key.type ||
> -			found_key->objectid != key.objectid) {
> +	    found_key->objectid != key.objectid)

This fits one line. We don't have perfect 1:1 line matching with kernel
so the style can be fixed.

>  		ret = 1;
> -		goto out;
> -	}
> +	else
> +		ret = 0;
>  
>  out:
>  	if (path != found_path)
> -- 
> 2.49.0
> 

  reply	other threads:[~2025-05-30 11:11 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-15  8:00 [PATCH v2 0/6] btrfs-progs: introduce "btrfs rescue fix-data-checksum" Qu Wenruo
2025-05-15  8:00 ` [PATCH v2 1/6] " Qu Wenruo
2025-05-30 11:10   ` David Sterba
2025-05-15  8:00 ` [PATCH v2 2/6] btrfs-progs: fix a bug in btrfs_find_item() Qu Wenruo
2025-05-30 11:11   ` David Sterba [this message]
2025-05-15  8:00 ` [PATCH v2 3/6] btrfs-progs: fix-data-checksum: show affected files Qu Wenruo
2025-05-30 11:14   ` David Sterba
2025-05-15  8:00 ` [PATCH v2 4/6] btrfs-progs: fix-data-checksum: introduce interactive mode Qu Wenruo
2025-05-30 11:18   ` David Sterba
2025-05-15  8:00 ` [PATCH v2 5/6] btrfs-progs: fix-data-checksum: update csum items to fix csum mismatch Qu Wenruo
2025-05-30 11:19   ` David Sterba
2025-05-30 22:23     ` Qu Wenruo
2025-05-15  8:00 ` [PATCH v2 6/6] btrfs-progs: fix-data-checksum: introduce -m|--mirror option Qu Wenruo
2025-05-30 11:07 ` [PATCH v2 0/6] btrfs-progs: introduce "btrfs rescue fix-data-checksum" David Sterba
2025-05-31 16:58 ` Goffredo Baroncelli
2025-05-31 22:07   ` Qu Wenruo
2025-06-02 17:28     ` Goffredo Baroncelli
2025-06-02 22:55       ` Qu Wenruo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250530111141.GR4037@twin.jikos.cz \
    --to=dsterba@suse.cz \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=wqu@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox