fygue: fix read() + fix broken sync() + fix path handling + fix file stat() + various other fixes

This commit is contained in:
Yann MAGNIN 2025-04-10 23:40:59 +02:00
parent 69d59cd4d2
commit ec6f7cedc5
No known key found for this signature in database
GPG key ID: D82629D933EADC59
20 changed files with 108 additions and 83 deletions

View file

@ -263,6 +263,7 @@ set(SOURCES
src/fs/fygue/fygue.c src/fs/fygue/fygue.c
src/fs/fygue/fygue_open.c src/fs/fygue/fygue_open.c
src/fs/fygue/fygue_syncfs.c src/fs/fygue/fygue_syncfs.c
src/fs/fygue/fygue_sync.c
src/fs/fygue/fygue_stat.c src/fs/fygue/fygue_stat.c
src/fs/fygue/fygue_mount.c src/fs/fygue/fygue_mount.c
src/fs/fygue/fygue_dir_open.c src/fs/fygue/fygue_dir_open.c

View file

@ -66,6 +66,7 @@ bool fs_descriptor_is_fygue(fs_descriptor_t const *desc)
void fs_fygue_sync(void) void fs_fygue_sync(void)
{ {
fygue_sync();
for (int i = 3 ; i < FS_FD_MAX ; i++) { for (int i = 3 ; i < FS_FD_MAX ; i++) {
if (fdtable[i].type == NULL) if (fdtable[i].type == NULL)
continue; continue;

View file

@ -100,15 +100,13 @@ ssize_t fugue_write(void *data0, const void *buf, size_t size)
else { else {
gint_world_enter(GINT_WORLD_OS); gint_world_enter(GINT_WORLD_OS);
int rc = BFile_Write(fugue_fd, buf, size); int rc = BFile_Write(fugue_fd, buf, size);
gint_world_leave();
if(rc < 0) { if(rc < 0) {
errno = bfile_error_to_errno(rc); errno = bfile_error_to_errno(rc);
rc = -1; return -1;
} else { }
data->pos += rc; data->pos += rc;
rc = 0; return rc;
}
gint_world_leave();
return rc;
} }
} }

View file

@ -374,10 +374,10 @@ static int _fygue_readdir_fat_check(struct _fat_info *finfo)
/* fygue_fat_dir_read() - readdir-like primitive /* fygue_fat_dir_read() - readdir-like primitive
* *
* return * return
* -3 no dirent remaning
* -2 internal error * -2 internal error
* -1 argument error * -1 argument error
* 0 success */ * 0 success
* 1 no directory found */
int fygue_fat_dir_read( int fygue_fat_dir_read(
struct fygue_fat *fat, struct fygue_fat *fat,
struct fygue_fat_dir *dir, struct fygue_fat_dir *dir,
@ -415,5 +415,5 @@ int fygue_fat_dir_read(
return 0; return 0;
} }
dir->end_of_dirent = true; dir->end_of_dirent = true;
return -3; return 1;
} }

View file

@ -9,35 +9,33 @@ int fygue_fat_file_read(
void *buffer, void *buffer,
size_t size size_t size
) { ) {
void *chunk_data_addr; uintptr_t chunk_data_addr;
size_t chunk_data_available; size_t chunk_data_available;
size_t chunk_data_offset; size_t chunk_data_offset;
size_t read; size_t read;
if (fat == NULL || file == NULL || buffer == NULL) { if (fat == NULL || file == NULL || buffer == NULL)
errno = EIO;
return -1; return -1;
} if (file->chunk == NULL)
if (file->chunk == NULL) {
errno = EIO;
return -1; return -1;
}
read = 0; read = 0;
chunk_data_offset = file->chunk_rd_offset; chunk_data_offset = file->chunk_rd_offset;
while (read < size) while (read < size)
{ {
if (file->chunk_rd_index >= file->chunk_count) if (file->chunk_rd_index >= file->chunk_count)
break; break;
chunk_data_addr = (void*)file->chunk[file->chunk_rd_index].addr; chunk_data_addr = file->chunk[file->chunk_rd_index].addr;
chunk_data_addr += chunk_data_offset;
chunk_data_available = file->chunk[file->chunk_rd_index].size; chunk_data_available = file->chunk[file->chunk_rd_index].size;
chunk_data_available -= chunk_data_offset; chunk_data_available -= chunk_data_offset;
if (read + chunk_data_available > size) if (read + chunk_data_available > size)
{ {
chunk_data_offset = size - read; chunk_data_offset += size - read;
memcpy(buffer, chunk_data_addr, chunk_data_offset); memcpy(buffer, (void*)chunk_data_addr, size - read);
read += size - read;
break; break;
} }
memcpy(buffer, chunk_data_addr, chunk_data_available); memcpy(buffer, (void*)chunk_data_addr, chunk_data_available);
read += chunk_data_available; read += chunk_data_available;
file->chunk_rd_index += 1; file->chunk_rd_index += 1;
chunk_data_offset = 0; chunk_data_offset = 0;

View file

@ -9,8 +9,8 @@
static mode_t _get_mode(int attribute) static mode_t _get_mode(int attribute)
{ {
if (attribute & FYGUE_FAT_ATTR_READ_ONLY) if (attribute & FYGUE_FAT_ATTR_READ_ONLY)
return S_IFDIR | 0444; return S_IFREG | 0444;
return S_IFDIR | 0777; return S_IFREG | 0777;
} }
/* _get_block_size(): return one cluster size */ /* _get_block_size(): return one cluster size */

View file

@ -86,8 +86,6 @@ int fygue_fat_open(
if (fat == NULL || path == NULL || desc == NULL) if (fat == NULL || path == NULL || desc == NULL)
return -1; return -1;
if (path[0] != '/')
return -1;
prefix = path; prefix = path;
is_root = true; is_root = true;
while (true) while (true)

View file

@ -25,8 +25,6 @@ struct _bfile_cluster_metadata
uint8_t ecc_bitmask_position[3]; uint8_t ecc_bitmask_position[3];
} GPACKED(1); } GPACKED(1);
uintptr_t debug_meta = 0;
/* _fygue_flash_cluster_convert - ensure that the provided meta is valid /* _fygue_flash_cluster_convert - ensure that the provided meta is valid
* *
* notes * notes
@ -179,7 +177,6 @@ static int _fygue_flash_cluster_details(
data = (geometry->phy_start | 0xa0000000) + (fsector_id * 0x20000); data = (geometry->phy_start | 0xa0000000) + (fsector_id * 0x20000);
meta = data + 0x1f000; meta = data + 0x1f000;
} }
debug_meta = meta;
if (_fygue_flash_cluster_convert(flash, fcluster, meta) != 0) if (_fygue_flash_cluster_convert(flash, fcluster, meta) != 0)
return -1; return -1;
if (fcluster->version != 0xffffffff) if (fcluster->version != 0xffffffff)

View file

@ -33,6 +33,7 @@ static int fygue_flash_cmap_update(
struct fygue_flash_cluster *fcluster struct fygue_flash_cluster *fcluster
) { ) {
struct fygue_flash_cmap_entry *entry; struct fygue_flash_cmap_entry *entry;
int i;
if (cmap == NULL || fcluster == NULL) if (cmap == NULL || fcluster == NULL)
return -1; return -1;
@ -48,14 +49,13 @@ static int fygue_flash_cmap_update(
return 1; return 1;
} }
} else { } else {
cmap->lcluster = realloc( cmap->lcluster = reallocarray(
cmap->lcluster, cmap->lcluster,
(fcluster->lcluster_id + 1) * sizeof( (fcluster->lcluster_id + 1),
struct fygue_flash_cmap_entry sizeof(struct fygue_flash_cmap_entry)
)
); );
for ( for (
int i = cmap->lcluster_id_max ; i = cmap->lcluster_id_max ;
i < fcluster->lcluster_id ; i < fcluster->lcluster_id ;
i++ i++
) { ) {
@ -74,6 +74,42 @@ static int fygue_flash_cmap_update(
return 0; return 0;
} }
/* _fygue_flash_cmap_discover(): discover flash information */
static int _fygue_flash_cmap_discover(
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap
) {
struct fygue_flash_cluster fcluster;
int fsector_id;
int fsector;
int rc;
int j;
fsector_id = 0;
for (
fsector = 0 ;
fsector < flash->geometry.fsector_count ;
fsector++
) {
if (fsector != 0)
fsector_id += flash->geometry.fcluster_per_fsector;
if (fygue_flash_cluster_get(flash, &fcluster, fsector_id) != 0)
continue;
if (fcluster.kind != 0x22)
continue;
for (j = 1 ; j < (flash->geometry.fcluster_per_fsector - 1) ; j++)
{
rc = fygue_flash_cluster_get(flash, &fcluster, fsector_id + j);
if (rc != 0)
continue;
if (fcluster.kind != 0x11)
continue;
fygue_flash_cmap_update(cmap, &fcluster);
}
}
return 0;
}
//--- //---
// Public // Public
//--- //---
@ -126,37 +162,11 @@ int fygue_flash_cmap_initialize(
struct fygue_flash *flash, struct fygue_flash *flash,
struct fygue_flash_cmap *cmap struct fygue_flash_cmap *cmap
) { ) {
struct fygue_flash_cluster fcluster;
int fsector_id;
int fsector;
int rc;
int j;
if (flash == NULL || cmap == NULL) if (flash == NULL || cmap == NULL)
return -1; return -1;
fsector_id = 0;
memset(cmap, 0x00, sizeof(struct fygue_flash_cmap)); memset(cmap, 0x00, sizeof(struct fygue_flash_cmap));
for ( if (_fygue_flash_cmap_discover(flash, cmap) != 0)
fsector = 0 ; return -1;
fsector < flash->geometry.fsector_count ;
fsector++
) {
if (fsector != 0)
fsector_id += flash->geometry.fcluster_per_fsector;
if (fygue_flash_cluster_get(flash, &fcluster, fsector_id) != 0)
continue;
if (fcluster.kind != 0x22)
continue;
for (j = 1 ; j < (flash->geometry.fcluster_per_fsector - 1) ; j++)
{
rc = fygue_flash_cluster_get(flash, &fcluster, fsector_id + j);
if (rc != 0)
continue;
if (fcluster.kind != 0x11)
continue;
fygue_flash_cmap_update(cmap, &fcluster);
}
}
if (cmap->lcluster == NULL) if (cmap->lcluster == NULL)
return -2; return -2;
if (cmap->lcluster[0].fcluster_id == 0xffff) if (cmap->lcluster[0].fcluster_id == 0xffff)
@ -173,7 +183,7 @@ int fygue_flash_cmap_sync(
return -1; return -1;
for (int i = 0 ; i < cmap->lcluster_id_max ; i++) for (int i = 0 ; i < cmap->lcluster_id_max ; i++)
cmap->lcluster[i].version = 0xffffffff; cmap->lcluster[i].version = 0xffffffff;
if (fygue_flash_cmap_initialize(flash, cmap) != 0) if (_fygue_flash_cmap_discover(flash, cmap) != 0)
return -2; return -2;
return 0; return 0;
} }

View file

@ -28,7 +28,7 @@ static int _fygue_gfdi_ensure_valid(
FYGUE_RET_ERRNO(ENOTSUP); FYGUE_RET_ERRNO(ENOTSUP);
if (fsinfo == NULL) if (fsinfo == NULL)
FYGUE_RET_ERRNO(EIO); FYGUE_RET_ERRNO(EIO);
if (desc == NULL || desc->type == type) if (desc == NULL || desc->type != type)
FYGUE_RET_ERRNO(EBADF); FYGUE_RET_ERRNO(EBADF);
if (fygue_mount(fsinfo) != 0) if (fygue_mount(fsinfo) != 0)
FYGUE_RET_ERRNO(EIO); FYGUE_RET_ERRNO(EIO);

View file

@ -44,7 +44,10 @@ extern int fygue_open(char const *path, int flags, mode_t mode);
/* fygue_stat() - get file or directory information */ /* fygue_stat() - get file or directory information */
extern int fygue_stat(char const *path, struct stat *statbuf); extern int fygue_stat(char const *path, struct stat *statbuf);
/* fygue_syncfs() - request filesystem re-synchronisation */ /* fygue_sync() - request filesystem re-synchronisation */
extern int fygue_sync(void);
/* fygue_syncfs() - request filesystem and file re-synchronisation */
extern int fygue_syncfs(void *data); extern int fygue_syncfs(void *data);
/* fygue_mount() - mount the filesystem */ /* fygue_mount() - mount the filesystem */

View file

@ -9,8 +9,6 @@ int fygue_dir_close(
struct fygue_fsinfo *fsinfo, struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir struct fygue_dir *dir
) { ) {
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if (fsinfo == NULL || dir == NULL) if (fsinfo == NULL || dir == NULL)
FYGUE_RET_ERRNO(EIO); FYGUE_RET_ERRNO(EIO);
fygue_fat_dir_close(&(fsinfo->fat), &(dir->fat)); fygue_fat_dir_close(&(fsinfo->fat), &(dir->fat));

View file

@ -66,7 +66,7 @@ static int _fygue_dir_open_discover(
while (true) while (true)
{ {
rc = fygue_fat_dir_read(&(fsinfo->fat), &(dir->fat), &dirent); rc = fygue_fat_dir_read(&(fsinfo->fat), &(dir->fat), &dirent);
if (rc == -1) if (rc > 0)
return 0; return 0;
if (rc < 0) if (rc < 0)
break; break;
@ -74,7 +74,7 @@ static int _fygue_dir_open_discover(
if (_fygue_dir_open_table_realloc(dir) != 0) if (_fygue_dir_open_table_realloc(dir) != 0)
break; break;
} }
rc = _fygue_dir_open_convert(&(dir->dirent[dir->pos]), &dirent); rc = _fygue_dir_open_convert(&(dir->dirent[dir->count]), &dirent);
if (rc != 0) if (rc != 0)
break; break;
dir->count += 1; dir->count += 1;
@ -87,6 +87,7 @@ static int _fygue_dir_open_discover(
// Public // Public
//--- //---
/* fygue_dir_open(): directory-specific open */ /* fygue_dir_open(): directory-specific open */
int fygue_dir_open( int fygue_dir_open(
struct fygue_fsinfo *fsinfo, struct fygue_fsinfo *fsinfo,
@ -95,7 +96,7 @@ int fygue_dir_open(
struct fygue_fat_dir *fat_dir struct fygue_fat_dir *fat_dir
) { ) {
if (fsinfo == NULL || dir == NULL || path == NULL || fat_dir == NULL) if (fsinfo == NULL || dir == NULL || path == NULL || fat_dir == NULL)
return 1; return -1;
memset(dir, 0x00, sizeof(struct fygue_dir)); memset(dir, 0x00, sizeof(struct fygue_dir));
dir->path = strdup(path); dir->path = strdup(path);

View file

@ -1,6 +1,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "fygue.h" #include "fygue.h"
#include "fat/fat.h"
/* fygue_file_close(): close directory */ /* fygue_file_close(): close directory */
int fygue_file_close( int fygue_file_close(
@ -10,6 +10,8 @@ int fygue_file_close(
if (fsinfo == NULL || file == NULL) if (fsinfo == NULL || file == NULL)
FYGUE_RET_ERRNO(EIO); FYGUE_RET_ERRNO(EIO);
fygue_fat_file_close(&(fsinfo->fat), &(file->fat)); fygue_fat_file_close(&(fsinfo->fat), &(file->fat));
free(file); if (file->path != NULL)
free(file->path);
memset(file, 0x00, sizeof(struct fygue_file));
return 0; return 0;
} }

View file

@ -16,6 +16,7 @@ int fygue_file_open(
if (file->path == NULL) if (file->path == NULL)
FYGUE_RET_ERRNO(ENOMEM); FYGUE_RET_ERRNO(ENOMEM);
file->cursor = 0; file->cursor = 0;
file->size = fat_file->size;
memcpy(&(file->fat), fat_file, sizeof(struct fygue_fat_file)); memcpy(&(file->fat), fat_file, sizeof(struct fygue_fat_file));
return 0; return 0;
} }

View file

@ -7,14 +7,19 @@ ssize_t fygue_file_read(
void *buffer, void *buffer,
size_t size size_t size
) { ) {
ssize_t read;
if (fsinfo == NULL || file == NULL) if (fsinfo == NULL || file == NULL)
FYGUE_RET_ERRNO(EIO); FYGUE_RET_ERRNO(EIO);
if (buffer == NULL) if (buffer == NULL)
FYGUE_RET_ERRNO(EFAULT); FYGUE_RET_ERRNO(EFAULT);
return fygue_fat_file_read( if (file->cursor > 0 && (unsigned)file->cursor >= file->size)
&(fsinfo->fat), return 0;
&(file->fat), if (file->cursor + size >= file->size)
buffer, size = file->size - file->cursor;
size read = fygue_fat_file_read(&(fsinfo->fat), &(file->fat), buffer, size);
); if (read < 0)
FYGUE_RET_ERRNO(EIO);
file->cursor += read;
return read;
} }

View file

@ -23,7 +23,7 @@ int fygue_open_resolve(
struct fygue_fat_descriptor fat_desc; struct fygue_fat_descriptor fat_desc;
struct fygue_fsinfo *fsinfo; struct fygue_fsinfo *fsinfo;
if (path == NULL || path[0] != '/' || desc == NULL) if (path == NULL || desc == NULL)
return -1; return -1;
if (fygue_mount(&fsinfo) != 0) if (fygue_mount(&fsinfo) != 0)
return -2; return -2;

15
src/fs/fygue/fygue_sync.c Normal file
View file

@ -0,0 +1,15 @@
#include <gint/hardware.h>
#include "fygue.h"
/* fygue_sync() - request filesystem re-synchronisation */
int fygue_sync(void)
{
struct fygue_fsinfo *fsinfo;
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if (fygue_mount(&fsinfo) != 0)
FYGUE_RET_ERRNO(EIO);
fsinfo->dirty = true;
return 0;
}

View file

@ -4,17 +4,14 @@
/* fygue_syncfs() - request filesystem re-synchronisation */ /* fygue_syncfs() - request filesystem re-synchronisation */
int fygue_syncfs(void *data) int fygue_syncfs(void *data)
{ {
struct fygue_fsinfo *fsinfo;
struct fygue_descriptor *desc; struct fygue_descriptor *desc;
if(gint[HWFS] != HWFS_FUGUE) if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP); FYGUE_RET_ERRNO(ENOTSUP);
if (data == NULL) if (data == NULL)
FYGUE_RET_ERRNO(EBADF); FYGUE_RET_ERRNO(EBADF);
if (fygue_mount(&fsinfo) != 0)
FYGUE_RET_ERRNO(EIO);
desc = data; desc = data;
desc->dirty = true; desc->dirty = true;
fsinfo->dirty = true; fygue_sync();
return 0; return 0;
} }

View file

@ -197,7 +197,6 @@ void gint_world_leave(void)
int gint_world_switch(gint_call_t call) int gint_world_switch(gint_call_t call)
{ {
extern void *gint_stack_top;
gint_world_enter(GINT_WORLD_OS); gint_world_enter(GINT_WORLD_OS);
void *ILRAM = (void *)0xe5200000; void *ILRAM = (void *)0xe5200000;
@ -205,6 +204,7 @@ int gint_world_switch(gint_call_t call)
void *YRAM = (void *)0xe5010000; void *YRAM = (void *)0xe5010000;
/* Watch out for stack overflows */ /* Watch out for stack overflows */
extern void *gint_stack_top;
uint32_t *canary = gint_stack_top; uint32_t *canary = gint_stack_top;
if(canary) if(canary)
*canary = 0xb7c0ffee; *canary = 0xb7c0ffee;