mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-05-18 15:29:16 +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" {
|
||||
#endif
|
||||
|
||||
#include <gint/defs/types.h>
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
@ -100,6 +101,19 @@ char *fs_path_normalize(char const *path);
|
|||
calls to BFile. */
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -11,9 +11,16 @@ int close(int fd)
|
|||
}
|
||||
|
||||
int rc = 0;
|
||||
if(d->type->close)
|
||||
rc = d->type->close(d->data);
|
||||
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);
|
||||
if (fs_descriptor_is_fugue(d))
|
||||
fs_fygue_sync();
|
||||
|
||||
end:
|
||||
fs_free_descriptor(fd);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ DIR *fdopendir(int fd)
|
|||
errno = EBADF;
|
||||
return NULL;
|
||||
}
|
||||
if(desc->type != &fugue_dir_descriptor_type) {
|
||||
if(!fs_descriptor_is_dir(desc)) {
|
||||
errno = ENOTDIR;
|
||||
return NULL;
|
||||
}
|
||||
|
|
32
src/fs/fs.c
32
src/fs/fs.c
|
@ -3,6 +3,8 @@
|
|||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include "fugue/fugue.h"
|
||||
#include "fygue/fygue.h"
|
||||
|
||||
/* File descriptor table */
|
||||
static fs_descriptor_t *fdtable;
|
||||
|
@ -42,6 +44,36 @@ void fs_free_descriptor(int fd)
|
|||
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)
|
||||
{
|
||||
if(!fdtable) {
|
||||
|
|
|
@ -31,7 +31,6 @@ int fugue_mkdir(char const *path, mode_t mode);
|
|||
|
||||
int fugue_rmdir(char const *path);
|
||||
|
||||
int fugue_stat(char const * restrict path, struct stat * restrict statbuf);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
if(d->type->lseek)
|
||||
return d->type->lseek(d->data, offset, whence);
|
||||
|
||||
/* 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)
|
||||
{
|
||||
/* 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 <stdarg.h>
|
||||
#include "fugue/fugue.h"
|
||||
#include "fygue/fygue.h"
|
||||
|
||||
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);
|
||||
va_end(args);
|
||||
|
||||
/* Standard open() is the Fugue filesystem only */
|
||||
return fugue_open(path, flags, mode);
|
||||
/* Standard open() use Fugue filesystem if a write operation
|
||||
* 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;
|
||||
}
|
||||
|
||||
if(d->type->read)
|
||||
return d->type->read(d->data, buf, size);
|
||||
|
||||
/* 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 <gint/fs.h>
|
||||
#include "fugue/fugue.h"
|
||||
|
||||
int rename(char const *oldpath, char const *newpath)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
/* 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 "fugue/fugue.h"
|
||||
#include "fygue/fygue.h"
|
||||
|
||||
int stat(char const * restrict path, struct stat * restrict statbuf)
|
||||
{
|
||||
/* Standard stat() is the Fugue filesystem only */
|
||||
return fugue_stat(path, statbuf);
|
||||
/* Standard stat() is also provided by Fugue, but rely on Casio's
|
||||
* 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 <gint/fs.h>
|
||||
#include "fugue/fugue.h"
|
||||
|
||||
int unlink(char const *path)
|
||||
{
|
||||
/* 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;
|
||||
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 */
|
||||
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