Clean SMEMFS primitives

This commit is contained in:
Yann MAGNIN 2020-01-07 10:12:45 +01:00
parent d83175f1dd
commit 215925ed35
8 changed files with 78 additions and 65 deletions

View File

@ -16,16 +16,15 @@
#define CASIO_SMEM_FRAGMENT_INFO_EXIST CASIO_SMEM_HEADER_INFO_EXIST
#define CASIO_SMEM_FRAGMENT_INFO_DELETE CASIO_SMEM_HEADER_INFO_DELETE
#define CASIO_SMEM_FRAGMENT_MAGIC 0x0120
#define CASIO_SMEM_ROOT_ID 0xffff
#define CASIO_SMEM_ROOT_ID 0xffff
//
typedef struct casio_smem_block_s
// Define block data.
struct casio_smem_block_s
{
uint16_t magic_start; // always 0x4200
uint16_t entry_number; // indicate the block number
uint32_t offset; // offset in the memory (?)
uint32_t offset; // offset in the memory (sector ?)
struct {
uint8_t used; // Indicate if the block is used (0xff yes, 0x00 no)
@ -34,10 +33,10 @@ typedef struct casio_smem_block_s
} info;
uint8_t magic_end[20]; // Content always 0xff 0xff 0xff 0xff 0x00 0x00 0x00 0x01 0xff 0xff...
} casio_smem_block_t;
};
// Define file header.
typedef struct casio_smem_header_s
struct casio_smem_header_s
{
uint8_t info; // 0x51 if entry exist, 0x01 if entry refer to delete file. (?)
uint8_t type; // 0x10 for a directory, 0x20 for preheader.
@ -49,10 +48,10 @@ typedef struct casio_smem_header_s
} parent;
uint16_t name[12]; // File name
} casio_smem_header_t;
};
// Define frament data.
typedef struct casio_smem_fragment_s
struct casio_smem_fragment_s
{
uint8_t info; // 0x51 if entry exit, 0x01 if entry refer to delete file.
uint8_t unknown0; // always 0x30
@ -70,33 +69,43 @@ typedef struct casio_smem_fragment_s
uint16_t data_size; // size of this fragment data
uint8_t fill[12]; // 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ...
} casio_smem_fragment_t;
};
// Define internal typedef
typedef struct casio_smem_block_s smemfs_sector_t;
typedef struct casio_smem_header_s smemfs_inode_t;
typedef struct casio_smem_fragment_s smemfs_fragdata_t;
// Internal superblock
// Define internal superblock
struct smemfs_superblock_s
{
casio_smem_header_t *inode_table;
casio_smem_block_t *sector_table;
smemfs_inode_t *inode_table;
smemfs_sector_t *sector_table;
};
// Constructor
extern void smemfs_initialize();
// Superblock primitives
extern void *smemfs_mount(void);
extern int smemfs_umount(void);
// File primitives
extern ssize_t smemfs_read(void *inode, void *buf, size_t count, off_t pos);
// Inode primitive
extern void *smemfs_find_first_inode(casio_smem_header_t *inode, uint16_t parent_id);
extern void *smemfs_find_next_sibling(void *inode);
extern void *smemfs_find_first_child(void *inode);
extern void *smemfs_find_parent(void *inode);
extern int smemfs_get_name(void *inode, char *name, size_t count);
extern mode_t smemfs_get_mode(void *inode);
// Internal helper !
#define WALK_FLAG_ID_CHECK_PARENT (1 << 0)
#define WALK_FLAG_ID_CHECK_DIRECTORY (0 << 0)
extern smemfs_inode_t *smemfs_walk(smemfs_inode_t *current,
smemfs_inode_t *entry, uint16_t folder_id, int flags);
#endif /*_CASIO_SMEM_H__*/

View File

