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_open.c
src/fs/fygue/fygue_syncfs.c
src/fs/fygue/fygue_sync.c
src/fs/fygue/fygue_stat.c
src/fs/fygue/fygue_mount.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)
{
fygue_sync();
for (int i = 3 ; i < FS_FD_MAX ; i++) {
if (fdtable[i].type == NULL)
continue;

View file

@ -100,14 +100,12 @@ ssize_t fugue_write(void *data0, const void *buf, size_t size)
else {
gint_world_enter(GINT_WORLD_OS);
int rc = BFile_Write(fugue_fd, buf, size);
gint_world_leave();
if(rc < 0) {
errno = bfile_error_to_errno(rc);
rc = -1;
} else {
data->pos += rc;
rc = 0;
return -1;
}
gint_world_leave();
data->pos += rc;
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
*
* return
* -3 no dirent remaning
* -2 internal error
* -1 argument error
* 0 success */
* 0 success
* 1 no directory found */
int fygue_fat_dir_read(
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
@ -415,5 +415,5 @@ int fygue_fat_dir_read(
return 0;
}
dir->end_of_dirent = true;
return -3;
return 1;
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -28,7 +28,7 @@ static int _fygue_gfdi_ensure_valid(
FYGUE_RET_ERRNO(ENOTSUP);
if (fsinfo == NULL)
FYGUE_RET_ERRNO(EIO);
if (desc == NULL || desc->type == type)
if (desc == NULL || desc->type != type)
FYGUE_RET_ERRNO(EBADF);
if (fygue_mount(fsinfo) != 0)
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 */
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);
/* fygue_mount() - mount the filesystem */

View file

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

View file

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

View file

@ -1,6 +1,6 @@
#include <stdlib.h>
#include <string.h>
#include "fygue.h"
#include "fat/fat.h"
/* fygue_file_close(): close directory */
int fygue_file_close(
@ -10,6 +10,8 @@ int fygue_file_close(
if (fsinfo == NULL || file == NULL)
FYGUE_RET_ERRNO(EIO);
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;
}

View file

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

View file

@ -7,14 +7,19 @@ ssize_t fygue_file_read(
void *buffer,
size_t size
) {
ssize_t read;
if (fsinfo == NULL || file == NULL)
FYGUE_RET_ERRNO(EIO);
if (buffer == NULL)
FYGUE_RET_ERRNO(EFAULT);
return fygue_fat_file_read(
&(fsinfo->fat),
&(file->fat),
buffer,
size
);
if (file->cursor > 0 && (unsigned)file->cursor >= file->size)
return 0;
if (file->cursor + size >= file->size)
size = file->size - file->cursor;
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_fsinfo *fsinfo;
if (path == NULL || path[0] != '/' || desc == NULL)
if (path == NULL || desc == NULL)
return -1;
if (fygue_mount(&fsinfo) != 0)
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 */
int fygue_syncfs(void *data)
{
struct fygue_fsinfo *fsinfo;
struct fygue_descriptor *desc;
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if (data == NULL)
FYGUE_RET_ERRNO(EBADF);
if (fygue_mount(&fsinfo) != 0)
FYGUE_RET_ERRNO(EIO);
desc = data;
desc->dirty = true;
fsinfo->dirty = true;
fygue_sync();
return 0;
}

View file

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