fygue: fix FAT cluster resolution + support stat() for directory + support stat(), lseek() and write() (EROFS) for file

This commit is contained in:
Yann MAGNIN 2025-04-05 13:34:42 +02:00
parent bad0dbd5f4
commit eaa0602225
No known key found for this signature in database
GPG key ID: D82629D933EADC59
10 changed files with 136 additions and 16 deletions

View file

@ -268,6 +268,8 @@ set(SOURCES
src/fs/fygue/fygue_dir_lseek.c src/fs/fygue/fygue_dir_lseek.c
src/fs/fygue/fygue_dir_write.c src/fs/fygue/fygue_dir_write.c
src/fs/fygue/fygue_dir_close.c src/fs/fygue/fygue_dir_close.c
src/fs/fygue/fygue_file_lseek.c
src/fs/fygue/fygue_file_write.c
src/fs/fygue/fat/cluster.c src/fs/fygue/fat/cluster.c
src/fs/fygue/fat/initialize.c src/fs/fygue/fat/initialize.c
src/fs/fygue/fat/fat_dir_read.c src/fs/fygue/fat/fat_dir_read.c

View file

@ -2,29 +2,64 @@
** fygue/fat/cluster - FAT cluster handling ** fygue/fat/cluster - FAT cluster handling
*/ */
#include "fat.h" #include "fat.h"
#include "../flash/flash.h"
//--- //---
// Public // Public
//--- //---
/* fygue_fat_cluster_get_next() - find the next cluster ID of a file */ /* fygue_fat_cluster_get_next() - find the next cluster ID of a file
*
* returns
* -7 next cluster unused (0x0000)
* -6 next cluster end (0xffff)
* -5 internal error
* -4 provided cluster unused (0x0000)
* -3 provided cluster end (0xffff)
* -2 provided invalid cluster (root or "out of fat")
* -1 argument error
* 0 success
*
* todo
* - ensure FAT1 information is the same ? */
int fygue_fat_cluster_get_next(struct fygue_fat *fat, int *cluster_current) int fygue_fat_cluster_get_next(struct fygue_fat *fat, int *cluster_current)
{ {
uint16_t *fat0; uint16_t *fat0;
int nb_entry_per_sector;
int cluster_sector;
int cluster_real;
int cluster; int cluster;
int rc;
if (fat == NULL || cluster_current == NULL) if (fat == NULL || cluster_current == NULL)
return -1; return -1;
cluster = *cluster_current; cluster = *cluster_current;
if (cluster == 0xffff)
return -3;
if (cluster == 0x0000)
return -4;
if (cluster <= 1) if (cluster <= 1)
return -2; return -2;
if (cluster >= fat->ClusterCount) if (cluster >= fat->ClusterCount)
return -2; return -2;
fat0 = (void*)fat->FAT0Addr; nb_entry_per_sector = fat->SectorSize / 2;
if (fat0[cluster] == 0xffff) cluster_sector = cluster / nb_entry_per_sector;
return -3; cluster_real = cluster - (cluster_sector * nb_entry_per_sector);
*cluster_current = fat0[cluster]; rc = fygue_fat_sector_get_addr(
return 0; fat,
(void*)&fat0,
fat->FAT0SectorID + cluster_sector
);
if (rc < 0)
return -5;
rc = 0;
cluster = FAT_WORD(fat0[cluster_real]);
if (cluster == 0xffff)
rc = -6;
if (cluster == 0x0000)
rc = -7;
*cluster_current = cluster;
return rc;
} }
/* fygue_fat_cluster_get_sector() - get sector ID from cluster ID */ /* fygue_fat_cluster_get_sector() - get sector ID from cluster ID */

View file

@ -44,8 +44,6 @@ struct fygue_fat
int FAT1SectorID; int FAT1SectorID;
int RootSectorID; int RootSectorID;
int DataSectorID; int DataSectorID;
uintptr_t FAT0Addr;
uintptr_t FAT1Addr;
uintptr_t RootAddr; uintptr_t RootAddr;
uintptr_t BPB; uintptr_t BPB;
struct { struct {

View file

@ -147,23 +147,26 @@ static int _fygue_fat_configure(struct fygue_fat *fat)
} }
/* _fygue_fat_prepare() - prepare logic information */ /* _fygue_fat_prepare() - prepare logic information */
static int _fygue_fat_prepare(struct fygue_fat *fat) { static int _fygue_fat_prepare(struct fygue_fat *fat)
{
int rc; int rc;
rc = fygue_flash_cmap_lsector_get_addr( #if 0
&fat->_flash.cmap, rc = fygue_fat_sector_get_addr(
fat,
&fat->FAT0Addr, &fat->FAT0Addr,
fat->FAT0SectorID fat->FAT0SectorID
); );
if (rc != 0) if (rc != 0)
return -1; return -1;
rc = fygue_flash_cmap_lsector_get_addr( rc = fygue_fat_sector_get_addr(
&fat->_flash.cmap, fat,
(void*)&fat->FAT1Addr, (void*)&fat->FAT1Addr,
fat->FAT1SectorID fat->FAT1SectorID
); );
if (rc != 0) if (rc != 0)
return -1; return -1;
#endif
rc = fygue_flash_cmap_lsector_get_addr( rc = fygue_flash_cmap_lsector_get_addr(
&fat->_flash.cmap, &fat->_flash.cmap,
&fat->RootAddr, &fat->RootAddr,

View file

@ -85,8 +85,8 @@ int fygue_resolve(char const * const path, struct fygue_resolve *resolve)
const fs_descriptor_type_t fygue_descriptor_type = { const fs_descriptor_type_t fygue_descriptor_type = {
.read = NULL, .read = NULL,
.write = NULL, .write = (void*)&fygue_file_write,
.lseek = NULL, .lseek = (void*)&fygue_file_lseek,
.close = NULL, .close = NULL,
}; };
@ -94,5 +94,5 @@ const fs_descriptor_type_t fygue_dir_descriptor_type = {
.read = (void*)&fygue_dir_read, .read = (void*)&fygue_dir_read,
.write = (void*)&fygue_dir_write, .write = (void*)&fygue_dir_write,
.lseek = (void*)&fygue_dir_lseek, .lseek = (void*)&fygue_dir_lseek,
.close = NULL, .close = (void*)&fygue_dir_close,
}; };

View file

@ -65,6 +65,7 @@ struct fygue_resolve {
struct { struct {
off_t cursor; off_t cursor;
struct fygue_fat_file fat; struct fygue_fat_file fat;
off_t size;
} file; } file;
struct { struct {
struct fygue_fat_dir fat; struct fygue_fat_dir fat;
@ -94,6 +95,10 @@ extern int fygue_resolve(
struct fygue_resolve *resolve struct fygue_resolve *resolve
); );
//---
// Directory interface
//---
/* fygue_dir_read(): directory read implementation */ /* fygue_dir_read(): directory read implementation */
extern int fygue_dir_read( extern int fygue_dir_read(
struct fygue_descriptor *desc, struct fygue_descriptor *desc,
@ -115,6 +120,27 @@ ssize_t fygue_dir_write(
size_t size size_t size
); );
/* fygue_dir_close(): close directory */
extern int fygue_dir_close(struct fygue_descriptor *desc);
//---
// File interface
//---
/* fygue_file_lseek(): seek directory */
extern off_t fygue_file_lseek(
struct fygue_descriptor *desc,
off_t offset,
int whence
);
/* fygue_file_write(): write directory (EROFS) */
extern ssize_t fygue_file_write(
struct fygue_descriptor *desc,
void *buffer,
size_t size
);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -3,6 +3,7 @@
#include "fygue.h" #include "fygue.h"
#include "fat/fat.h" #include "fat/fat.h"
/* fygue_dir_close(): close directory */
int fygue_dir_close(struct fygue_descriptor *desc) int fygue_dir_close(struct fygue_descriptor *desc)
{ {
struct fygue_fsinfo *fsinfo; struct fygue_fsinfo *fsinfo;

View file

@ -26,10 +26,15 @@ off_t fygue_dir_lseek(
off_t offset, off_t offset,
int whence int whence
) { ) {
ENOTSUP_IF_NOT_FYGUE(-1);
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) { if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
errno = EBADF; errno = EBADF;
return -1; return -1;
} }
if (whence != SEEK_CUR && whence != SEEK_SET && whence != SEEK_END) {
errno = EINVAL;
return -1;
}
if(whence == SEEK_CUR) if(whence == SEEK_CUR)
offset += desc->resolve.dir.pos; offset += desc->resolve.dir.pos;
if(whence == SEEK_END) { if(whence == SEEK_END) {

View file

@ -0,0 +1,28 @@
#include "fygue.h"
/* fygue_file_lseek(): seek directory */
off_t fygue_file_lseek(
struct fygue_descriptor *desc,
off_t offset,
int whence
) {
ENOTSUP_IF_NOT_FYGUE(-1);
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_FILE) {
errno = EBADF;
return -1;
}
if (whence != SEEK_CUR && whence != SEEK_SET && whence != SEEK_END) {
errno = EINVAL;
return -1;
}
if(whence == SEEK_CUR)
offset += desc->resolve.dir.pos;
if(whence == SEEK_END)
offset += desc->resolve.file.size;
if(offset < 0 || offset >= desc->resolve.file.size + 1) {
errno = EINVAL;
return -1;
}
desc->resolve.file.cursor = offset;
return desc->resolve.file.cursor;
}

View file

@ -0,0 +1,22 @@
#include "fygue.h"
/* fygue_file_write(): write directory (EISDIR) */
ssize_t fygue_file_write(
struct fygue_descriptor *desc,
void *buffer,
size_t size
) {
ENOTSUP_IF_NOT_FYGUE(-1);
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_FILE) {
errno = EBADF;
return -1;
}
if (buffer == NULL) {
errno = EFAULT;
return -1;
}
if (size == 0)
return 0;
errno = EROFS;
return -1;
}