15
15
#include <linux/buffer_head.h>
16
16
#include "qnx4.h"
17
17
18
- /*
19
- * A qnx4 directory entry is an inode entry or link info
20
- * depending on the status field in the last byte. The
21
- * first byte is where the name start either way, and a
22
- * zero means it's empty.
23
- *
24
- * Also, due to a bug in gcc, we don't want to use the
25
- * real (differently sized) name arrays in the inode and
26
- * link entries, but always the 'de_name[]' one in the
27
- * fake struct entry.
28
- *
29
- * See
30
- *
31
- * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578#c6
32
- *
33
- * for details, but basically gcc will take the size of the
34
- * 'name' array from one of the used union entries randomly.
35
- *
36
- * This use of 'de_name[]' (48 bytes) avoids the false positive
37
- * warnings that would happen if gcc decides to use 'inode.di_name'
38
- * (16 bytes) even when the pointer and size were to come from
39
- * 'link.dl_name' (48 bytes).
40
- *
41
- * In all cases the actual name pointer itself is the same, it's
42
- * only the gcc internal 'what is the size of this field' logic
43
- * that can get confused.
44
- */
45
- union qnx4_directory_entry {
46
- struct {
47
- const char de_name [48 ];
48
- u8 de_pad [15 ];
49
- u8 de_status ;
50
- };
51
- struct qnx4_inode_entry inode ;
52
- struct qnx4_link_info link ;
53
- };
54
-
55
18
static int qnx4_readdir (struct file * file , struct dir_context * ctx )
56
19
{
57
20
struct inode * inode = file_inode (file );
@@ -74,26 +37,25 @@ static int qnx4_readdir(struct file *file, struct dir_context *ctx)
74
37
ix = (ctx -> pos >> QNX4_DIR_ENTRY_SIZE_BITS ) % QNX4_INODES_PER_BLOCK ;
75
38
for (; ix < QNX4_INODES_PER_BLOCK ; ix ++ , ctx -> pos += QNX4_DIR_ENTRY_SIZE ) {
76
39
union qnx4_directory_entry * de ;
40
+ const char * fname ;
77
41
78
42
offset = ix * QNX4_DIR_ENTRY_SIZE ;
79
43
de = (union qnx4_directory_entry * ) (bh -> b_data + offset );
80
44
81
- if (!de -> de_name [0 ])
82
- continue ;
83
- if (!(de -> de_status & (QNX4_FILE_USED |QNX4_FILE_LINK )))
45
+ fname = get_entry_fname (de , & size );
46
+ if (!fname )
84
47
continue ;
48
+
85
49
if (!(de -> de_status & QNX4_FILE_LINK )) {
86
- size = sizeof (de -> inode .di_fname );
87
50
ino = blknum * QNX4_INODES_PER_BLOCK + ix - 1 ;
88
51
} else {
89
- size = sizeof (de -> link .dl_fname );
90
52
ino = ( le32_to_cpu (de -> link .dl_inode_blk ) - 1 ) *
91
53
QNX4_INODES_PER_BLOCK +
92
54
de -> link .dl_inode_ndx ;
93
55
}
94
- size = strnlen ( de -> de_name , size );
95
- QNX4DEBUG ((KERN_INFO "qnx4_readdir:%.*s\n" , size , name ));
96
- if (!dir_emit (ctx , de -> de_name , size , ino , DT_UNKNOWN )) {
56
+
57
+ QNX4DEBUG ((KERN_INFO "qnx4_readdir:%.*s\n" , size , fname ));
58
+ if (!dir_emit (ctx , fname , size , ino , DT_UNKNOWN )) {
97
59
brelse (bh );
98
60
return 0 ;
99
61
}
0 commit comments