On Fri, Apr 19, 2024 at 03:48:50PM +0800, Hongbo Li wrote:
> [BUG]
> When compiling the bcachefs-tools, the following compilation warning
> is reported:
>     libbcachefs/snapshot.c: In function ‘bch2_reconstruct_snapshots’:
>     libbcachefs/snapshot.c:915:19: warning: ‘tree_id’ may be used 
> uninitialized in this function [-Wmaybe-uninitialized]
>       915 |  snapshot->v.tree = cpu_to_le32(tree_id);
>     libbcachefs/snapshot.c:903:6: note: ‘tree_id’ was declared here
>       903 |  u32 tree_id;
>        |      ^~~~~~~
> 
> [CAUSE]
> This is a false alert, because @tree_id is changed in
> bch2_snapshot_tree_create after it returns 0. And if this function
> returns other value, @tree_id wouldn't be used. Thus there should
> be nothing wrong in logical.
> 
> [FIX]
> Although the report itself is a false alert, we can still make it more
> explicit by:
>   - check the input parameter 'u32 *tree_id' with WARN_ON_ONCE
>   - initialize @tree_id to U32_MAX
>   - add extra WARN_ON_ONCE to make sure @tree_id is updated
> 
> Fixes: a292be3b68f3 ("bcachefs: Reconstruct missing snapshot nodes")
> Signed-off-by: Hongbo Li <[email protected]>
> ---
>  fs/bcachefs/snapshot.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/bcachefs/snapshot.c b/fs/bcachefs/snapshot.c
> index 0b26dee17a5a..cad3408903b2 100644
> --- a/fs/bcachefs/snapshot.c
> +++ b/fs/bcachefs/snapshot.c
> @@ -78,6 +78,7 @@ __bch2_snapshot_tree_create(struct btree_trans *trans)
>  static int bch2_snapshot_tree_create(struct btree_trans *trans,
>                               u32 root_id, u32 subvol_id, u32 *tree_id)
>  {
> +     WARN_ON_ONCE(!tree_id);

There's no point checking for a null pointer like that; the oops from a
null ptr deref gives us exactly the same information.

>       struct bkey_i_snapshot_tree *n_tree =
>               __bch2_snapshot_tree_create(trans);
>  
> @@ -900,7 +901,7 @@ static int check_snapshot_exists(struct btree_trans 
> *trans, u32 id)
>       if (bch2_snapshot_equiv(c, id))
>               return 0;
>  
> -     u32 tree_id;
> +     u32 tree_id = U32_MAX;

Just initialize it to 0. 0 is an invalid tree ID, so it'll be caught by
snapshot_tree_invalid() if it's not set.

>       int ret = bch2_snapshot_tree_create(trans, id, 0, &tree_id);
>       if (ret)
>               return ret;
> @@ -910,6 +911,8 @@ static int check_snapshot_exists(struct btree_trans 
> *trans, u32 id)
>       if (ret)
>               return ret;
>  
> +     /* bch2_snapshot_tree_create returned 0, @tree_id must be updated. */
> +     WARN_ON_ONCE(tree_id == U32_MAX);

Nix this as well.

>       bkey_snapshot_init(&snapshot->k_i);
>       snapshot->k.p           = POS(0, id);
>       snapshot->v.tree        = cpu_to_le32(tree_id);
> -- 
> 2.34.1
> 

Reply via email to