fygue: WIP prepare syncfs() implementation + fix Math+ Flash information

This commit is contained in:
Yann MAGNIN 2025-04-09 18:31:28 +02:00
parent ba7d84dbb2
commit c99a18d748
No known key found for this signature in database
GPG key ID: D82629D933EADC59
23 changed files with 388 additions and 155 deletions

View file

@ -274,9 +274,11 @@ set(SOURCES
src/fs/fygue/fygue_file_read.c src/fs/fygue/fygue_file_read.c
src/fs/fygue/fat/cluster.c src/fs/fygue/fat/cluster.c
src/fs/fygue/fat/fat.c src/fs/fygue/fat/fat.c
src/fs/fygue/fat/fat_dir_open.c
src/fs/fygue/fat/fat_dir_read.c src/fs/fygue/fat/fat_dir_read.c
src/fs/fygue/fat/fat_dir_close.c src/fs/fygue/fat/fat_dir_close.c
src/fs/fygue/fat/fat_dir_stat.c src/fs/fygue/fat/fat_dir_stat.c
src/fs/fygue/fat/fat_file_open.c
src/fs/fygue/fat/fat_file_stat.c src/fs/fygue/fat/fat_file_stat.c
src/fs/fygue/fat/fat_file_close.c src/fs/fygue/fat/fat_file_close.c
src/fs/fygue/fat/fat_file_read.c src/fs/fygue/fat/fat_file_read.c

View file

@ -153,8 +153,8 @@ static int _fygue_fat_prepare(struct fygue_fat *fat)
// Public // Public
//--- //---
/* fygue_fat_init_cold() - fully initialize the FAT information */ /* fygue_fat_initialize() - fully initialize the FAT information */
int fygue_fat_init_cold(struct fygue_fat *fat) int fygue_fat_initialize(struct fygue_fat *fat)
{ {
if (fat == NULL) if (fat == NULL)
return -1; return -1;
@ -170,11 +170,14 @@ int fygue_fat_init_cold(struct fygue_fat *fat)
return 0; return 0;
} }
/* fygue_fat_init_hot(): re-initialize the FAT information */ /* fygue_fat_sync(): re-initialize the FAT information */
int fygue_fat_init_hot(struct fygue_fat *fat) int fygue_fat_sync(struct fygue_fat *fat)
{ {
//FIXME: implement if (fat == NULL)
(void)fat; return -1;
errno = ENOTSUP; if (fygue_flash_sync((&fat->_flash)) != 0)
return -3; return -2;
if (_fygue_fat_prepare(fat) != 0)
return -3;
return 0;
} }

View file

@ -82,11 +82,13 @@ struct fygue_fat_file
int cluster_entry; int cluster_entry;
int attribute; int attribute;
size_t size; size_t size;
off_t cursor;
struct { struct {
uintptr_t addr; uintptr_t addr;
size_t size; size_t size;
int cluster_count; int cluster_count;
} *chunk; } *chunk;
int chunk_table_max_index;
int chunk_count; int chunk_count;
int chunk_rd_index; int chunk_rd_index;
int chunk_rd_offset; int chunk_rd_offset;
@ -105,11 +107,11 @@ struct fygue_fat_resolve
}; };
}; };
/* fygue_fat_init_cold() - fully initialize the FAT information */ /* fygue_fat_initialize() - fully initialize the FAT information */
extern int fygue_fat_init_cold(struct fygue_fat *fat); extern int fygue_fat_initialize(struct fygue_fat *fat);
/* fygue_fat_init_hot() - re-initialize the FAT information */ /* fygue_fat_sync() - re-initialize the FAT information */
extern int fygue_fat_init_hot(struct fygue_fat *fat); extern int fygue_fat_sync(struct fygue_fat *fat);
/* fygue_fat_resolve() - resolve the path and set the dirent information */ /* fygue_fat_resolve() - resolve the path and set the dirent information */
extern int fygue_fat_resolve( extern int fygue_fat_resolve(
@ -122,6 +124,13 @@ extern int fygue_fat_resolve(
// Directory interface // Directory interface
//--- //---
/* fugue_fat_dir_open(): convert dirent to dir */
extern int fygue_fat_dir_open(
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct fygue_fat_dirent *dirent
);
/* fygue_fat_dir_read(): readdir primitive */ /* fygue_fat_dir_read(): readdir primitive */
extern int fygue_fat_dir_read( extern int fygue_fat_dir_read(
struct fygue_fat *fat, struct fygue_fat *fat,
@ -142,10 +151,23 @@ extern int fygue_fat_dir_stat(
struct stat *statbuf struct stat *statbuf
); );
/* fygue_fat_dir_sync(): sync directory information */
extern int fygue_fat_dir_sync(
struct fygue_fat *fat,
struct fygue_fat_dir *dir
);
//--- //---
// File interface // File interface
//--- //---
/* _fygue_fat_file_open(): generate file information */
extern int fygue_fat_file_open(
struct fygue_fat *fat,
struct fygue_fat_file *file,
struct fygue_fat_dirent *dirent
);
/* fygue_fat_file_read(): read primitive */ /* fygue_fat_file_read(): read primitive */
extern int fygue_fat_file_read( extern int fygue_fat_file_read(
struct fygue_fat *fat, struct fygue_fat *fat,
@ -171,7 +193,13 @@ extern int fygue_fat_file_seek(
/* fygue_fat_file_close(): close primitive */ /* fygue_fat_file_close(): close primitive */
extern int fygue_fat_file_close( extern int fygue_fat_file_close(
struct fygue_fat *fat, struct fygue_fat *fat,
struct fygue_fat_file *dir struct fygue_fat_file *file
);
/* fygue_fat_file_sync(): sync internal information */
extern int fygue_fat_file_sync(
struct fygue_fat *fat,
struct fygue_fat_file *file
); );
//--- //---

View file

@ -0,0 +1,44 @@
#include <string.h>
#include "fat.h"
/* fugue_fat_dir_open(): convert dirent to dir */
int fygue_fat_dir_open(
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct fygue_fat_dirent *dirent
) {
int rc;
memset(dir, 0x00, sizeof(struct fygue_fat_dir));
if (dirent == NULL) {
dir->cluster_entry = 0;
dir->root_dirent_count = fat->RootEntCount;
dir->attribute = FYGUE_FAT_FILE_TYPE_DIR;
} else {
if ((dirent->attribute & FYGUE_FAT_FILE_TYPE_DIR) == 0x00)
return -1;
dir->cluster_entry = dirent->cluster_id;
dir->attribute = FYGUE_FAT_FILE_TYPE_DIR;
dir->root_dirent_count = 0;
}
dir->dirty = false;
dir->sector_count = 0;
dir->dirent_cursor = 0;
dir->end_of_dirent = false;
dir->cluster_current = dir->cluster_entry;
rc = fygue_fat_cluster_get_sector(
fat,
dir->cluster_current,
&dir->sector_id
);
if (rc != 0)
return -2;
rc = fygue_fat_sector_get_addr(
fat,
&dir->dirent_current_addr,
dir->sector_id
);
if (rc != 0)
return -3;
return 0;
}

View file

@ -0,0 +1,12 @@
#include "fat.h"
/* fygue_fat_dir_sync(): sync directory information */
int fygue_fat_dir_sync(
struct fygue_fat *fat,
struct fygue_fat_dir *dir
) {
if (fat == NULL || dir == NULL)
return -1;
// nothing to do (?)
return 0;
}

View file

@ -0,0 +1,25 @@
#include <string.h>
#include <stdlib.h>
#include "fat.h"
/* fygue_fat_file_open(): generate file information */
int fygue_fat_file_open(
struct fygue_fat *fat,
struct fygue_fat_file *file,
struct fygue_fat_dirent *dirent
) {
memset(file, 0x00, sizeof(struct fygue_fat_file));
file->attribute = dirent->attribute;
file->cluster_entry = dirent->cluster_id;
file->size = dirent->size;
file->chunk = NULL;
file->chunk_count = 0;
file->chunk_table_max_index = 0;
if (fygue_fat_file_sync(fat, file) != 0)
return -1;
if (fygue_fat_file_seek(fat, file, 0) != 0)
return -2;
return 0;
}

View file

@ -21,6 +21,7 @@ int fygue_fat_file_seek(
offset_test += file->chunk[i].size; offset_test += file->chunk[i].size;
if (offset_test > offset) { if (offset_test > offset) {
file->chunk_rd_offset = offset - offset_test; file->chunk_rd_offset = offset - offset_test;
file->cursor = offset;
return 0; return 0;
} }
file->chunk_rd_index += 1; file->chunk_rd_index += 1;

View file

@ -0,0 +1,84 @@
#include <stdlib.h>
#include "fat.h"
//---
// Internals
//---
/* _fygue_chunk_table_update(): update chunk table */
static int _fygue_chunk_table_update(
struct fygue_fat_file *file,
uintptr_t cluster_addr
) {
uintptr_t cluster_addr_prev;
void *tmp;
if (file->chunk_count > 0)
{
cluster_addr_prev = file->chunk[file->chunk_count - 1].addr;
cluster_addr_prev += file->chunk[file->chunk_count - 1].size;
if (cluster_addr == cluster_addr_prev)
{
file->chunk[file->chunk_count - 1].size += 8*512;
file->chunk[file->chunk_count - 1].cluster_count += 1;
return 0;
}
}
if (file->chunk_count >= file->chunk_table_max_index)
{
tmp = reallocarray(
file->chunk,
file->chunk_table_max_index + 1,
sizeof(*file->chunk)
);
if (tmp == NULL)
return -1;
file->chunk = tmp;
file->chunk_table_max_index += 1;
}
file->chunk[file->chunk_count].size = 8*512;
file->chunk[file->chunk_count].addr = cluster_addr;
file->chunk[file->chunk_count].cluster_count = 1;
file->chunk_count += 1;
return 0;
}
/* _fygue_chunk_error(): invalidate the chunk table */
static int _fygue_chunk_error(struct fygue_fat_file *file)
{
if (file->chunk == NULL)
free(file->chunk);
file->chunk_table_max_index = 0;
file->chunk_count = 0;
return -1;
}
//---
// Public
//---
/* fygue_fat_file_sync(): sync internal information */
int fygue_fat_file_sync(
struct fygue_fat *fat,
struct fygue_fat_file *file
) {
uintptr_t cluster_addr;
int cluster_id;
if (fat == NULL || file == NULL)
return -1;
file->chunk_count = 0;
cluster_id = file->cluster_entry;
while (true)
{
if (fygue_fat_cluster_get_addr(fat, &cluster_addr, cluster_id) != 0)
return _fygue_chunk_error(file);
if (_fygue_chunk_table_update(file, cluster_addr) != 0)
return _fygue_chunk_error(file);
if (fygue_fat_cluster_get_next(fat, &cluster_id) != 0)
break;
}
if (fygue_fat_file_seek(fat, file, file->cursor) != 0)
return -3;
return 0;
}

View file

@ -31,108 +31,6 @@ static int _fygue_path_get_name(
return 0; return 0;
} }
/* _fygue_dirent_resolve_file(): generate file information
*
* notes
* - assume FAT integrity */
static int _fygue_dirent_resolve_file(
struct fygue_fat *fat,
struct fygue_fat_file *file,
struct fygue_fat_dirent *dirent
) {
uintptr_t cluster_addr_prev;
uintptr_t cluster_addr;
size_t cluster_size;
int cluster;
void *tmp;
memset(file, 0x00, sizeof(struct fygue_fat_file));
file->attribute = dirent->attribute;
file->cluster_entry = dirent->cluster_id;
file->size = dirent->size;
file->chunk = NULL;
file->chunk_count = 0;
cluster = file->cluster_entry;
cluster_size = fat->SectorSize * fat->SectorPerClus;
while (true)
{
if (fygue_fat_cluster_get_addr(fat, &cluster_addr, cluster) != 0)
goto error;
if (file->chunk_count > 0) {
cluster_addr_prev = file->chunk[file->chunk_count - 1].addr;
cluster_addr_prev += file->chunk[file->chunk_count - 1].size;
if (cluster_addr == cluster_addr_prev) {
file->chunk[file->chunk_count - 1].size += cluster_size;
file->chunk[file->chunk_count - 1].cluster_count += 1;
if (fygue_fat_cluster_get_next(fat, &cluster) != 0)
break;
continue;
}
}
tmp = reallocarray(
file->chunk,
file->chunk_count + 1,
sizeof(*file->chunk)
);
if (tmp == NULL)
goto error;
file->chunk = tmp;
file->chunk[file->chunk_count].size = cluster_size;
file->chunk[file->chunk_count].addr = cluster_addr;
file->chunk[file->chunk_count].cluster_count = 1;
file->chunk_count += 1;
if (fygue_fat_cluster_get_next(fat, &cluster) != 0)
break;
}
return 0;
error:
if (file->chunk == NULL)
free(file->chunk);
memset(file, 0x00, sizeof(struct fygue_fat_file));
return -1;
}
/* _fugue_dirent_resolve_dir(): convert found dirent to dir */
static int _fygue_dirent_resolve_dir(
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct fygue_fat_dirent *dirent
) {
int rc;
memset(dir, 0x00, sizeof(struct fygue_fat_dir));
if (dirent == NULL) {
dir->cluster_entry = 0;
dir->root_dirent_count = fat->RootEntCount;
dir->attribute = FYGUE_FAT_FILE_TYPE_DIR;
} else {
if ((dirent->attribute & FYGUE_FAT_FILE_TYPE_DIR) == 0x00)
return -1;
dir->cluster_entry = dirent->cluster_id;
dir->attribute = FYGUE_FAT_FILE_TYPE_DIR;
dir->root_dirent_count = 0;
}
dir->dirty = false;
dir->sector_count = 0;
dir->dirent_cursor = 0;
dir->end_of_dirent = false;
dir->cluster_current = dir->cluster_entry;
rc = fygue_fat_cluster_get_sector(
fat,
dir->cluster_current,
&dir->sector_id
);
if (rc != 0)
return -2;
rc = fygue_fat_sector_get_addr(
fat,
&dir->dirent_current_addr,
dir->sector_id
);
return (rc != 0) ? -3 : 0;
}
/* _fygue_opendir_find() - try to find the directory entry */ /* _fygue_opendir_find() - try to find the directory entry */
static int _fygue_dirent_find( static int _fygue_dirent_find(
struct fygue_fat *fat, struct fygue_fat *fat,
@ -159,10 +57,10 @@ static int _fygue_resolve_set(
) { ) {
if (dirent == NULL || (dirent->attribute & FYGUE_FAT_ATTR_DIRECTORY)) { if (dirent == NULL || (dirent->attribute & FYGUE_FAT_ATTR_DIRECTORY)) {
resolve->type = FYGUE_FAT_FILE_TYPE_DIR; resolve->type = FYGUE_FAT_FILE_TYPE_DIR;
return _fygue_dirent_resolve_dir(fat, &(resolve->dir), dirent); return fygue_fat_dir_open(fat, &(resolve->dir), dirent);
} }
resolve->type = FYGUE_FAT_FILE_TYPE_FILE; resolve->type = FYGUE_FAT_FILE_TYPE_FILE;
return _fygue_dirent_resolve_file(fat, &(resolve->file), dirent); return fygue_fat_file_open(fat, &(resolve->file), dirent);
} }
//--- //---
@ -194,7 +92,7 @@ int fygue_fat_resolve(
while (true) while (true)
{ {
if (is_root) { if (is_root) {
if (_fygue_dirent_resolve_dir(fat, &dir, NULL) != 0) if (fygue_fat_dir_open(fat, &dir, NULL) != 0)
return -3; return -3;
if (_fygue_path_get_name(&prefix, &start, &len) != 0) if (_fygue_path_get_name(&prefix, &start, &len) != 0)
break; break;
@ -205,7 +103,7 @@ int fygue_fat_resolve(
return -4; return -4;
if (_fygue_path_get_name(&prefix, &start, &len) != 0) if (_fygue_path_get_name(&prefix, &start, &len) != 0)
break; break;
if (_fygue_dirent_resolve_dir(fat, &dir, &dirent) != 0) if (fygue_fat_dir_open(fat, &dir, &dirent) != 0)
return -5; return -5;
} }
if (is_root) if (is_root)

View file

@ -78,6 +78,33 @@ static int fygue_flash_cmap_update(
// Public // Public
//--- //---
/* fygue_flash_cmap_lsector_get_addr() - get logical sector address */
int fygue_flash_cmap_lsector_get_addr(
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap,
uintptr_t *sector,
uint16_t lsector_id
) {
uintptr_t fsector_addr;
uint16_t lcluster_id;
if (flash == NULL || sector == NULL || cmap == NULL)
return -1;
if (cmap->lcluster == NULL)
return -1;
lcluster_id = lsector_id / 8;
if (
cmap->lcluster_id_max < lcluster_id ||
cmap->lcluster[lcluster_id].fcluster_id == 0xffff
) {
return -2;
}
fsector_addr = cmap->lcluster[lcluster_id].fcluster_addr;
fsector_addr += (lsector_id % 8) * 512;
*sector = fsector_addr;
return 0;
}
/* fygue_flash_cmap_init() - initialize fcluster translation /* fygue_flash_cmap_init() - initialize fcluster translation
* *
* notes: * notes:
@ -95,7 +122,7 @@ static int fygue_flash_cmap_update(
* returns: * returns:
* -1 if the sector 0 is not found * -1 if the sector 0 is not found
* 0 success */ * 0 success */
int fygue_flash_cmap_init( int fygue_flash_cmap_initialize(
struct fygue_flash *flash, struct fygue_flash *flash,
struct fygue_flash_cmap *cmap struct fygue_flash_cmap *cmap
) { ) {
@ -137,29 +164,16 @@ int fygue_flash_cmap_init(
return 0; return 0;
} }
/* fygue_flash_cmap_lsector_get_addr() - get logical sector address */ /* fygue_flash_cmap_sync() - sync the fcluster redirection map */
int fygue_flash_cmap_lsector_get_addr( int fygue_flash_cmap_sync(
struct fygue_flash *flash, struct fygue_flash *flash,
struct fygue_flash_cmap *cmap, struct fygue_flash_cmap *cmap
uintptr_t *sector,
uint16_t lsector_id
) { ) {
uintptr_t fsector_addr; if (flash == NULL || cmap == NULL)
uint16_t lcluster_id;
if (flash == NULL || sector == NULL || cmap == NULL)
return -1; return -1;
if (cmap->lcluster == NULL) for (int i = 0 ; i < cmap->lcluster_id_max ; i++)
return -1; cmap->lcluster[i].version = 0xffffffff;
lcluster_id = lsector_id / 8; if (fygue_flash_cmap_initialize(flash, cmap) != 0)
if (
cmap->lcluster_id_max < lcluster_id ||
cmap->lcluster[lcluster_id].fcluster_id == 0xffff
) {
return -2; return -2;
}
fsector_addr = cmap->lcluster[lcluster_id].fcluster_addr;
fsector_addr += (lsector_id % 8) * 512;
*sector = fsector_addr;
return 0; return 0;
} }

View file

@ -36,9 +36,9 @@ int _fygue_flash_hw_detect(struct fygue_flash *flash)
geometry->fsector_size = FYGUE_FSECTOR_SIZE_128K; geometry->fsector_size = FYGUE_FSECTOR_SIZE_128K;
break; break;
case HWCALC_FXCG100: case HWCALC_FXCG100:
geometry->phy_start = 0x00bc0000; geometry->phy_start = 0x00c80000;
geometry->fsector_size = FYGUE_FSECTOR_SIZE_128K; geometry->fsector_size = FYGUE_FSECTOR_SIZE_128K;
geometry->fsector_count = 0x26; geometry->fsector_count = 0x3d;
break; break;
default: default:
errno = ENOTSUP; errno = ENOTSUP;
@ -69,7 +69,17 @@ int fygue_flash_initialize(struct fygue_flash *flash)
memset(flash, 0x00, sizeof(struct fygue_flash)); memset(flash, 0x00, sizeof(struct fygue_flash));
if (_fygue_flash_hw_detect(flash) != 0) if (_fygue_flash_hw_detect(flash) != 0)
return -2; return -2;
if (fygue_flash_cmap_init(flash, &(flash->cmap)) != 0) if (fygue_flash_cmap_initialize(flash, &(flash->cmap)) != 0)
return -3;
return 0;
}
/* fygue_flash_sync(): re-init flash information */
int fygue_flash_sync(struct fygue_flash *flash)
{
if (flash == NULL)
return -1;
if (fygue_flash_cmap_sync(flash, &(flash->cmap)) != 0)
return -3; return -3;
return 0; return 0;
} }

View file

@ -62,6 +62,9 @@ struct fygue_flash
/* fygue_flash_initialize(): init flash abstraction */ /* fygue_flash_initialize(): init flash abstraction */
extern int fygue_flash_initialize(struct fygue_flash *flash); extern int fygue_flash_initialize(struct fygue_flash *flash);
/* fygue_flash_sync(): re-init flash information */
extern int fygue_flash_sync(struct fygue_flash *flash);
/* fygue_flash_sector_get_addr(): return the logical sector address */ /* fygue_flash_sector_get_addr(): return the logical sector address */
extern int fygue_flash_sector_get_addr( extern int fygue_flash_sector_get_addr(
struct fygue_flash *flash, struct fygue_flash *flash,
@ -73,8 +76,14 @@ extern int fygue_flash_sector_get_addr(
// (internal) cluster map interface // (internal) cluster map interface
//--- //---
/* fygue_flash_cmap_init() - initialize the fcluster redirection map */ /* fygue_flash_cmap_initialize() - initialize the fcluster redirection map */
extern int fygue_flash_cmap_init( extern int fygue_flash_cmap_initialize(
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap
);
/* fygue_flash_cmap_sync() - sync the fcluster redirection map */
extern int fygue_flash_cmap_sync(
struct fygue_flash *flash, struct fygue_flash *flash,
struct fygue_flash_cmap *cmap struct fygue_flash_cmap *cmap
); );

View file

@ -27,7 +27,7 @@ int fygue_mount(struct fygue_fsinfo **fsinfo, bool refresh)
__fygue_fsinfo = calloc(1, sizeof(struct fygue_fsinfo)); __fygue_fsinfo = calloc(1, sizeof(struct fygue_fsinfo));
if (__fygue_fsinfo == NULL) if (__fygue_fsinfo == NULL)
return -2; return -2;
if (fygue_fat_init_cold(&(__fygue_fsinfo->fat)) != 0) { if (fygue_fat_initialize(&(__fygue_fsinfo->fat)) != 0) {
free(__fygue_fsinfo); free(__fygue_fsinfo);
__fygue_fsinfo = NULL; __fygue_fsinfo = NULL;
return -3; return -3;
@ -35,7 +35,7 @@ int fygue_mount(struct fygue_fsinfo **fsinfo, bool refresh)
__fygue_fsinfo->dirty = false; __fygue_fsinfo->dirty = false;
} }
if (refresh && __fygue_fsinfo->dirty) { if (refresh && __fygue_fsinfo->dirty) {
if (fygue_fat_init_hot(&(__fygue_fsinfo->fat)) != 0) if (fygue_fat_sync(&(__fygue_fsinfo->fat)) != 0)
return -4; return -4;
__fygue_fsinfo->dirty = false; __fygue_fsinfo->dirty = false;
} }
@ -82,6 +82,34 @@ int fygue_resolve(char const * const path, struct fygue_resolve *resolve)
return 0; return 0;
} }
//---
// Syncronization
//---
/* fygue_descriptor_sync(): sync internal descriptor information */
int fygue_descriptor_sync(
struct fygue_fsinfo **fsinfo,
struct fygue_descriptor *desc
) {
int (*sync)(struct fygue_descriptor*);
struct fygue_fsinfo *ffsinfo;
if (fygue_mount(&ffsinfo, true) != 0)
return -2;
if (fsinfo != NULL)
*fsinfo = ffsinfo;
if (desc != NULL && desc->dirty)
{
sync = &fygue_file_sync;
if (desc->resolve.type == FYGUE_FILE_TYPE_DIR)
sync = &fygue_dir_sync;
if (sync(desc) != 0)
return -1;
desc->dirty = false;
}
return 0;
}
//--- //---
// Descriptor // Descriptor
//--- //---

View file

@ -65,7 +65,6 @@ 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;
@ -88,6 +87,11 @@ struct fygue_descriptor
/* fygue_mount(): mount and return the filesystem info */ /* fygue_mount(): mount and return the filesystem info */
extern int fygue_mount(struct fygue_fsinfo **fsinfo, bool refresh); extern int fygue_mount(struct fygue_fsinfo **fsinfo, bool refresh);
/* fygue_descriptor_sync(): sync internal descriptor information */
extern int fygue_descriptor_sync(
struct fygue_fsinfo **fsinfo,
struct fygue_descriptor *desc
);
/* fygue_resolve() - try to resolve path */ /* fygue_resolve() - try to resolve path */
extern int fygue_resolve( extern int fygue_resolve(
@ -123,6 +127,9 @@ extern ssize_t fygue_dir_write(
/* fygue_dir_close(): close directory */ /* fygue_dir_close(): close directory */
extern int fygue_dir_close(struct fygue_descriptor *desc); extern int fygue_dir_close(struct fygue_descriptor *desc);
/* fygue_dir_sync(): directory-specific sync */
extern int fygue_dir_sync(struct fygue_descriptor *desc);
//--- //---
// File interface // File interface
//--- //---
@ -151,6 +158,9 @@ extern ssize_t fygue_file_write(
/* fygue_file_close(): close directory */ /* fygue_file_close(): close directory */
extern int fygue_file_close(struct fygue_descriptor *desc); extern int fygue_file_close(struct fygue_descriptor *desc);
/* fygue_file_sync(): file-specific sync */
extern int fygue_file_sync(struct fygue_descriptor *desc);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -13,7 +13,7 @@ int fygue_dir_close(struct fygue_descriptor *desc)
errno = EBADF; errno = EBADF;
return -1; return -1;
} }
if (fygue_mount(&fsinfo, true) != 0) { if (fygue_descriptor_sync(&fsinfo, desc) != 0) {
errno = EIO; errno = EIO;
return -1; return -1;
} }

View file

@ -35,6 +35,10 @@ off_t fygue_dir_lseek(
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
if (fygue_descriptor_sync(NULL, desc) != 0) {
errno = EIO;
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

@ -77,7 +77,6 @@ int fygue_dir_read(
int rc; int rc;
ENOTSUP_IF_NOT_FYGUE(-1); 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;
@ -90,7 +89,7 @@ int fygue_dir_read(
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
if (fygue_mount(&fsinfo, true) != 0) { if (fygue_descriptor_sync(&fsinfo, desc) != 0) {
errno = EIO; errno = EIO;
return -1; return -1;
} }

View file

@ -0,0 +1,33 @@
#include <stdlib.h>
#include "fygue.h"
/* fygue_dir_sync(): directory-specific sync */
int fygue_dir_sync(struct fygue_descriptor *desc)
{
struct fygue_fsinfo *fsinfo;
int rc;
ENOTSUP_IF_NOT_FYGUE(-1);
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
errno = EBADF;
return -1;
}
//if (desc->)
if (fygue_mount(&fsinfo, true)) {
errno = EIO;
return -1;
}
for (int i = 0 ; i < desc->resolve.dir.count ; i++) {
if (desc->resolve.dir.dirent[i] == NULL)
continue;
free(desc->resolve.dir.dirent[i]);
desc->resolve.dir.dirent[i] = NULL;
}
rc = fygue_fat_dir_sync(
&(fsinfo->fat),
&(desc->resolve.dir.fat)
);
if (rc != 0)
return -2;
return 0;
}

View file

@ -13,7 +13,7 @@ int fygue_file_close(struct fygue_descriptor *desc)
errno = EBADF; errno = EBADF;
return -1; return -1;
} }
if (fygue_mount(&fsinfo, true) != 0) { if (fygue_descriptor_sync(&fsinfo, desc) != 0) {
errno = EIO; errno = EIO;
return -1; return -1;
} }

View file

@ -1,6 +1,6 @@
#include "fygue.h" #include "fygue.h"
/* fygue_file_lseek(): seek directory */ /* fygue_file_lseek(): seek file */
off_t fygue_file_lseek( off_t fygue_file_lseek(
struct fygue_descriptor *desc, struct fygue_descriptor *desc,
off_t offset, off_t offset,
@ -17,7 +17,7 @@ off_t fygue_file_lseek(
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
if (fygue_mount(&fsinfo, true) != 0) { if (fygue_descriptor_sync(&fsinfo, desc) != 0) {
errno = EIO; errno = EIO;
return -1; return -1;
} }

View file

@ -19,6 +19,10 @@ ssize_t fygue_file_read(
errno = EFAULT; errno = EFAULT;
return -1; return -1;
} }
if (fygue_file_sync(desc) != 0) {
errno = EIO;
return -1;
}
if (fygue_mount(&fsinfo, true) != 0) { if (fygue_mount(&fsinfo, true) != 0) {
errno = EIO; errno = EIO;
return -1; return -1;

View file

@ -0,0 +1,26 @@
#include "fygue.h"
/* fygue_file_sync(): file-specific sync */
int fygue_file_sync(struct fygue_descriptor *desc)
{
struct fygue_fsinfo *fsinfo;
int rc;
ENOTSUP_IF_NOT_FYGUE(-1);
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_FILE) {
errno = EBADF;
return -1;
}
if (fygue_mount(&fsinfo, true)) {
errno = EIO;
return -1;
}
// nothing to sync in high-level
rc = fygue_fat_file_sync(
&(fsinfo->fat),
&(desc->resolve.file.fat)
);
if (rc != 0)
return -1;
return 0;
}

View file

@ -16,7 +16,6 @@ int fygue_stat(char const * const path, struct stat *statbuf)
errno = EIO; errno = EIO;
return -1; return -1;
} }
if (fygue_resolve(path, &resolve) != 0) { if (fygue_resolve(path, &resolve) != 0) {
errno = ENOENT; errno = ENOENT;
return -1; return -1;