Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

md/raid5: Convert stripe_head's "dev" to flexible array member

Replace old-style 1-element array of "dev" in struct stripe_head with
modern C99 flexible array. In the future, we can additionally annotate
it with the run-time size, found in the "disks" member.

Cc: Song Liu <song@kernel.org>
Cc: linux-raid@vger.kernel.org
Reviewed-by: Christoph Hellwig <hch@lst.de>
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/lkml/20230522212114.gonna.589-kees@kernel.org/
---
It looks like this memory calculation:

memory = conf->min_nr_stripes * (sizeof(struct stripe_head) +
max_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;

... was already buggy (i.e. it included the single "dev" bytes in the
result). However, I'm not entirely sure if that is the right analysis,
since "dev" is not related to struct bio nor PAGE_SIZE?

+3 -3
+2 -2
drivers/md/raid5.c
··· 2433 2433 2434 2434 conf->active_name = 0; 2435 2435 sc = kmem_cache_create(conf->cache_name[conf->active_name], 2436 - sizeof(struct stripe_head)+(devs-1)*sizeof(struct r5dev), 2436 + struct_size_t(struct stripe_head, dev, devs), 2437 2437 0, 0, NULL); 2438 2438 if (!sc) 2439 2439 return 1; ··· 2559 2559 2560 2560 /* Step 1 */ 2561 2561 sc = kmem_cache_create(conf->cache_name[1-conf->active_name], 2562 - sizeof(struct stripe_head)+(newsize-1)*sizeof(struct r5dev), 2562 + struct_size_t(struct stripe_head, dev, newsize), 2563 2563 0, 0, NULL); 2564 2564 if (!sc) 2565 2565 return -ENOMEM;
+1 -1
drivers/md/raid5.h
··· 268 268 unsigned long flags; 269 269 u32 log_checksum; 270 270 unsigned short write_hint; 271 - } dev[1]; /* allocated with extra space depending of RAID geometry */ 271 + } dev[]; /* allocated depending of RAID geometry ("disks" member) */ 272 272 }; 273 273 274 274 /* stripe_head_state - collects and tracks the dynamic state of a stripe_head