mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-06-26 07:36:39 +02:00
fygue: fix read() + fix broken sync() + fix path handling + fix file stat() + various other fixes
This commit is contained in:
parent
69d59cd4d2
commit
ec6f7cedc5
20 changed files with 108 additions and 83 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
15
src/fs/fygue/fygue_sync.c
Normal 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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue