mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-05-18 15:29:16 +02:00
fygue: fix FAT cluster resolution + support stat() for directory + support stat(), lseek() and write() (EROFS) for file
This commit is contained in:
parent
bad0dbd5f4
commit
eaa0602225
10 changed files with 136 additions and 16 deletions
|
@ -268,6 +268,8 @@ set(SOURCES
|
||||||
src/fs/fygue/fygue_dir_lseek.c
|
src/fs/fygue/fygue_dir_lseek.c
|
||||||
src/fs/fygue/fygue_dir_write.c
|
src/fs/fygue/fygue_dir_write.c
|
||||||
src/fs/fygue/fygue_dir_close.c
|
src/fs/fygue/fygue_dir_close.c
|
||||||
|
src/fs/fygue/fygue_file_lseek.c
|
||||||
|
src/fs/fygue/fygue_file_write.c
|
||||||
src/fs/fygue/fat/cluster.c
|
src/fs/fygue/fat/cluster.c
|
||||||
src/fs/fygue/fat/initialize.c
|
src/fs/fygue/fat/initialize.c
|
||||||
src/fs/fygue/fat/fat_dir_read.c
|
src/fs/fygue/fat/fat_dir_read.c
|
||||||
|
|
|
@ -2,29 +2,64 @@
|
||||||
** fygue/fat/cluster - FAT cluster handling
|
** fygue/fat/cluster - FAT cluster handling
|
||||||
*/
|
*/
|
||||||
#include "fat.h"
|
#include "fat.h"
|
||||||
|
#include "../flash/flash.h"
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Public
|
// Public
|
||||||
//---
|
//---
|
||||||
|
|
||||||
/* fygue_fat_cluster_get_next() - find the next cluster ID of a file */
|
/* fygue_fat_cluster_get_next() - find the next cluster ID of a file
|
||||||
|
*
|
||||||
|
* returns
|
||||||
|
* -7 next cluster unused (0x0000)
|
||||||
|
* -6 next cluster end (0xffff)
|
||||||
|
* -5 internal error
|
||||||
|
* -4 provided cluster unused (0x0000)
|
||||||
|
* -3 provided cluster end (0xffff)
|
||||||
|
* -2 provided invalid cluster (root or "out of fat")
|
||||||
|
* -1 argument error
|
||||||
|
* 0 success
|
||||||
|
*
|
||||||
|
* todo
|
||||||
|
* - ensure FAT1 information is the same ? */
|
||||||
int fygue_fat_cluster_get_next(struct fygue_fat *fat, int *cluster_current)
|
int fygue_fat_cluster_get_next(struct fygue_fat *fat, int *cluster_current)
|
||||||
{
|
{
|
||||||
uint16_t *fat0;
|
uint16_t *fat0;
|
||||||
|
int nb_entry_per_sector;
|
||||||
|
int cluster_sector;
|
||||||
|
int cluster_real;
|
||||||
int cluster;
|
int cluster;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (fat == NULL || cluster_current == NULL)
|
if (fat == NULL || cluster_current == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
cluster = *cluster_current;
|
cluster = *cluster_current;
|
||||||
|
if (cluster == 0xffff)
|
||||||
|
return -3;
|
||||||
|
if (cluster == 0x0000)
|
||||||
|
return -4;
|
||||||
if (cluster <= 1)
|
if (cluster <= 1)
|
||||||
return -2;
|
return -2;
|
||||||
if (cluster >= fat->ClusterCount)
|
if (cluster >= fat->ClusterCount)
|
||||||
return -2;
|
return -2;
|
||||||
fat0 = (void*)fat->FAT0Addr;
|
nb_entry_per_sector = fat->SectorSize / 2;
|
||||||
if (fat0[cluster] == 0xffff)
|
cluster_sector = cluster / nb_entry_per_sector;
|
||||||
return -3;
|
cluster_real = cluster - (cluster_sector * nb_entry_per_sector);
|
||||||
*cluster_current = fat0[cluster];
|
rc = fygue_fat_sector_get_addr(
|
||||||
return 0;
|
fat,
|
||||||
|
(void*)&fat0,
|
||||||
|
fat->FAT0SectorID + cluster_sector
|
||||||
|
);
|
||||||
|
if (rc < 0)
|
||||||
|
return -5;
|
||||||
|
rc = 0;
|
||||||
|
cluster = FAT_WORD(fat0[cluster_real]);
|
||||||
|
if (cluster == 0xffff)
|
||||||
|
rc = -6;
|
||||||
|
if (cluster == 0x0000)
|
||||||
|
rc = -7;
|
||||||
|
*cluster_current = cluster;
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fygue_fat_cluster_get_sector() - get sector ID from cluster ID */
|
/* fygue_fat_cluster_get_sector() - get sector ID from cluster ID */
|
||||||
|
|
|
@ -44,8 +44,6 @@ struct fygue_fat
|
||||||
int FAT1SectorID;
|
int FAT1SectorID;
|
||||||
int RootSectorID;
|
int RootSectorID;
|
||||||
int DataSectorID;
|
int DataSectorID;
|
||||||
uintptr_t FAT0Addr;
|
|
||||||
uintptr_t FAT1Addr;
|
|
||||||
uintptr_t RootAddr;
|
uintptr_t RootAddr;
|
||||||
uintptr_t BPB;
|
uintptr_t BPB;
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -147,23 +147,26 @@ static int _fygue_fat_configure(struct fygue_fat *fat)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _fygue_fat_prepare() - prepare logic information */
|
/* _fygue_fat_prepare() - prepare logic information */
|
||||||
static int _fygue_fat_prepare(struct fygue_fat *fat) {
|
static int _fygue_fat_prepare(struct fygue_fat *fat)
|
||||||
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = fygue_flash_cmap_lsector_get_addr(
|
#if 0
|
||||||
&fat->_flash.cmap,
|
rc = fygue_fat_sector_get_addr(
|
||||||
|
fat,
|
||||||
&fat->FAT0Addr,
|
&fat->FAT0Addr,
|
||||||
fat->FAT0SectorID
|
fat->FAT0SectorID
|
||||||
);
|
);
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
return -1;
|
return -1;
|
||||||
rc = fygue_flash_cmap_lsector_get_addr(
|
rc = fygue_fat_sector_get_addr(
|
||||||
&fat->_flash.cmap,
|
fat,
|
||||||
(void*)&fat->FAT1Addr,
|
(void*)&fat->FAT1Addr,
|
||||||
fat->FAT1SectorID
|
fat->FAT1SectorID
|
||||||
);
|
);
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
#endif
|
||||||
rc = fygue_flash_cmap_lsector_get_addr(
|
rc = fygue_flash_cmap_lsector_get_addr(
|
||||||
&fat->_flash.cmap,
|
&fat->_flash.cmap,
|
||||||
&fat->RootAddr,
|
&fat->RootAddr,
|
||||||
|
|
|
@ -85,8 +85,8 @@ int fygue_resolve(char const * const path, struct fygue_resolve *resolve)
|
||||||
|
|
||||||
const fs_descriptor_type_t fygue_descriptor_type = {
|
const fs_descriptor_type_t fygue_descriptor_type = {
|
||||||
.read = NULL,
|
.read = NULL,
|
||||||
.write = NULL,
|
.write = (void*)&fygue_file_write,
|
||||||
.lseek = NULL,
|
.lseek = (void*)&fygue_file_lseek,
|
||||||
.close = NULL,
|
.close = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -94,5 +94,5 @@ const fs_descriptor_type_t fygue_dir_descriptor_type = {
|
||||||
.read = (void*)&fygue_dir_read,
|
.read = (void*)&fygue_dir_read,
|
||||||
.write = (void*)&fygue_dir_write,
|
.write = (void*)&fygue_dir_write,
|
||||||
.lseek = (void*)&fygue_dir_lseek,
|
.lseek = (void*)&fygue_dir_lseek,
|
||||||
.close = NULL,
|
.close = (void*)&fygue_dir_close,
|
||||||
};
|
};
|
||||||
|
|
|
@ -65,6 +65,7 @@ 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;
|
||||||
|
@ -94,6 +95,10 @@ extern int fygue_resolve(
|
||||||
struct fygue_resolve *resolve
|
struct fygue_resolve *resolve
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Directory interface
|
||||||
|
//---
|
||||||
|
|
||||||
/* fygue_dir_read(): directory read implementation */
|
/* fygue_dir_read(): directory read implementation */
|
||||||
extern int fygue_dir_read(
|
extern int fygue_dir_read(
|
||||||
struct fygue_descriptor *desc,
|
struct fygue_descriptor *desc,
|
||||||
|
@ -115,6 +120,27 @@ ssize_t fygue_dir_write(
|
||||||
size_t size
|
size_t size
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* fygue_dir_close(): close directory */
|
||||||
|
extern int fygue_dir_close(struct fygue_descriptor *desc);
|
||||||
|
|
||||||
|
//---
|
||||||
|
// File interface
|
||||||
|
//---
|
||||||
|
|
||||||
|
/* fygue_file_lseek(): seek directory */
|
||||||
|
extern off_t fygue_file_lseek(
|
||||||
|
struct fygue_descriptor *desc,
|
||||||
|
off_t offset,
|
||||||
|
int whence
|
||||||
|
);
|
||||||
|
|
||||||
|
/* fygue_file_write(): write directory (EROFS) */
|
||||||
|
extern ssize_t fygue_file_write(
|
||||||
|
struct fygue_descriptor *desc,
|
||||||
|
void *buffer,
|
||||||
|
size_t size
|
||||||
|
);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "fygue.h"
|
#include "fygue.h"
|
||||||
#include "fat/fat.h"
|
#include "fat/fat.h"
|
||||||
|
|
||||||
|
/* fygue_dir_close(): close directory */
|
||||||
int fygue_dir_close(struct fygue_descriptor *desc)
|
int fygue_dir_close(struct fygue_descriptor *desc)
|
||||||
{
|
{
|
||||||
struct fygue_fsinfo *fsinfo;
|
struct fygue_fsinfo *fsinfo;
|
||||||
|
|
|
@ -26,10 +26,15 @@ off_t fygue_dir_lseek(
|
||||||
off_t offset,
|
off_t offset,
|
||||||
int whence
|
int whence
|
||||||
) {
|
) {
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
if (whence != SEEK_CUR && whence != SEEK_SET && whence != SEEK_END) {
|
||||||
|
errno = EINVAL;
|
||||||
|
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) {
|
||||||
|
|
28
src/fs/fygue/fygue_file_lseek.c
Normal file
28
src/fs/fygue/fygue_file_lseek.c
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#include "fygue.h"
|
||||||
|
|
||||||
|
/* fygue_file_lseek(): seek directory */
|
||||||
|
off_t fygue_file_lseek(
|
||||||
|
struct fygue_descriptor *desc,
|
||||||
|
off_t offset,
|
||||||
|
int whence
|
||||||
|
) {
|
||||||
|
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||||
|
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_FILE) {
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (whence != SEEK_CUR && whence != SEEK_SET && whence != SEEK_END) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(whence == SEEK_CUR)
|
||||||
|
offset += desc->resolve.dir.pos;
|
||||||
|
if(whence == SEEK_END)
|
||||||
|
offset += desc->resolve.file.size;
|
||||||
|
if(offset < 0 || offset >= desc->resolve.file.size + 1) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
desc->resolve.file.cursor = offset;
|
||||||
|
return desc->resolve.file.cursor;
|
||||||
|
}
|
22
src/fs/fygue/fygue_file_write.c
Normal file
22
src/fs/fygue/fygue_file_write.c
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#include "fygue.h"
|
||||||
|
|
||||||
|
/* fygue_file_write(): write directory (EISDIR) */
|
||||||
|
ssize_t fygue_file_write(
|
||||||
|
struct fygue_descriptor *desc,
|
||||||
|
void *buffer,
|
||||||
|
size_t size
|
||||||
|
) {
|
||||||
|
ENOTSUP_IF_NOT_FYGUE(-1);
|
||||||
|
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_FILE) {
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (buffer == NULL) {
|
||||||
|
errno = EFAULT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (size == 0)
|
||||||
|
return 0;
|
||||||
|
errno = EROFS;
|
||||||
|
return -1;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue