@@ -36,6 +36,18 @@ static inline uint32_t fat32_cluster_lba(fat32_fs_t* fs, uint32_t cluster) {
3636 (cluster - 2 ) * fs -> sectors_per_cluster ;
3737}
3838
39+ static int fat32_zero_cluster (fat32_fs_t * fs , uint32_t cluster ) {
40+ uint8_t zero [FAT32_SECTOR_SIZE ];
41+ memset (zero , 0 , sizeof (zero ));
42+
43+ uint32_t lba = fat32_cluster_lba (fs , cluster );
44+ for (uint32_t i = 0 ; i < fs -> sectors_per_cluster ; i ++ ) {
45+ if (fat32_write_sector (fs , lba + i , zero ))
46+ return -1 ;
47+ }
48+ return 0 ;
49+ }
50+
3951uint32_t fat32_read_fat (fat32_fs_t * fs , uint32_t cluster ) {
4052 uint32_t offset = cluster * 4 ;
4153 uint32_t lba = fs -> fat_start_lba + (offset / FAT32_SECTOR_SIZE );
@@ -63,12 +75,19 @@ static int fat32_write_fat(fat32_fs_t* fs, uint32_t cluster, uint32_t value) {
6375
6476uint32_t fat32_alloc_cluster (fat32_fs_t * fs ) {
6577 uint32_t start = fs -> last_alloc ? fs -> last_alloc : 2 ;
66-
67- for (uint32_t c = start ; c < fs -> total_clusters + 2 ; c ++ ) {
68- if (fat32_read_fat (fs , c ) == FAT32_CLUSTER_FREE ) {
69- fat32_write_fat (fs , c , FAT32_CLUSTER_EOC );
70- fs -> last_alloc = c ;
71- return c ;
78+ uint32_t end = fs -> total_clusters + 2 ;
79+
80+ for (uint32_t pass = 0 ; pass < 2 ; pass ++ ) {
81+ uint32_t from = (pass == 0 ) ? start : 2 ;
82+ uint32_t to = (pass == 0 ) ? end : start ;
83+
84+ for (uint32_t c = from ; c < to ; c ++ ) {
85+ if (fat32_read_fat (fs , c ) == FAT32_CLUSTER_FREE ) {
86+ if (fat32_write_fat (fs , c , FAT32_CLUSTER_EOC ))
87+ return 0 ;
88+ fs -> last_alloc = c ;
89+ return c ;
90+ }
7291 }
7392 }
7493 return 0 ;
@@ -176,13 +195,19 @@ int fat32_open(fat32_fs_t* fs, const char* path, fat32_file_t* f) {
176195 fat32_dir_entry_t found = {0 };
177196
178197 while (tok ) {
179- uint8_t * buf = kmalloc (sizeof (uint8_t ) * fs -> sectors_per_cluster * FAT32_SECTOR_SIZE );
198+ uint32_t cluster_bytes = fs -> sectors_per_cluster * FAT32_SECTOR_SIZE ;
199+ uint8_t * buf = kmalloc (cluster_bytes );
200+ if (!buf )
201+ return -1 ;
180202 int hit = 0 ;
181203
182204 while (cluster < FAT32_CLUSTER_EOC ) {
183- fat32_read_cluster (fs , cluster , buf );
205+ if (fat32_read_cluster (fs , cluster , buf )) {
206+ kfree (buf );
207+ return -1 ;
208+ }
184209
185- for (uint32_t off = 0 ; off < sizeof ( buf ) ; off += 32 ) {
210+ for (uint32_t off = 0 ; off < cluster_bytes ; off += sizeof ( fat32_dir_entry_t ) ) {
186211 fat32_dir_entry_t * e = (void * )(buf + off );
187212 if (e -> name [0 ] == 0x00 ) break ;
188213 if (e -> attr == FAT_ATTR_LFN ) continue ;
@@ -199,6 +224,7 @@ int fat32_open(fat32_fs_t* fs, const char* path, fat32_file_t* f) {
199224 cluster = fat32_read_fat (fs , cluster );
200225 }
201226
227+ kfree (buf );
202228 if (!hit ) return -1 ;
203229 tok = strtok (NULL , "/" );
204230 }
@@ -226,9 +252,15 @@ int fat32_read(fat32_file_t* f, void* buf, uint32_t len) {
226252 uint32_t cluster_size =
227253 f -> fs -> sectors_per_cluster * FAT32_SECTOR_SIZE ;
228254
255+ uint8_t * clbuf = kmalloc (cluster_size );
256+ if (!clbuf )
257+ return -1 ;
258+
229259 while (len && f -> pos < f -> entry .file_size ) {
230- uint8_t clbuf [cluster_size ];
231- fat32_read_cluster (f -> fs , f -> current_cluster , clbuf );
260+ if (fat32_read_cluster (f -> fs , f -> current_cluster , clbuf )) {
261+ kfree (clbuf );
262+ return -1 ;
263+ }
232264
233265 uint32_t off = f -> pos % cluster_size ;
234266 uint32_t take = cluster_size - off ;
@@ -245,6 +277,7 @@ int fat32_read(fat32_file_t* f, void* buf, uint32_t len) {
245277 if (off + take >= cluster_size )
246278 f -> current_cluster = fat32_read_fat (f -> fs , f -> current_cluster );
247279 }
280+ kfree (clbuf );
248281 return done ;
249282}
250283
@@ -262,12 +295,21 @@ int fat32_write(fat32_file_t* f, const void* buf, uint32_t len) {
262295
263296 if (!f -> start_cluster ) {
264297 f -> start_cluster = fat32_alloc_cluster (f -> fs );
298+ if (!f -> start_cluster )
299+ return -1 ;
300+ fat32_zero_cluster (f -> fs , f -> start_cluster );
265301 f -> current_cluster = f -> start_cluster ;
266302 }
267303
304+ uint8_t * clbuf = kmalloc (cluster_size );
305+ if (!clbuf )
306+ return -1 ;
307+
268308 while (len ) {
269- uint8_t clbuf [cluster_size ];
270- fat32_read_cluster (f -> fs , f -> current_cluster , clbuf );
309+ if (fat32_read_cluster (f -> fs , f -> current_cluster , clbuf )) {
310+ kfree (clbuf );
311+ return -1 ;
312+ }
271313
272314 uint32_t off = f -> pos % cluster_size ;
273315 uint32_t take = cluster_size - off ;
@@ -277,8 +319,11 @@ int fat32_write(fat32_file_t* f, const void* buf, uint32_t len) {
277319
278320 uint32_t lba = fat32_cluster_lba (f -> fs , f -> current_cluster );
279321 for (uint32_t i = 0 ; i < f -> fs -> sectors_per_cluster ; i ++ )
280- fat32_write_sector (f -> fs , lba + i ,
281- clbuf + i * FAT32_SECTOR_SIZE );
322+ if (fat32_write_sector (f -> fs , lba + i ,
323+ clbuf + i * FAT32_SECTOR_SIZE )) {
324+ kfree (clbuf );
325+ return -1 ;
326+ }
282327
283328 done += take ;
284329 f -> pos += take ;
@@ -288,7 +333,12 @@ int fat32_write(fat32_file_t* f, const void* buf, uint32_t len) {
288333 uint32_t next = fat32_read_fat (f -> fs , f -> current_cluster );
289334 if (next >= FAT32_CLUSTER_EOC ) {
290335 next = fat32_alloc_cluster (f -> fs );
336+ if (!next ) {
337+ kfree (clbuf );
338+ return -1 ;
339+ }
291340 fat32_write_fat (f -> fs , f -> current_cluster , next );
341+ fat32_zero_cluster (f -> fs , next );
292342 }
293343 f -> current_cluster = next ;
294344 }
@@ -297,6 +347,7 @@ int fat32_write(fat32_file_t* f, const void* buf, uint32_t len) {
297347 if (f -> pos > f -> entry .file_size )
298348 f -> entry .file_size = f -> pos ;
299349
350+ kfree (clbuf );
300351 return done ;
301352}
302353
@@ -548,8 +599,42 @@ uint32_t fat32_clusters_for_size(fat32_fs_t* fs, uint32_t size)
548599
549600void fat32_update_entry (fat32_fs_t * fs , fat32_dir_entry_t * e )
550601{
551- (void )fs ;
552- (void )e ;
602+ if (!fs || !e )
603+ return ;
604+
605+ uint8_t sector [FAT32_SECTOR_SIZE ];
606+ uint32_t last_cluster = ((uint32_t )e -> first_cluster_high << 16 ) | e -> first_cluster_low ;
607+
608+ for (uint32_t cluster = 2 ; cluster < fs -> total_clusters + 2 ; cluster ++ ) {
609+ uint32_t lba = fat32_cluster_lba (fs , cluster );
610+
611+ for (uint32_t s = 0 ; s < fs -> sectors_per_cluster ; s ++ ) {
612+ if (fat32_read_sector (fs , lba + s , sector ))
613+ continue ;
614+
615+ fat32_dir_entry_t * entries = (fat32_dir_entry_t * )sector ;
616+ uint32_t count = FAT32_SECTOR_SIZE / sizeof (fat32_dir_entry_t );
617+
618+ for (uint32_t i = 0 ; i < count ; i ++ ) {
619+ if (entries [i ].name [0 ] == 0x00 )
620+ break ;
621+ if (entries [i ].name [0 ] == 0xE5 || entries [i ].attr == FAT_ATTR_LFN )
622+ continue ;
623+
624+ uint32_t entry_cluster =
625+ ((uint32_t )entries [i ].first_cluster_high << 16 ) |
626+ entries [i ].first_cluster_low ;
627+
628+ if (entry_cluster == last_cluster &&
629+ memcmp (entries [i ].name , e -> name , 11 ) == 0 )
630+ {
631+ entries [i ] = * e ;
632+ fat32_write_sector (fs , lba + s , sector );
633+ return ;
634+ }
635+ }
636+ }
637+ }
553638}
554639
555640void fat32_free_chain_from (
0 commit comments