Skip to content

Commit 68a7449

Browse files
GustavoARSilvaMikulas Patocka
authored andcommitted
fs: hpfs: Avoid multiple -Wflex-array-member-not-at-end warnings
-Wflex-array-member-not-at-end was introduced in GCC-14, and we are getting ready to enable it, globally. So, in order to avoid ending up with a flexible-array member in the middle of other structs, we use the `struct_group_tagged()` helper to create a new tagged `struct bplus_header_fixed`. This structure groups together all the members of the flexible `struct bplus_header` except the flexible array. As a result, the array is effectively separated from the rest of the members without modifying the memory layout of the flexible structure. We then change the type of the middle struct member currently causing trouble from `struct bplus_header` to `struct bplus_header_fixed`. We also want to ensure that when new members need to be added to the flexible structure, they are always included within the newly created tagged struct. For this, we use `static_assert()`. This ensures that the memory layout for both the flexible structure and the new tagged struct is the same after any changes. This approach avoids having to implement `struct bplus_header_fixed` as a completely separate structure, thus preventing having to maintain two independent but basically identical structures, closing the door to potential bugs in the future. We also use `container_of()` (via a wrapper) whenever we need to retrieve a pointer to the flexible structure, through which we can access the flexible-array member, if necessary. So, with these changes, fix 26 of the following type of warnings: fs/hpfs/hpfs.h:456:23: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] fs/hpfs/hpfs.h:498:23: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] Signed-off-by: Gustavo A. R. Silva <[email protected]> Signed-off-by: Mikulas Patocka <[email protected]>
1 parent 76eeb9b commit 68a7449

File tree

5 files changed

+61
-40
lines changed

5 files changed

+61
-40
lines changed