@ -3,10 +3,10 @@
#include <kernel/util.h>
/* casio_smem_data_base_address() - Generate the fragmented data address (0xa0000000 + offset) */
static void *casio_smem_get_data_base_address(casio_smem_fragment_t *fragment)
static void *casio_smem_get_data_base_address(smemfs_fragdata_t *fragment)
{
extern struct smemfs_superblock_s smemfs_superblock;
casio_smem_block_t *block;
struct casio_smem_block_s *block;
block = smemfs_superblock.sector_table;
while (block->magic_start == CASIO_SMEM_BLOCK_ENTRY_MAGIC &&
@ -22,7 +22,7 @@ static void *casio_smem_get_data_base_address(casio_smem_fragment_t *fragment)
/* casio_smem_read() - Read the file data (based on internal cursor) */
ssize_t smemfs_read(void *inode, void *buf, size_t count, off_t pos)
{
casio_smem_fragment_t *fragment;
smemfs_fragdata_t *fragment;
off_t fragment_data_offset;
void *data_base_addr;
ssize_t current_size;
@ -34,7 +34,7 @@ ssize_t smemfs_read(void *inode, void *buf, size_t count, off_t pos)
// Get the current data fragment.
current_size = 0;
fragment = (void *)((uint32_t)inode + sizeof(casio_smem_header_t));
fragment = (void *)((uint32_t)inode + sizeof(struct casio_smem_header_s));
while (fragment->magic == CASIO_SMEM_FRAGMENT_MAGIC &&
pos > (off_t)(current_size + fragment->data_size + 1))
{

View File

@ -1,14 +1,11 @@
#include <kernel/fs/smemfs.h>
#include <kernel/util.h>
// Internal function
extern casio_smem_header_t *smemfs_walk(casio_smem_header_t *current_inode,
uint16_t parent_id, int skip);
/* smemfs_find_first_child() - Find the fist file in the (folder) inode */
void *smemfs_find_first_child(void *inode)
{
extern struct smemfs_superblock_s smemfs_superblock;
uint16_t parent_id;
uint16_t folder_id;
// Check error.
if (inode == NULL)
@ -17,16 +14,21 @@ void *smemfs_find_first_child(void *inode)
// Check root inode
if (inode == smemfs_superblock.sector_table)
{
parent_id = CASIO_SMEM_ROOT_ID;
folder_id = CASIO_SMEM_ROOT_ID;
} else {
// Check inode validity
if (((struct casio_smem_header_s *)inode)->info != CASIO_SMEM_HEADER_INFO_EXIST)
return (NULL);
// Check directory
if (((struct casio_smem_header_s *)inode)->type != CASIO_SMEM_HEADER_TYPE_DIRECTORY)
return (NULL);
// Get directory ID
parent_id = ((struct casio_smem_header_s *)inode)->id;
folder_id = ((struct casio_smem_header_s *)inode)->id;
}
// Return the first child of the file.
return (smemfs_walk(smemfs_superblock.inode_table, parent_id, 0));
return (smemfs_walk(inode, smemfs_superblock.inode_table,
folder_id, WALK_FLAG_ID_CHECK_PARENT));
}

View File

@ -1,14 +1,10 @@
#include <kernel/fs/smemfs.h>
#include <kernel/util.h>
// Internal function
extern casio_smem_header_t *smemfs_walk(casio_smem_header_t *current_inode,
uint16_t parent_id, int skip);
void *smemfs_find_next_sibling(void *inode)
{
extern struct smemfs_superblock_s smemfs_superblock;
uint16_t parent_id;
uint16_t folder_id;
// Check error.
if (inode == NULL)
@ -18,9 +14,13 @@ void *smemfs_find_next_sibling(void *inode)
if (inode == smemfs_superblock.sector_table)
return (NULL);
// Check inode validity
if (((struct casio_smem_header_s *)inode)->info != CASIO_SMEM_HEADER_INFO_EXIST)
return (NULL);
// Get parent ID.
parent_id = ((struct casio_smem_header_s *)inode)->parent.id;
folder_id = ((struct casio_smem_header_s *)inode)->parent.id;
// Return the next file of the directory.
return (smemfs_walk(inode, parent_id, 0x01));
return (smemfs_walk(inode, inode, folder_id, WALK_FLAG_ID_CHECK_PARENT));
}

View File

@ -1,21 +1,27 @@
#include <kernel/fs/smemfs.h>
// Internal function
extern casio_smem_header_t *smemfs_walk(casio_smem_header_t *current_inode,
uint16_t parent_id, int skip);
/* smemfs_find_parent() - Return the parent inode */
void *smemfs_find_parent(void *inode)
{
extern struct smemfs_superblock_s smemfs_superblock;
uint16_t parent_id;
uint16_t folder_id;
// Check error.
if (inode == NULL)
return (NULL);
// Check root inode
if (inode == smemfs_superblock.sector_table)
return (NULL);
// Check inode validity
if (((struct casio_smem_header_s *)inode)->info != CASIO_SMEM_HEADER_INFO_EXIST)
return (NULL);
// Get parent ID.
parent_id = ((struct casio_smem_header_s *)inode)->parent.id;
folder_id = ((struct casio_smem_header_s *)inode)->parent.id;
// Return first inode find
return (smemfs_walk(smemfs_superblock.inode_table, parent_id, 0x01 | 0x02));
return (smemfs_walk(inode, smemfs_superblock.inode_table, folder_id,
WALK_FLAG_ID_CHECK_DIRECTORY));
}

View File

@ -4,7 +4,7 @@
mode_t smemfs_get_mode(void *inode)
{
extern struct smemfs_superblock_s smemfs_superblock;
casio_smem_header_t *header;
struct casio_smem_header_s *header;
int inode_type;
// Check error

View File

@ -3,7 +3,7 @@
int smemfs_get_name(void *inode, char *buf, size_t count)
{
extern struct smemfs_superblock_s smemfs_superblock;
casio_smem_header_t *header;
struct casio_smem_header_s *header;
// Check error
if (inode == NULL)

View File

@ -1,42 +1,38 @@
#include <kernel/fs/smemfs.h>
#include <kernel/util.h>
casio_smem_header_t *smemfs_walk(casio_smem_header_t *current_inode, uint16_t parent_id, int skip)
/* smemfs_walk() - Find inode based on directory ID and flags */
smemfs_inode_t *smemfs_walk(smemfs_inode_t *current,
smemfs_inode_t *entry, uint16_t folder_id, int flags)
{
struct casio_smem_fragment_s *current_fragment;
smemfs_fragdata_t *fragdata;
// Check current inode validity.
if (current_inode == NULL)
if (entry == NULL)
return (NULL);
// Walk entry
while (current_inode->info == CASIO_SMEM_HEADER_INFO_EXIST ||
current_inode->info == CASIO_SMEM_HEADER_INFO_DELETE)
while (entry->info == CASIO_SMEM_HEADER_INFO_EXIST ||
entry->info == CASIO_SMEM_HEADER_INFO_DELETE)
{
// New inode validity check.
if (current_inode->info == CASIO_SMEM_HEADER_INFO_EXIST &&
((skip & 0x01) == 0) &&
(((skip & 0x02) == 0 && current_inode->parent.id == parent_id) ||
((skip & 0x02) != 0 && current_inode->id == parent_id)))
if (entry != current &&
entry->info == CASIO_SMEM_HEADER_INFO_EXIST &&
(((flags & WALK_FLAG_ID_CHECK_PARENT) != 0 && entry->parent.id == folder_id) ||
((flags & WALK_FLAG_ID_CHECK_PARENT) == 0 && entry->id == folder_id)))
{
return (current_inode);
return (entry);
}
// Fast fragmentation skip
current_fragment = (void *)((uint32_t)(current_inode) + sizeof(struct casio_smem_header_s));
if (current_fragment->magic == CASIO_SMEM_FRAGMENT_MAGIC)
fragdata = (void *)((uint32_t)(entry) + sizeof(struct casio_smem_header_s));
if (fragdata->magic == CASIO_SMEM_FRAGMENT_MAGIC)
{
current_fragment = (void *)((uint32_t)current_fragment +
sizeof(struct casio_smem_fragment_s) *
current_fragment->frag_total);
fragdata = (void *)((uint32_t)fragdata +
(sizeof(struct casio_smem_fragment_s) * fragdata->frag_total));
}
// Update current inode
current_inode = (void*)current_fragment;
// Workaround update
skip = skip & ~0x01;
entry = (void*)fragdata;
}
return (NULL);
}