fat32: update the code because the author seemed to fix the bugs in a282d4b92fc0ce6bc6dfd08111791b984f6834e4

This commit is contained in:
2025-03-27 16:08:56 +03:00
parent ec9146f815
commit 7eaabe0f5f
2 changed files with 64 additions and 22 deletions
+2 -1
View File
@@ -8,6 +8,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
//#include <stdio.h> //#include <stdio.h>
#include "../include/stdio.h"
#include <stdarg.h> #include <stdarg.h>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -74,7 +75,7 @@ typedef struct fat_t
uint32_t sect_per_clust; uint32_t sect_per_clust;
uint32_t clust_cnt; uint32_t clust_cnt;
uint32_t info_sect; uint32_t info_sect;
uint32_t fat_sect; uint32_t fat_sect[2];
uint32_t data_sect; uint32_t data_sect;
uint32_t root_sect; uint32_t root_sect;
+57 -16
View File
@@ -2,11 +2,8 @@
// Copyright (c) 2025, Bjørn Brodtkorb. All rights reserved. // Copyright (c) 2025, Bjørn Brodtkorb. All rights reserved.
//#include <string.h> //#include <string.h>
#include "../include/fat.h"
#include "../include/stdio.h"
#include "../include/string.h" #include "../include/string.h"
#include "../include/fat.h"
#define NULL 0
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#define LIMIT(a, b) ((a) < (b) ? (a) : (b)) #define LIMIT(a, b) ((a) < (b) ? (a) : (b))
@@ -444,6 +441,7 @@ static fat_t* find_fat_volume(const char* path, int len)
if (len == it->pathlen && 0 == memcmp(path, it->path, len)) if (len == it->pathlen && 0 == memcmp(path, it->path, len))
return it; return it;
} }
return NULL; return NULL;
} }
@@ -559,7 +557,8 @@ static uint32_t clust_to_sect(fat_t* fat, uint32_t clust)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
static int get_fat(fat_t* fat, uint32_t clust, uint32_t* res) static int get_fat(fat_t* fat, uint32_t clust, uint32_t* res)
{ {
uint32_t sect = fat->fat_sect + clust / 128; // Assume first FAT is correct
uint32_t sect = fat->fat_sect[0] + clust / 128;
uint32_t off = (clust % 128) << 2; uint32_t off = (clust % 128) << 2;
int err = move_win(fat, sect); int err = move_win(fat, sect);
@@ -573,9 +572,9 @@ static int get_fat(fat_t* fat, uint32_t clust, uint32_t* res)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
static int put_fat(fat_t* fat, uint32_t clust, uint32_t val) static int put_fat_in(fat_t* fat, int idx, uint32_t clust, uint32_t val)
{ {
uint32_t sect = fat->fat_sect + clust / 128; uint32_t sect = fat->fat_sect[idx] + clust / 128;
uint32_t off = 4 * (clust % 128); uint32_t off = 4 * (clust % 128);
int err = move_win(fat, sect); int err = move_win(fat, sect);
@@ -590,6 +589,16 @@ static int put_fat(fat_t* fat, uint32_t clust, uint32_t val)
return FAT_ERR_NONE; return FAT_ERR_NONE;
} }
//------------------------------------------------------------------------------
static int put_fat(fat_t* fat, uint32_t clust, uint32_t val)
{
int err = put_fat_in(fat, 0, clust, val);
if (err)
return err;
return put_fat_in(fat, 1, clust, val);
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
static int get_clust_status(fat_t* fat, uint32_t clust) static int get_clust_status(fat_t* fat, uint32_t clust)
{ {
@@ -643,7 +652,7 @@ static int clust_chain_remove(fat_t* fat, uint32_t clust)
if (err) if (err)
return err; return err;
fat->info_cnt--; fat->info_cnt++;
clust = next; clust = next;
if (status & CLUST_LAST) if (status & CLUST_LAST)
@@ -942,7 +951,7 @@ static int load_lfn_name(fat_t* fat, dir_t* dir)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
static int dir_search(fat_t* fat, dir_t* dir, const char* name, int len) static int dir_search(fat_t* fat, dir_t* dir, const char* name, int len, dir_t* start)
{ {
dir_rewind(fat, dir); dir_rewind(fat, dir);
@@ -959,8 +968,15 @@ static int dir_search(fat_t* fat, dir_t* dir, const char* name, int len)
if (!dir_ent_is_free(ent)) if (!dir_ent_is_free(ent))
{ {
if (start)
{
start->sect = dir->sect;
start->idx = dir->idx;
}
if (dir_ent_is_lfn(ent)) if (dir_ent_is_lfn(ent))
{ {
err = load_lfn_name(fat, dir); err = load_lfn_name(fat, dir);
if (err) if (err)
return err; return err;
@@ -1007,9 +1023,11 @@ static int follow_path(dir_t* dir, const char** path)
len = subpath_len(str); len = subpath_len(str);
if (len == 0) if (len == 0)
return FAT_ERR_PATH; return FAT_ERR_PATH;
fat_t* fat = find_fat_volume(str, len); fat_t* fat = find_fat_volume(str, len);
if (!fat) if (!fat)
return FAT_ERR_PATH; return FAT_ERR_PATH;
str += len; str += len;
dir->fat = fat; dir->fat = fat;
@@ -1037,7 +1055,7 @@ static int follow_path(dir_t* dir, const char** path)
if (len == 0) if (len == 0)
return FAT_ERR_NONE; return FAT_ERR_NONE;
err = dir_search(fat, dir, str, len); err = dir_search(fat, dir, str, len, NULL);
if (err) if (err)
return err; return err;
@@ -1184,8 +1202,10 @@ static int get_mbr_partition(fat_t* fat, mbr_part_t* part, int part_num)
int err = move_win(fat, 0); int err = move_win(fat, 0);
if (err) if (err)
return err; return err;
if (fat->win[510] != 0x55 || fat->win[511] != 0xaa) if (fat->win[510] != 0x55 || fat->win[511] != 0xaa)
return FAT_ERR_NOFAT; return FAT_ERR_NOFAT;
*part = ((mbr_part_t*)(fat->win + 446))[part_num]; *part = ((mbr_part_t*)(fat->win + 446))[part_num];
return FAT_ERR_NONE; return FAT_ERR_NONE;
} }
@@ -1238,8 +1258,9 @@ int fat_mount(disk_ops_t* ops, int part_num, fat_t* fat, const char* path)
fat->sect_per_clust = bpb->sect_per_clust; fat->sect_per_clust = bpb->sect_per_clust;
fat->clust_cnt = bpb->sect_per_fat_32 * 128; fat->clust_cnt = bpb->sect_per_fat_32 * 128;
fat->info_sect = part.lba + bpb->info_sect; fat->info_sect = part.lba + bpb->info_sect;
fat->fat_sect = part.lba + bpb->res_sect_cnt; fat->fat_sect[0] = part.lba + bpb->res_sect_cnt;
fat->data_sect = fat->fat_sect + bpb->fat_cnt * bpb->sect_per_fat_32; fat->fat_sect[1] = fat->fat_sect[0] + bpb->sect_per_fat_32;
fat->data_sect = fat->fat_sect[0] + bpb->fat_cnt * bpb->sect_per_fat_32;
fat->root_sect = clust_to_sect(fat, bpb->root_cluster); fat->root_sect = clust_to_sect(fat, bpb->root_cluster);
err = move_win(fat, fat->info_sect); err = move_win(fat, fat->info_sect);
@@ -1345,7 +1366,7 @@ int fat_fopen(file_t* file, const char* path, const char* mode)
if (len == 0 || path[len]) if (len == 0 || path[len])
return FAT_ERR_PATH; return FAT_ERR_PATH;
err = dir_search(fat, dir, path, len); err = dir_search(fat, dir, path, len, NULL);
if (err == FAT_ERR_EOF) if (err == FAT_ERR_EOF)
{ {
@@ -1640,8 +1661,9 @@ int fat_unlink(const char* path)
return FAT_ERR_PATH; return FAT_ERR_PATH;
fat_t* fat = dir.fat; fat_t* fat = dir.fat;
dir_t sdir = dir;
err = dir_search(fat, &dir, path, len); err = dir_search(fat, &dir, path, len, &sdir);
if (err) if (err)
return err; return err;
@@ -1651,9 +1673,24 @@ int fat_unlink(const char* path)
if (err) if (err)
return err; return err;
for (;;)
{
err = move_win(fat, sdir.sect);
if (err)
return err;
dir_ent_t* ent = (dir_ent_t*)(fat->win + sdir.idx);
ent->name[0] = SFN_FREE; ent->name[0] = SFN_FREE;
fat->win_dirty = true; fat->win_dirty = true;
if (sdir.sect == dir.sect && sdir.idx == dir.idx)
break;
err = dir_next(fat, &sdir);
if (err)
return err;
}
return sync_fat(fat); return sync_fat(fat);
} }
@@ -1671,6 +1708,10 @@ int fat_mkdir(const char* path)
if (len == 0 || path[len]) if (len == 0 || path[len])
return FAT_ERR_PATH; return FAT_ERR_PATH;
uint32_t prev = dir.first_clust;
if (prev == 2) // Old cluster is the root directory
prev = 0;
// Create a new directory // Create a new directory
uint32_t new; uint32_t new;
err = clust_chain_create(fat, &new); err = clust_chain_create(fat, &new);
@@ -1704,8 +1745,8 @@ int fat_mkdir(const char* path)
memcpy(ent + 1, ent, sizeof(dir_ent_t)); memcpy(ent + 1, ent, sizeof(dir_ent_t));
ent[1].name[1] = '.'; ent[1].name[1] = '.';
ent[1].clust_hi = dir.first_clust >> 16; ent[1].clust_hi = prev >> 16;
ent[1].clust_lo = dir.first_clust & 0xffff; ent[1].clust_lo = prev & 0xffff;
err = dir_register(fat, &dir, path, len, FAT_ATTR_DIR, new); err = dir_register(fat, &dir, path, len, FAT_ATTR_DIR, new);
if (err) if (err)