btrfs: make sure to initialize start and len in find_free_dev_extent
authorJosef Bacik <josef@toxicpanda.com>
Tue, 5 Sep 2023 16:15:23 +0000 (12:15 -0400)
committerDavid Sterba <dsterba@suse.com>
Thu, 21 Sep 2023 16:52:20 +0000 (18:52 +0200)
Jens reported a compiler error when using CONFIG_CC_OPTIMIZE_FOR_SIZE=y
that looks like this

  In function ‘gather_device_info’,
      inlined from ‘btrfs_create_chunk’ at fs/btrfs/volumes.c:5507:8:
  fs/btrfs/volumes.c:5245:48: warning: ‘dev_offset’ may be used uninitialized [-Wmaybe-uninitialized]
   5245 |                 devices_info[ndevs].dev_offset = dev_offset;
|                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~
  fs/btrfs/volumes.c: In function ‘btrfs_create_chunk’:
  fs/btrfs/volumes.c:5196:13: note: ‘dev_offset’ was declared here
   5196 |         u64 dev_offset;

This occurs because find_free_dev_extent is responsible for setting
dev_offset, however if we get an -ENOMEM at the top of the function
we'll return without setting the value.

This isn't actually a problem because we will see the -ENOMEM in
gather_device_info() and return and not use the uninitialized value,
however we also just don't want the compiler warning so rework the code
slightly in find_free_dev_extent() to make sure it's always setting
*start and *len to avoid the compiler warning.

Reported-by: Jens Axboe <axboe@kernel.dk>
Tested-by: Jens Axboe <axboe@kernel.dk>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/volumes.c

index 7338421..e3a3769 100644 (file)
@@ -1594,7 +1594,7 @@ static int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes,
        u64 search_start;
        u64 hole_size;
        u64 max_hole_start;
-       u64 max_hole_size;
+       u64 max_hole_size = 0;
        u64 extent_end;
        u64 search_end = device->total_bytes;
        int ret;
@@ -1602,17 +1602,16 @@ static int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes,
        struct extent_buffer *l;
 
        search_start = dev_extent_search_start(device);
+       max_hole_start = search_start;
 
        WARN_ON(device->zone_info &&
                !IS_ALIGNED(num_bytes, device->zone_info->zone_size));
 
        path = btrfs_alloc_path();
-       if (!path)
-               return -ENOMEM;
-
-       max_hole_start = search_start;
-       max_hole_size = 0;
-
+       if (!path) {
+               ret = -ENOMEM;
+               goto out;
+       }
 again:
        if (search_start >= search_end ||
                test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state)) {