• Qu Wenruo's avatar
    btrfs: handle tree backref walk error properly · b7f9945a
    Qu Wenruo authored
    [BUG]
    Smatch reports the following errors related to commit ("btrfs: output
    affected files when relocation fails"):
    
    	fs/btrfs/inode.c:283 print_data_reloc_error()
    	error: uninitialized symbol 'ref_level'.
    
    [CAUSE]
    That part of code is mostly copied from scrub, but unfortunately scrub
    code from the beginning is not doing the error handling properly.
    
    The offending code looks like this:
    
    	do {
    		ret = tree_backref_for_extent();
    		btrfs_warn_rl();
    	} while (ret != 1);
    
    There are several problems involved:
    
    - No error handling
      If that tree_backref_for_extent() failed, we would output the same
      error again and again, never really exit as it requires ret == 1 to
      exit.
    
    - Always do one extra output
      As tree_backref_for_extent() only return > 0 if there is no more
      backref item.
      This means after the last item we hit, we would output an invalid
      error message for ret > 0 case.
    
    [FIX]
    Fix the old code by:
    
    - Move @ref_root and @ref_level into the if branch
      And do not initialize them, so we can catch such uninitialized values
      just like what we do in the inode.c
    
    - Explicitly check the return value of tree_backref_for_extent()
      And handle ret < 0 and ret > 0 cases properly.
    
    - No more do {} while () loop
      Instead go while (true) {} loop since we will handle @ret manually.
    Reported-by: default avatarDan Carpenter <dan.carpenter@linaro.org>
    Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
    Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    b7f9945a
inode.c 317 KB