diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ae6bcf..34e2c03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -274,9 +274,11 @@ set(SOURCES src/fs/fygue/fygue_file_read.c src/fs/fygue/fat/cluster.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_close.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_close.c src/fs/fygue/fat/fat_file_read.c diff --git a/src/fs/fygue/fat/fat.c b/src/fs/fygue/fat/fat.c index 840eb07..30b2e72 100644 --- a/src/fs/fygue/fat/fat.c +++ b/src/fs/fygue/fat/fat.c @@ -153,8 +153,8 @@ static int _fygue_fat_prepare(struct fygue_fat *fat) // Public //--- -/* fygue_fat_init_cold() - fully initialize the FAT information */ -int fygue_fat_init_cold(struct fygue_fat *fat) +/* fygue_fat_initialize() - fully initialize the FAT information */ +int fygue_fat_initialize(struct fygue_fat *fat) { if (fat == NULL) return -1; @@ -170,11 +170,14 @@ int fygue_fat_init_cold(struct fygue_fat *fat) return 0; } -/* fygue_fat_init_hot(): re-initialize the FAT information */ -int fygue_fat_init_hot(struct fygue_fat *fat) +/* fygue_fat_sync(): re-initialize the FAT information */ +int fygue_fat_sync(struct fygue_fat *fat) { - //FIXME: implement - (void)fat; - errno = ENOTSUP; - return -3; + if (fat == NULL) + return -1; + if (fygue_flash_sync((&fat->_flash)) != 0) + return -2; + if (_fygue_fat_prepare(fat) != 0) + return -3; + return 0; } diff --git a/src/fs/fygue/fat/fat.h b/src/fs/fygue/fat/fat.h index b33dd11..4701440 100644 --- a/src/fs/fygue/fat/fat.h +++ b/src/fs/fygue/fat/fat.h @@ -82,11 +82,13 @@ struct fygue_fat_file int cluster_entry; int attribute; size_t size; + off_t cursor; struct { uintptr_t addr; size_t size; int cluster_count; } *chunk; + int chunk_table_max_index; int chunk_count; int chunk_rd_index; int chunk_rd_offset; @@ -105,11 +107,11 @@ struct fygue_fat_resolve }; }; -/* fygue_fat_init_cold() - fully initialize the FAT information */ -extern int fygue_fat_init_cold(struct fygue_fat *fat); +/* fygue_fat_initialize() - fully initialize the FAT information */ +extern int fygue_fat_initialize(struct fygue_fat *fat); -/* fygue_fat_init_hot() - re-initialize the FAT information */ -extern int fygue_fat_init_hot(struct fygue_fat *fat); +/* fygue_fat_sync() - re-initialize the FAT information */ +extern int fygue_fat_sync(struct fygue_fat *fat); /* fygue_fat_resolve() - resolve the path and set the dirent information */ extern int fygue_fat_resolve( @@ -122,6 +124,13 @@ extern int fygue_fat_resolve( // 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 */ extern int fygue_fat_dir_read( struct fygue_fat *fat, @@ -142,10 +151,23 @@ extern int fygue_fat_dir_stat( 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 //--- +/* _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 */ extern int fygue_fat_file_read( struct fygue_fat *fat, @@ -171,7 +193,13 @@ extern int fygue_fat_file_seek( /* fygue_fat_file_close(): close primitive */ extern int fygue_fat_file_close( 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 ); //--- diff --git a/src/fs/fygue/fat/fat_dir_open.c b/src/fs/fygue/fat/fat_dir_open.c new file mode 100644 index 0000000..0c43768 --- /dev/null +++ b/src/fs/fygue/fat/fat_dir_open.c @@ -0,0 +1,44 @@ +#include +#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; +} diff --git a/src/fs/fygue/fat/fat_dir_sync.c b/src/fs/fygue/fat/fat_dir_sync.c new file mode 100644 index 0000000..8f2761a --- /dev/null +++ b/src/fs/fygue/fat/fat_dir_sync.c @@ -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; +} diff --git a/src/fs/fygue/fat/fat_file_open.c b/src/fs/fygue/fat/fat_file_open.c new file mode 100644 index 0000000..b0f4de7 --- /dev/null +++ b/src/fs/fygue/fat/fat_file_open.c @@ -0,0 +1,25 @@ +#include +#include +#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; +} + + diff --git a/src/fs/fygue/fat/fat_file_seek.c b/src/fs/fygue/fat/fat_file_seek.c index 458ad64..c9b3c37 100644 --- a/src/fs/fygue/fat/fat_file_seek.c +++ b/src/fs/fygue/fat/fat_file_seek.c @@ -21,6 +21,7 @@ int fygue_fat_file_seek( offset_test += file->chunk[i].size; if (offset_test > offset) { file->chunk_rd_offset = offset - offset_test; + file->cursor = offset; return 0; } file->chunk_rd_index += 1; diff --git a/src/fs/fygue/fat/fat_file_sync.c b/src/fs/fygue/fat/fat_file_sync.c new file mode 100644 index 0000000..0adda80 --- /dev/null +++ b/src/fs/fygue/fat/fat_file_sync.c @@ -0,0 +1,84 @@ +#include +#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; +} diff --git a/src/fs/fygue/fat/resolve.c b/src/fs/fygue/fat/resolve.c index 6400c0c..73f8bc2 100644 --- a/src/fs/fygue/fat/resolve.c +++ b/src/fs/fygue/fat/resolve.c @@ -31,108 +31,6 @@ static int _fygue_path_get_name( 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 */ static int _fygue_dirent_find( struct fygue_fat *fat, @@ -159,10 +57,10 @@ static int _fygue_resolve_set( ) { if (dirent == NULL || (dirent->attribute & FYGUE_FAT_ATTR_DIRECTORY)) { 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; - 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) { if (is_root) { - if (_fygue_dirent_resolve_dir(fat, &dir, NULL) != 0) + if (fygue_fat_dir_open(fat, &dir, NULL) != 0) return -3; if (_fygue_path_get_name(&prefix, &start, &len) != 0) break; @@ -205,7 +103,7 @@ int fygue_fat_resolve( return -4; if (_fygue_path_get_name(&prefix, &start, &len) != 0) break; - if (_fygue_dirent_resolve_dir(fat, &dir, &dirent) != 0) + if (fygue_fat_dir_open(fat, &dir, &dirent) != 0) return -5; } if (is_root) diff --git a/src/fs/fygue/flash/cmap.c b/src/fs/fygue/flash/cmap.c index b16d669..e61f0ca 100644 --- a/src/fs/fygue/flash/cmap.c +++ b/src/fs/fygue/flash/cmap.c @@ -78,6 +78,33 @@ static int fygue_flash_cmap_update( // 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 * * notes: @@ -95,7 +122,7 @@ static int fygue_flash_cmap_update( * returns: * -1 if the sector 0 is not found * 0 success */ -int fygue_flash_cmap_init( +int fygue_flash_cmap_initialize( struct fygue_flash *flash, struct fygue_flash_cmap *cmap ) { @@ -137,29 +164,16 @@ int fygue_flash_cmap_init( return 0; } -/* fygue_flash_cmap_lsector_get_addr() - get logical sector address */ -int fygue_flash_cmap_lsector_get_addr( +/* fygue_flash_cmap_sync() - sync the fcluster redirection map */ +int fygue_flash_cmap_sync( struct fygue_flash *flash, - struct fygue_flash_cmap *cmap, - uintptr_t *sector, - uint16_t lsector_id + struct fygue_flash_cmap *cmap ) { - uintptr_t fsector_addr; - uint16_t lcluster_id; - - if (flash == NULL || sector == NULL || cmap == NULL) + if (flash == 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 - ) { + for (int i = 0 ; i < cmap->lcluster_id_max ; i++) + cmap->lcluster[i].version = 0xffffffff; + if (fygue_flash_cmap_initialize(flash, cmap) != 0) return -2; - } - fsector_addr = cmap->lcluster[lcluster_id].fcluster_addr; - fsector_addr += (lsector_id % 8) * 512; - *sector = fsector_addr; return 0; } diff --git a/src/fs/fygue/flash/flash.c b/src/fs/fygue/flash/flash.c index 1302803..a3ffd34 100644 --- a/src/fs/fygue/flash/flash.c +++ b/src/fs/fygue/flash/flash.c @@ -36,9 +36,9 @@ int _fygue_flash_hw_detect(struct fygue_flash *flash) geometry->fsector_size = FYGUE_FSECTOR_SIZE_128K; break; case HWCALC_FXCG100: - geometry->phy_start = 0x00bc0000; + geometry->phy_start = 0x00c80000; geometry->fsector_size = FYGUE_FSECTOR_SIZE_128K; - geometry->fsector_count = 0x26; + geometry->fsector_count = 0x3d; break; default: errno = ENOTSUP; @@ -69,7 +69,17 @@ int fygue_flash_initialize(struct fygue_flash *flash) memset(flash, 0x00, sizeof(struct fygue_flash)); if (_fygue_flash_hw_detect(flash) != 0) 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 0; } diff --git a/src/fs/fygue/flash/flash.h b/src/fs/fygue/flash/flash.h index 7224a43..677faee 100644 --- a/src/fs/fygue/flash/flash.h +++ b/src/fs/fygue/flash/flash.h @@ -62,6 +62,9 @@ struct fygue_flash /* fygue_flash_initialize(): init flash abstraction */ 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 */ extern int fygue_flash_sector_get_addr( struct fygue_flash *flash, @@ -73,8 +76,14 @@ extern int fygue_flash_sector_get_addr( // (internal) cluster map interface //--- -/* fygue_flash_cmap_init() - initialize the fcluster redirection map */ -extern int fygue_flash_cmap_init( +/* fygue_flash_cmap_initialize() - initialize the fcluster redirection map */ +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_cmap *cmap ); diff --git a/src/fs/fygue/fygue.c b/src/fs/fygue/fygue.c index e4ed053..72577b2 100644 --- a/src/fs/fygue/fygue.c +++ b/src/fs/fygue/fygue.c @@ -27,7 +27,7 @@ int fygue_mount(struct fygue_fsinfo **fsinfo, bool refresh) __fygue_fsinfo = calloc(1, sizeof(struct fygue_fsinfo)); if (__fygue_fsinfo == NULL) return -2; - if (fygue_fat_init_cold(&(__fygue_fsinfo->fat)) != 0) { + if (fygue_fat_initialize(&(__fygue_fsinfo->fat)) != 0) { free(__fygue_fsinfo); __fygue_fsinfo = NULL; return -3; @@ -35,7 +35,7 @@ int fygue_mount(struct fygue_fsinfo **fsinfo, bool refresh) __fygue_fsinfo->dirty = false; } if (refresh && __fygue_fsinfo->dirty) { - if (fygue_fat_init_hot(&(__fygue_fsinfo->fat)) != 0) + if (fygue_fat_sync(&(__fygue_fsinfo->fat)) != 0) return -4; __fygue_fsinfo->dirty = false; } @@ -82,6 +82,34 @@ int fygue_resolve(char const * const path, struct fygue_resolve *resolve) 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 //--- diff --git a/src/fs/fygue/fygue.h b/src/fs/fygue/fygue.h index 6e1d931..d8ae317 100644 --- a/src/fs/fygue/fygue.h +++ b/src/fs/fygue/fygue.h @@ -65,7 +65,6 @@ struct fygue_resolve { struct { off_t cursor; struct fygue_fat_file fat; - off_t size; } file; struct { struct fygue_fat_dir fat; @@ -88,6 +87,11 @@ struct fygue_descriptor /* fygue_mount(): mount and return the filesystem info */ 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 */ extern int fygue_resolve( @@ -123,6 +127,9 @@ extern ssize_t fygue_dir_write( /* fygue_dir_close(): close directory */ 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 //--- @@ -151,6 +158,9 @@ extern ssize_t fygue_file_write( /* fygue_file_close(): close directory */ 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 } #endif diff --git a/src/fs/fygue/fygue_dir_close.c b/src/fs/fygue/fygue_dir_close.c index 518607e..a2e670f 100644 --- a/src/fs/fygue/fygue_dir_close.c +++ b/src/fs/fygue/fygue_dir_close.c @@ -13,7 +13,7 @@ int fygue_dir_close(struct fygue_descriptor *desc) errno = EBADF; return -1; } - if (fygue_mount(&fsinfo, true) != 0) { + if (fygue_descriptor_sync(&fsinfo, desc) != 0) { errno = EIO; return -1; } diff --git a/src/fs/fygue/fygue_dir_lseek.c b/src/fs/fygue/fygue_dir_lseek.c index fa3184c..f1809e1 100644 --- a/src/fs/fygue/fygue_dir_lseek.c +++ b/src/fs/fygue/fygue_dir_lseek.c @@ -35,6 +35,10 @@ off_t fygue_dir_lseek( errno = EINVAL; return -1; } + if (fygue_descriptor_sync(NULL, desc) != 0) { + errno = EIO; + return -1; + } if(whence == SEEK_CUR) offset += desc->resolve.dir.pos; if(whence == SEEK_END) { diff --git a/src/fs/fygue/fygue_dir_read.c b/src/fs/fygue/fygue_dir_read.c index b72148c..7ff183f 100644 --- a/src/fs/fygue/fygue_dir_read.c +++ b/src/fs/fygue/fygue_dir_read.c @@ -77,7 +77,6 @@ int fygue_dir_read( int rc; ENOTSUP_IF_NOT_FYGUE(-1); - if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) { errno = EBADF; return -1; @@ -90,7 +89,7 @@ int fygue_dir_read( errno = EINVAL; return -1; } - if (fygue_mount(&fsinfo, true) != 0) { + if (fygue_descriptor_sync(&fsinfo, desc) != 0) { errno = EIO; return -1; } diff --git a/src/fs/fygue/fygue_dir_sync.c b/src/fs/fygue/fygue_dir_sync.c new file mode 100644 index 0000000..7b5a296 --- /dev/null +++ b/src/fs/fygue/fygue_dir_sync.c @@ -0,0 +1,33 @@ +#include +#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; +} diff --git a/src/fs/fygue/fygue_file_close.c b/src/fs/fygue/fygue_file_close.c index 8f2ad8a..51131c2 100644 --- a/src/fs/fygue/fygue_file_close.c +++ b/src/fs/fygue/fygue_file_close.c @@ -13,7 +13,7 @@ int fygue_file_close(struct fygue_descriptor *desc) errno = EBADF; return -1; } - if (fygue_mount(&fsinfo, true) != 0) { + if (fygue_descriptor_sync(&fsinfo, desc) != 0) { errno = EIO; return -1; } diff --git a/src/fs/fygue/fygue_file_lseek.c b/src/fs/fygue/fygue_file_lseek.c index bd3da94..e4ff525 100644 --- a/src/fs/fygue/fygue_file_lseek.c +++ b/src/fs/fygue/fygue_file_lseek.c @@ -1,6 +1,6 @@ #include "fygue.h" -/* fygue_file_lseek(): seek directory */ +/* fygue_file_lseek(): seek file */ off_t fygue_file_lseek( struct fygue_descriptor *desc, off_t offset, @@ -17,7 +17,7 @@ off_t fygue_file_lseek( errno = EINVAL; return -1; } - if (fygue_mount(&fsinfo, true) != 0) { + if (fygue_descriptor_sync(&fsinfo, desc) != 0) { errno = EIO; return -1; } diff --git a/src/fs/fygue/fygue_file_read.c b/src/fs/fygue/fygue_file_read.c index 2a93995..1f8c18f 100644 --- a/src/fs/fygue/fygue_file_read.c +++ b/src/fs/fygue/fygue_file_read.c @@ -19,6 +19,10 @@ ssize_t fygue_file_read( errno = EFAULT; return -1; } + if (fygue_file_sync(desc) != 0) { + errno = EIO; + return -1; + } if (fygue_mount(&fsinfo, true) != 0) { errno = EIO; return -1; diff --git a/src/fs/fygue/fygue_file_sync.c b/src/fs/fygue/fygue_file_sync.c new file mode 100644 index 0000000..52d10a2 --- /dev/null +++ b/src/fs/fygue/fygue_file_sync.c @@ -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; +} diff --git a/src/fs/fygue/fygue_stat.c b/src/fs/fygue/fygue_stat.c index 2028dd6..97f867c 100644 --- a/src/fs/fygue/fygue_stat.c +++ b/src/fs/fygue/fygue_stat.c @@ -16,7 +16,6 @@ int fygue_stat(char const * const path, struct stat *statbuf) errno = EIO; return -1; } - if (fygue_resolve(path, &resolve) != 0) { errno = ENOENT; return -1;