@@ -73,21 +73,18 @@ static uint8_t readbuf[TFFS_SECTOR_SIZE];
73
73
static uint8_t oobbuf [TFFS_SECTOR_OOB_SIZE ];
74
74
static uint32_t blocksize ;
75
75
static int mtdfd ;
76
- struct tffs_sectors * sectors ;
77
-
78
- struct tffs_sectors {
79
- uint32_t num_sectors ;
80
- uint8_t sectors [0 ];
81
- };
76
+ static uint32_t num_sectors ;
77
+ static uint8_t * sectors ;
78
+ static uint32_t * sector_ids ;
82
79
83
80
static inline void sector_mark_bad (int num )
84
81
{
85
- sectors -> sectors [num / 8 ] &= ~(0x80 >> (num % 8 ));
82
+ sectors [num / 8 ] &= ~(0x80 >> (num % 8 ));
86
83
};
87
84
88
85
static inline uint8_t sector_get_good (int num )
89
86
{
90
- return sectors -> sectors [num / 8 ] & 0x80 >> (num % 8 );
87
+ return sectors [num / 8 ] & 0x80 >> (num % 8 );
91
88
};
92
89
93
90
struct tffs_entry_segment {
@@ -139,6 +136,8 @@ static int read_sector(off_t pos)
139
136
return -1 ;
140
137
}
141
138
139
+ sector_ids [pos / TFFS_SECTOR_SIZE ] = read_uint32 (readbuf , 0x00 );
140
+
142
141
return 0 ;
143
142
}
144
143
@@ -176,25 +175,39 @@ static int find_entry(uint32_t id, struct tffs_entry *entry)
176
175
177
176
off_t pos = 0 ;
178
177
uint8_t block_end = 0 ;
179
- for (uint32_t sector = 0 ; sector < sectors -> num_sectors ; sector ++ , pos += TFFS_SECTOR_SIZE ) {
178
+ for (uint32_t sector = 0 ; sector < num_sectors ; sector ++ , pos += TFFS_SECTOR_SIZE ) {
180
179
if (block_end ) {
181
180
if (pos % blocksize == 0 ) {
182
181
block_end = 0 ;
183
182
}
184
183
} else if (sector_get_good (sector )) {
184
+ if (sector_ids [sector ]) {
185
+ if (sector_ids [sector ] == TFFS_ID_END ) {
186
+ /* no more entries in this block */
187
+ block_end = 1 ;
188
+ continue ;
189
+ }
190
+
191
+ if (sector_ids [sector ] != id )
192
+ continue ;
193
+ }
194
+
185
195
if (read_sectoroob (pos ) || read_sector (pos )) {
186
196
fprintf (stderr , "ERROR: sector isn't readable, but has been previously!\n" );
187
197
exit (EXIT_FAILURE );
188
198
}
189
- uint32_t oob_id = read_uint32 (oobbuf , 0x02 );
190
- uint32_t oob_len = read_uint32 (oobbuf , 0x06 );
191
- uint32_t oob_rev = read_uint32 (oobbuf , 0x0a );
192
199
uint32_t read_id = read_uint32 (readbuf , 0x00 );
193
200
uint32_t read_len = read_uint32 (readbuf , 0x04 );
194
201
uint32_t read_rev = read_uint32 (readbuf , 0x0c );
195
- if (read_oob_sector_health && (oob_id != read_id || oob_len != read_len || oob_rev != read_rev )) {
196
- fprintf (stderr , "Warning: sector has inconsistent metadata\n" );
197
- continue ;
202
+ if (read_oob_sector_health ) {
203
+ uint32_t oob_id = read_uint32 (oobbuf , 0x02 );
204
+ uint32_t oob_len = read_uint32 (oobbuf , 0x06 );
205
+ uint32_t oob_rev = read_uint32 (oobbuf , 0x0a );
206
+
207
+ if (oob_id != read_id || oob_len != read_len || oob_rev != read_rev ) {
208
+ fprintf (stderr , "Warning: sector has inconsistent metadata\n" );
209
+ continue ;
210
+ }
198
211
}
199
212
if (read_id == TFFS_ID_END ) {
200
213
/* no more entries in this block */
@@ -414,13 +427,14 @@ static int scan_mtd(void)
414
427
415
428
blocksize = info .erasesize ;
416
429
417
- sectors = malloc (sizeof (* sectors ) + (info .size / TFFS_SECTOR_SIZE + 7 ) / 8 );
418
- if (sectors == NULL ) {
430
+ num_sectors = info .size / TFFS_SECTOR_SIZE ;
431
+ sectors = malloc ((num_sectors + 7 ) / 8 );
432
+ sector_ids = calloc (num_sectors , sizeof (uint32_t ));
433
+ if (!sectors || !sector_ids ) {
419
434
fprintf (stderr , "ERROR: memory allocation failed!\n" );
420
435
exit (EXIT_FAILURE );
421
436
}
422
- sectors -> num_sectors = info .size / TFFS_SECTOR_SIZE ;
423
- memset (sectors -> sectors , 0xff , (info .size / TFFS_SECTOR_SIZE + 7 ) / 8 );
437
+ memset (sectors , 0xff , (num_sectors + 7 ) / 8 );
424
438
425
439
uint32_t sector = 0 , valid_blocks = 0 ;
426
440
uint8_t block_ok = 0 ;
@@ -564,6 +578,7 @@ int main(int argc, char *argv[])
564
578
out_free_entry :
565
579
free (name_table .val );
566
580
out_free_sectors :
581
+ free (sector_ids );
567
582
free (sectors );
568
583
out_close :
569
584
close (mtdfd );
0 commit comments