fs: prepare Fygue integration

This commit is contained in:
Yann MAGNIN 2025-04-01 21:06:55 +02:00
parent 968588bac3
commit b40a6b3fa8
No known key found for this signature in database
GPG key ID: D82629D933EADC59
15 changed files with 143 additions and 26 deletions

View file

@ -9,6 +9,7 @@
extern "C" { extern "C" {
#endif #endif
#include <gint/defs/types.h>
#include <sys/types.h> #include <sys/types.h>
#include <stddef.h> #include <stddef.h>
@ -100,6 +101,19 @@ char *fs_path_normalize(char const *path);
calls to BFile. */ calls to BFile. */
uint16_t *fs_path_normalize_fc(char const *path); uint16_t *fs_path_normalize_fc(char const *path);
/* return True if the provided descriptor is a directory one */
bool fs_descriptor_is_dir(fs_descriptor_t const *data);
/* return True if the provided descriptor is a Fugue one */
bool fs_descriptor_is_fugue(fs_descriptor_t const *data);
/* return True if the provided descriptor is a Fygue one */
bool fs_descriptor_is_fygue(fs_descriptor_t const *data);
/* workaround to keep Fygue filesystem sync */
//TODO: (re?)move me
void fs_fygue_sync(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -11,9 +11,16 @@ int close(int fd)
} }
int rc = 0; int rc = 0;
if(d->type->close) if(d->type->close == NULL)
goto end;
/* Fugue's close primitive can flush pending IO write operation. So, we
* are in the same situation than the write() primitive: force-sync
* Fygue's descriptor to ensure data intergrity */
rc = d->type->close(d->data); rc = d->type->close(d->data);
if (fs_descriptor_is_fugue(d))
fs_fygue_sync();
end:
fs_free_descriptor(fd); fs_free_descriptor(fd);
return rc; return rc;
} }

View file

@ -11,7 +11,7 @@ DIR *fdopendir(int fd)
errno = EBADF; errno = EBADF;
return NULL; return NULL;
} }
if(desc->type != &fugue_dir_descriptor_type) { if(!fs_descriptor_is_dir(desc)) {
errno = ENOTDIR; errno = ENOTDIR;
return NULL; return NULL;
} }

View file

@ -3,6 +3,8 @@
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include "fugue/fugue.h"
#include "fygue/fygue.h"
/* File descriptor table */ /* File descriptor table */
static fs_descriptor_t *fdtable; static fs_descriptor_t *fdtable;
@ -42,6 +44,36 @@ void fs_free_descriptor(int fd)
fdtable[fd].data = NULL; fdtable[fd].data = NULL;
} }
//---
// Utils
//---
bool fs_descriptor_is_fugue(fs_descriptor_t const *desc)
{
return (
(desc->type == &fugue_dir_descriptor_type) ||
(desc->type == &fugue_descriptor_type)
);
}
bool fs_descriptor_is_fygue(fs_descriptor_t const *desc)
{
return (
(desc->type == &fygue_dir_descriptor_type) ||
(desc->type == &fygue_descriptor_type)
);
}
void fs_fygue_sync(void)
{
for (int i = 3 ; i < FS_FD_MAX ; i++) {
if (fdtable[i].type == NULL)
continue;
if (fs_descriptor_is_fygue(fdtable[i].data))
fygue_syncfs(fdtable[i].data);
}
}
int open_generic(fs_descriptor_type_t const *type, void *data, int fd) int open_generic(fs_descriptor_type_t const *type, void *data, int fd)
{ {
if(!fdtable) { if(!fdtable) {

View file

@ -31,7 +31,6 @@ int fugue_mkdir(char const *path, mode_t mode);
int fugue_rmdir(char const *path); int fugue_rmdir(char const *path);
int fugue_stat(char const * restrict path, struct stat * restrict statbuf);
/* Other functions */ /* Other functions */

26
src/fs/fygue/fygue.h Normal file
View file

@ -0,0 +1,26 @@
#ifndef FS_FYGUE_H
#define FS_FYGUE_H 1
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <gint/fs.h>
/* File descriptor type */
extern const fs_descriptor_type_t fygue_descriptor_type;
/* Directory descriptor type */
extern const fs_descriptor_type_t fygue_dir_descriptor_type;
/* Specific implementations of some standard functions */
extern int fygue_open(char const *path, int flags, mode_t mode);
extern int fygue_stat(
char const * restrict path,
struct stat * restrict statbuf
);
extern int fygue_syncfs(void *desc);
#endif /* FS_FYGUE_H */

View file

@ -15,9 +15,13 @@ off_t lseek(int fd, off_t offset, int whence)
return (ssize_t)-1; return (ssize_t)-1;
} }
if(d->type->lseek)
return d->type->lseek(d->data, offset, whence);
/* No seek function: cannot seek */ /* No seek function: cannot seek */
if(d->type->lseek == NULL)
return 0; return 0;
/* BFile_Seek() can flush pending IO write operations. Sync Fygue's
* descriptor to avoid data corruption */
off_t off = d->type->lseek(d->data, offset, whence);
if (fs_descriptor_is_fugue(d))
fs_fygue_sync();
return off;
} }

