mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-05-18 23:39:17 +02:00
fs: prepare Fygue integration
This commit is contained in:
parent
968588bac3
commit
b40a6b3fa8
15 changed files with 143 additions and 26 deletions
|
@ -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
|
||||||
|
|
|
@ -11,9 +11,16 @@ int close(int fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
if(d->type->close)
|
if(d->type->close == NULL)
|
||||||
rc = d->type->close(d->data);
|
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);
|
||||||
|
if (fs_descriptor_is_fugue(d))
|
||||||
|
fs_fygue_sync();
|
||||||
|
|
||||||
|
end:
|
||||||
fs_free_descriptor(fd);
|
fs_free_descriptor(fd);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
32
src/fs/fs.c
32
src/fs/fs.c
|
@ -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) {
|
||||||
|
|
|
@ -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
26
src/fs/fygue/fygue.h
Normal 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 */
|
|
@ -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 */
|
||||||
return 0;
|
if(d->type->lseek == NULL)
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
return 0;
|
if(d->type->read == NULL)
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
return size;
|
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue