btrfs-progs: send: add gcc9 workaround for root item reset

Gcc version 9.1.1 reports:

In file included from /usr/include/string.h:494,
                 from kerncompat.h:25,
                 from ctree.h:26,
                 from send-utils.c:26:
In function ‘memset’,
    inlined from ‘btrfs_read_root_item’ at send-utils.c:165:3,
    inlined from ‘subvol_uuid_search2’ at send-utils.c:494:8:
/usr/include/bits/string_fortified.h:71:10: warning: ‘__builtin_memset’ offset [248, 439] from the object at ‘root_item’ is out of the bounds of referenced subobject ‘generation_v2’ with type ‘long long unsigned int’ at offset 239 [-Warray-bounds]
   71 |   return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

That's correct in case the intent is to overwrite just the generation_v2
member, but we want to zero the rest of the root item structure starting
from the generation_v2. No typecasts can obscure that from gcc so the
starting address is calculated as base pointer + member offset.

Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
David Sterba 2019-07-02 12:50:14 +02:00
parent a62b7854de
commit 5f5c497c8b

View File

@ -151,10 +151,21 @@ static int btrfs_read_root_item(int mnt_fd, u64 root_id,
return ret;
if (read_len < sizeof(*item) ||
btrfs_root_generation(item) != btrfs_root_generation_v2(item))
memset(&item->generation_v2, 0,
btrfs_root_generation(item) != btrfs_root_generation_v2(item)) {
/*
* Workaround for gcc9 that warns that memset over
* generation_v2 overflows, which is what we want but would
* be otherwise a bug
*
* The below is &item->generation_v2
*/
char *start = (char *)item + offsetof(struct btrfs_root_item,
generation_v2);
memset(start, 0,
sizeof(*item) - offsetof(struct btrfs_root_item,
generation_v2));
}
return 0;
}