View file

@ -4,5 +4,7 @@
int mkdir(char const *path, mode_t mode) int mkdir(char const *path, mode_t mode)
{ {
/* Standard mkdir() is the Fugue filesystem only */ /* Standard mkdir() is the Fugue filesystem only */
return fugue_mkdir(path, mode); int rc = fugue_mkdir(path, mode);
fs_fygue_sync();
return rc;
} }

View file

@ -1,6 +1,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <stdarg.h> #include <stdarg.h>
#include "fugue/fugue.h" #include "fugue/fugue.h"
#include "fygue/fygue.h"
int open(char const *path, int flags, ...) int open(char const *path, int flags, ...)
{ {
@ -9,6 +10,22 @@ int open(char const *path, int flags, ...)
mode_t mode = va_arg(args, int); mode_t mode = va_arg(args, int);
va_end(args); va_end(args);
/* Standard open() is the Fugue filesystem only */ /* Standard open() use Fugue filesystem if a write operation
return fugue_open(path, flags, mode); * is requested, otherwise use the Fygue filesystem */
int rc = 0;
if ((flags & O_WRONLY) || (flags & O_RDWR)) {
rc = fugue_open(path, flags, mode);
} else {
rc = fygue_open(path, flags, mode);
}
/* Even with Fygue open primitive, request a sync for all Fygue's
* descriptor because when some flags are set (e.g O_CREATE) Fygue
* invoke BFile_*() syscall that perform IO operation.
*
* Note that Fygue's open() primitive with perform a "lazy" open operation
* by simply ensure that the file exists and mark the file descriptor as
* dirty to force internal data refresh on the next Fygue's IO
* operation */
fs_fygue_sync();
return rc;
} }

View file

@ -10,9 +10,12 @@ ssize_t read(int fd, void *buf, size_t size)
return (ssize_t)-1; return (ssize_t)-1;
} }
if(d->type->read)
return d->type->read(d->data, buf, size);
/* No read function: we can't read anything */ /* No read function: we can't read anything */
if(d->type->read == NULL)
return 0; return 0;
/* BFile_Read() can flush data in some circumstances, force-sync Fygue */
ssize_t rc = d->type->read(d->data, buf, size);
if (fs_descriptor_is_fugue(d))
fs_fygue_sync();
return rc;
} }

View file

@ -1,8 +1,11 @@
#include <stdio.h> #include <stdio.h>
#include <gint/fs.h>
#include "fugue/fugue.h" #include "fugue/fugue.h"
int rename(char const *oldpath, char const *newpath) int rename(char const *oldpath, char const *newpath)
{ {
/* Standard rename() is the Fugue filesystem only */ /* Standard rename() is the Fugue filesystem only */
return fugue_rename(oldpath, newpath); int rc = fugue_rename(oldpath, newpath);
fs_fygue_sync();
return rc;
} }

View file

@ -4,5 +4,7 @@
int rmdir(char const *path) int rmdir(char const *path)
{ {
/* Standard rmdir() is the Fugue filesystem only */ /* Standard rmdir() is the Fugue filesystem only */
return fugue_rmdir(path); int rc = fugue_rmdir(path);
fs_fygue_sync();
return rc;
} }

View file

@ -1,8 +1,10 @@
#include <sys/stat.h> #include <sys/stat.h>
#include "fugue/fugue.h" #include "fygue/fygue.h"
int stat(char const * restrict path, struct stat * restrict statbuf) int stat(char const * restrict path, struct stat * restrict statbuf)
{ {
/* Standard stat() is the Fugue filesystem only */ /* Standard stat() is also provided by Fugue, but rely on Casio's
return fugue_stat(path, statbuf); * syscall which do not provide all of the information and request
* a world-switch (internally) to works */
return fygue_stat(path, statbuf);
} }

View file

@ -1,8 +1,11 @@
#include <unistd.h> #include <unistd.h>
#include <gint/fs.h>
#include "fugue/fugue.h" #include "fugue/fugue.h"
int unlink(char const *path) int unlink(char const *path)
{ {
/* Standard unlink() is the Fugue filesystem only */ /* Standard unlink() is the Fugue filesystem only */
return fugue_unlink(path); int rc = fugue_unlink(path);
fs_fygue_sync();
return rc;
} }

View file

@ -9,10 +9,13 @@ ssize_t write(int fd, const void *buf, size_t size)
errno = EBADF; errno = EBADF;
return (ssize_t)-1; return (ssize_t)-1;
} }
if(d->type->write)
return d->type->write(d->data, buf, size);
/* No write function: discard the contents but show no error */ /* No write function: discard the contents but show no error */
if(d->type->write == NULL)
return 0;
/* A special synchronisation must be performed to ensure that all
* Fygue's descriptor meta information are valid */
size = d->type->write(d->data, buf, size);
if (fs_descriptor_is_fugue(d))
fs_fygue_sync();
return size; return size;
} }