fs/hpfs/anode.c

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ secno hpfs_bplus_lookup(struct super_block *s, struct inode *inode,
2727
a = le32_to_cpu(btree->u.internal[i].down);
2828
brelse(bh);
2929
if (!(anode = hpfs_map_anode(s, a, &bh))) return -1;
30-
btree = &anode->btree;
30+
btree = GET_BTREE_PTR(&anode->btree);
3131
goto go_down;
3232
}
3333
hpfs_error(s, "sector %08x not found in internal anode %08x", sec, a);
@@ -69,12 +69,13 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
6969
int n;
7070
unsigned fs;
7171
int c1, c2 = 0;
72+
7273
if (fnod) {
7374
if (!(fnode = hpfs_map_fnode(s, node, &bh))) return -1;
74-
btree = &fnode->btree;
75+
btree = GET_BTREE_PTR(&fnode->btree);
7576
} else {
7677
if (!(anode = hpfs_map_anode(s, node, &bh))) return -1;
77-
btree = &anode->btree;
78+
btree = GET_BTREE_PTR(&anode->btree);
7879
}
7980
a = node;
8081
go_down:
@@ -91,7 +92,7 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
9192
if (hpfs_sb(s)->sb_chk)
9293
if (hpfs_stop_cycles(s, a, &c1, &c2, "hpfs_add_sector_to_btree #1")) return -1;
9394
if (!(anode = hpfs_map_anode(s, a, &bh))) return -1;
94-
btree = &anode->btree;
95+
btree = GET_BTREE_PTR(&anode->btree);
9596
goto go_down;
9697
}
9798
if (n >= 0) {
@@ -151,7 +152,7 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
151152
}
152153
brelse(bh);
153154
bh = bh1;
154-
btree = &anode->btree;
155+
btree = GET_BTREE_PTR(&anode->btree);
155156
}
156157
btree->n_free_nodes--; n = btree->n_used_nodes++;
157158
le16_add_cpu(&btree->first_free, 12);
@@ -168,10 +169,10 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
168169
if (hpfs_stop_cycles(s, up, &c1, &c2, "hpfs_add_sector_to_btree #2")) return -1;
169170
if (up != node || !fnod) {
170171
if (!(anode = hpfs_map_anode(s, up, &bh))) return -1;
171-
btree = &anode->btree;
172+
btree = GET_BTREE_PTR(&anode->btree);
172173
} else {
173174
if (!(fnode = hpfs_map_fnode(s, up, &bh))) return -1;
174-
btree = &fnode->btree;
175+
btree = GET_BTREE_PTR(&fnode->btree);
175176
}
176177
if (btree->n_free_nodes) {
177178
btree->n_free_nodes--; n = btree->n_used_nodes++;
@@ -206,8 +207,8 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
206207
anode->btree.n_used_nodes = 1;
207208
anode->btree.n_free_nodes = 59;
208209
anode->btree.first_free = cpu_to_le16(16);
209-
anode->btree.u.internal[0].down = cpu_to_le32(a);
210-
anode->btree.u.internal[0].file_secno = cpu_to_le32(-1);
210+
GET_BTREE_PTR(&anode->btree)->u.internal[0].down = cpu_to_le32(a);
211+
GET_BTREE_PTR(&anode->btree)->u.internal[0].file_secno = cpu_to_le32(-1);
211212
mark_buffer_dirty(bh);
212213
brelse(bh);
213214
if ((anode = hpfs_map_anode(s, a, &bh))) {
@@ -229,20 +230,20 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
229230
brelse(bh2);
230231
return -1;
231232
}
232-
btree = &anode->btree;
233+
btree = GET_BTREE_PTR(&anode->btree);
233234
} else {
234235
if (!(fnode = hpfs_map_fnode(s, node, &bh))) {
235236
brelse(bh2);
236237
return -1;
237238
}
238-
btree = &fnode->btree;
239+
btree = GET_BTREE_PTR(&fnode->btree);
239240
}
240241
ranode->up = cpu_to_le32(node);
241242
memcpy(&ranode->btree, btree, le16_to_cpu(btree->first_free));
242243
if (fnod)
243244
ranode->btree.flags |= BP_fnode_parent;
244-
ranode->btree.n_free_nodes = (bp_internal(&ranode->btree) ? 60 : 40) - ranode->btree.n_used_nodes;
245-
if (bp_internal(&ranode->btree)) for (n = 0; n < ranode->btree.n_used_nodes; n++) {
245+
GET_BTREE_PTR(&ranode->btree)->n_free_nodes = (bp_internal(GET_BTREE_PTR(&ranode->btree)) ? 60 : 40) - GET_BTREE_PTR(&ranode->btree)->n_used_nodes;
246+
if (bp_internal(GET_BTREE_PTR(&ranode->btree))) for (n = 0; n < GET_BTREE_PTR(&ranode->btree)->n_used_nodes; n++) {
246247
struct anode *unode;
247248
if ((unode = hpfs_map_anode(s, le32_to_cpu(ranode->u.internal[n].down), &bh1))) {
248249
unode->up = cpu_to_le32(ra);
@@ -291,7 +292,7 @@ void hpfs_remove_btree(struct super_block *s, struct bplus_header *btree)
291292
if (hpfs_stop_cycles(s, ano, &d1, &d2, "hpfs_remove_btree #1"))
292293
return;
293294
if (!(anode = hpfs_map_anode(s, ano, &bh))) return;
294-
btree1 = &anode->btree;
295+
btree1 = GET_BTREE_PTR(&anode->btree);
295296
level++;
296297
pos = 0;
297298
}
@@ -307,7 +308,7 @@ void hpfs_remove_btree(struct super_block *s, struct bplus_header *btree)
307308
ano = le32_to_cpu(anode->up);
308309
if (--level) {
309310
if (!(anode = hpfs_map_anode(s, ano, &bh))) return;
310-
btree1 = &anode->btree;
311+
btree1 = GET_BTREE_PTR(&anode->btree);
311312
} else btree1 = btree;
312313
for (i = 0; i < btree1->n_used_nodes; i++) {
313314
if (le32_to_cpu(btree1->u.internal[i].down) == oano) {
@@ -332,7 +333,7 @@ static secno anode_lookup(struct super_block *s, anode_secno a, unsigned sec)
332333
struct anode *anode;
333334
struct buffer_head *bh;
334335
if (!(anode = hpfs_map_anode(s, a, &bh))) return -1;
335-
return hpfs_bplus_lookup(s, NULL, &anode->btree, sec, bh);
336+
return hpfs_bplus_lookup(s, NULL, GET_BTREE_PTR(&anode->btree), sec, bh);
336337
}
337338

338339
int hpfs_ea_read(struct super_block *s, secno a, int ano, unsigned pos,
@@ -388,7 +389,7 @@ void hpfs_ea_remove(struct super_block *s, secno a, int ano, unsigned len)
388389
struct buffer_head *bh;
389390
if (ano) {
390391
if (!(anode = hpfs_map_anode(s, a, &bh))) return;
391-
hpfs_remove_btree(s, &anode->btree);
392+
hpfs_remove_btree(s, GET_BTREE_PTR(&anode->btree));
392393
brelse(bh);
393394
hpfs_free_sectors(s, a, 1);
394395
} else hpfs_free_sectors(s, a, (len + 511) >> 9);
@@ -407,10 +408,10 @@ void hpfs_truncate_btree(struct super_block *s, secno f, int fno, unsigned secs)
407408
int c1, c2 = 0;
408409
if (fno) {
409410
if (!(fnode = hpfs_map_fnode(s, f, &bh))) return;
410-
btree = &fnode->btree;
411+
btree = GET_BTREE_PTR(&fnode->btree);
411412
} else {
412413
if (!(anode = hpfs_map_anode(s, f, &bh))) return;
413-
btree = &anode->btree;
414+
btree = GET_BTREE_PTR(&anode->btree);
414415
}
415416
if (!secs) {
416417
hpfs_remove_btree(s, btree);
@@ -448,7 +449,7 @@ void hpfs_truncate_btree(struct super_block *s, secno f, int fno, unsigned secs)
448449
if (hpfs_stop_cycles(s, node, &c1, &c2, "hpfs_truncate_btree"))
449450
return;
450451
if (!(anode = hpfs_map_anode(s, node, &bh))) return;
451-
btree = &anode->btree;
452+
btree = GET_BTREE_PTR(&anode->btree);
452453
}
453454
nodes = btree->n_used_nodes + btree->n_free_nodes;
454455
for (i = 0; i < btree->n_used_nodes; i++)
@@ -485,7 +486,7 @@ void hpfs_remove_fnode(struct super_block *s, fnode_secno fno)
485486
struct extended_attribute *ea;
486487
struct extended_attribute *ea_end;
487488
if (!(fnode = hpfs_map_fnode(s, fno, &bh))) return;
488-
if (!fnode_is_dir(fnode)) hpfs_remove_btree(s, &fnode->btree);
489+
if (!fnode_is_dir(fnode)) hpfs_remove_btree(s, GET_BTREE_PTR(&fnode->btree));
489490
else hpfs_remove_dtree(s, le32_to_cpu(fnode->u.external[0].disk_secno));
490491
ea_end = fnode_end_ea(fnode);
491492
for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))

fs/hpfs/ea.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
4141
struct buffer_head *bh;
4242
struct anode *anode;
4343
if ((anode = hpfs_map_anode(s, a, &bh))) {
44-
hpfs_remove_btree(s, &anode->btree);
44+
hpfs_remove_btree(s, GET_BTREE_PTR(&anode->btree));
4545
brelse(bh);
4646
hpfs_free_sectors(s, a, 1);
4747
}

fs/hpfs/file.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ static secno hpfs_bmap(struct inode *inode, unsigned file_secno, unsigned *n_sec
5151
return hpfs_inode->i_disk_sec + n;
5252
}
5353
if (!(fnode = hpfs_map_fnode(inode->i_sb, inode->i_ino, &bh))) return 0;
54-
disk_secno = hpfs_bplus_lookup(inode->i_sb, inode, &fnode->btree, file_secno, bh);
54+
disk_secno = hpfs_bplus_lookup(inode->i_sb, inode,
55+
GET_BTREE_PTR(&fnode->btree),
56+
file_secno, bh);
5557
if (disk_secno == -1) return 0;
5658
if (hpfs_chk_sectors(inode->i_sb, disk_secno, 1, "bmap")) return 0;
5759
n = file_secno - hpfs_inode->i_file_sec;

fs/hpfs/hpfs.h

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -394,27 +394,45 @@ enum {
394394
BP_binary_search = 0x40,
395395
BP_internal = 0x80
396396
};
397+
398+
/**
399+
* GET_BTREE_PTR() - Get a pointer to struct bplus_header
400+
*
401+
* Wrapper around container_of() to retrieve a pointer to struct
402+
* bplus_header from a pointer to struct bplus_header_fixed.
403+
*
404+
* @ptr: Pointer to struct bplus_header_fixed.
405+
*
406+
*/
407+
#define GET_BTREE_PTR(ptr) \
408+
container_of(ptr, struct bplus_header, __hdr)
409+
397410
struct bplus_header
398411
{
399-
u8 flags; /* bit 0 - high bit of first free entry offset
412+
/* New members MUST be added within the struct_group() macro below. */
413+
struct_group_tagged(bplus_header_fixed, __hdr,
414+
u8 flags; /* bit 0 - high bit of first free entry offset
400415
bit 5 - we're pointed to by an fnode,
401416
the data btree or some ea or the
402417
main ea bootage pointer ea_secno
403418
bit 6 - suggest binary search (unused)
404419
bit 7 - 1 -> (internal) tree of anodes
405420
0 -> (leaf) list of extents */
406-
u8 fill[3];
407-
u8 n_free_nodes; /* free nodes in following array */
408-
u8 n_used_nodes; /* used nodes in following array */
409-
__le16 first_free; /* offset from start of header to
421+
u8 fill[3];
422+
u8 n_free_nodes; /* free nodes in following array */
423+
u8 n_used_nodes; /* used nodes in following array */
424+
__le16 first_free; /* offset from start of header to
410425
first free node in array */
411-
union {
412-
/* (internal) 2-word entries giving subtree pointers */
413-
DECLARE_FLEX_ARRAY(struct bplus_internal_node, internal);
414-
/* (external) 3-word entries giving sector runs */
415-
DECLARE_FLEX_ARRAY(struct bplus_leaf_node, external);
416-
} u;
426+
);
427+
union {
428+
/* (internal) 2-word entries giving subtree pointers */
429+
DECLARE_FLEX_ARRAY(struct bplus_internal_node, internal);
430+
/* (external) 3-word entries giving sector runs */
431+
DECLARE_FLEX_ARRAY(struct bplus_leaf_node, external);
432+
} u;
417433
};
434+
static_assert(offsetof(struct bplus_header, u.internal) == sizeof(struct bplus_header_fixed),
435+
"struct member likely outside of struct_group_tagged()");
418436

419437
static inline bool bp_internal(struct bplus_header *bp)
420438
{
@@ -453,7 +471,7 @@ struct fnode
453471
__le16 flags; /* bit 1 set -> ea_secno is an anode */
454472
/* bit 8 set -> directory. first & only extent
455473
points to dnode. */
456-
struct bplus_header btree; /* b+ tree, 8 extents or 12 subtrees */
474+
struct bplus_header_fixed btree; /* b+ tree, 8 extents or 12 subtrees */
457475
union {
458476
struct bplus_leaf_node external[8];
459477
struct bplus_internal_node internal[12];
@@ -495,7 +513,7 @@ struct anode
495513
__le32 self; /* pointer to this anode */
496514
__le32 up; /* parent anode or fnode */
497515

498-
struct bplus_header btree; /* b+tree, 40 extents or 60 subtrees */
516+
struct bplus_header_fixed btree; /* b+tree, 40 extents or 60 subtrees */
499517
union {
500518
struct bplus_leaf_node external[40];
501519
struct bplus_internal_node internal[60];

fs/hpfs/map.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,14 @@ struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_hea
178178
}
179179
if (!fnode_is_dir(fnode)) {
180180
if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes !=
181-
(bp_internal(&fnode->btree) ? 12 : 8)) {
181+
(bp_internal(GET_BTREE_PTR(&fnode->btree)) ? 12 : 8)) {
182182
hpfs_error(s,
183183
"bad number of nodes in fnode %08lx",
184184
(unsigned long)ino);
185185
goto bail;
186186
}
187187
if (le16_to_cpu(fnode->btree.first_free) !=
188-
8 + fnode->btree.n_used_nodes * (bp_internal(&fnode->btree) ? 8 : 12)) {
188+
8 + fnode->btree.n_used_nodes * (bp_internal(GET_BTREE_PTR(&fnode->btree)) ? 8 : 12)) {
189189
hpfs_error(s,
190190
"bad first_free pointer in fnode %08lx",
191191
(unsigned long)ino);
@@ -233,12 +233,12 @@ struct anode *hpfs_map_anode(struct super_block *s, anode_secno ano, struct buff
233233
goto bail;
234234
}
235235
if ((unsigned)anode->btree.n_used_nodes + (unsigned)anode->btree.n_free_nodes !=
236-
(bp_internal(&anode->btree) ? 60 : 40)) {
236+
(bp_internal(GET_BTREE_PTR(&anode->btree)) ? 60 : 40)) {
237237
hpfs_error(s, "bad number of nodes in anode %08x", ano);
238238
goto bail;
239239
}
240240
if (le16_to_cpu(anode->btree.first_free) !=
241-
8 + anode->btree.n_used_nodes * (bp_internal(&anode->btree) ? 8 : 12)) {
241+
8 + anode->btree.n_used_nodes * (bp_internal(GET_BTREE_PTR(&anode->btree)) ? 8 : 12)) {
242242
hpfs_error(s, "bad first_free pointer in anode %08x", ano);
243243
goto bail;
244244
}

0 commit comments

Comments
 (0)