mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-05-18 23:39:17 +02:00
fygue: WIP prepare syncfs() implementation + fix Math+ Flash information
This commit is contained in:
parent
ba7d84dbb2
commit
c99a18d748
23 changed files with 388 additions and 155 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
);
|
);
|
||||||
|
|
||||||
//---
|
//---
|
||||||
|
|
44
src/fs/fygue/fat/fat_dir_open.c
Normal file
44
src/fs/fygue/fat/fat_dir_open.c
Normal 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;
|
||||||
|
}
|
12
src/fs/fygue/fat/fat_dir_sync.c
Normal file
12
src/fs/fygue/fat/fat_dir_sync.c
Normal 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;
|
||||||
|
}
|
25
src/fs/fygue/fat/fat_file_open.c
Normal file
25
src/fs/fygue/fat/fat_file_open.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
84
src/fs/fygue/fat/fat_file_sync.c
Normal file
84
src/fs/fygue/fat/fat_file_sync.c
Normal 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;
|
||||||
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
);
|
);
|
||||||
|
|
|
@ -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
|
||||||
//---
|
//---
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
33
src/fs/fygue/fygue_dir_sync.c
Normal file
33
src/fs/fygue/fygue_dir_sync.c
Normal 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;
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
26
src/fs/fygue/fygue_file_sync.c
Normal file
26
src/fs/fygue/fygue_file_sync.c
Normal 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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue