From 215925ed355f6a09fd7727df28c87171d03f9bdd Mon Sep 17 00:00:00 2001 From: Yann MAGNIN Date: Tue, 7 Jan 2020 10:12:45 +0100 Subject: [PATCH] Clean SMEMFS primitives --- include/kernel/fs/smemfs.h | 41 +++++++++++-------- src/kernel/fs/smemfs/file/read.c | 8 ++-- src/kernel/fs/smemfs/inode/find_first_child.c | 18 ++++---- .../fs/smemfs/inode/find_next_sibling.c | 14 +++---- src/kernel/fs/smemfs/inode/find_parent.c | 20 +++++---- src/kernel/fs/smemfs/inode/get_mode.c | 2 +- src/kernel/fs/smemfs/inode/get_name.c | 2 +- src/kernel/fs/smemfs/inode/walk.c | 38 ++++++++--------- 8 files changed, 78 insertions(+), 65 deletions(-) diff --git a/include/kernel/fs/smemfs.h b/include/kernel/fs/smemfs.h index 0c12185..2e59a1a 100644 --- a/include/kernel/fs/smemfs.h +++ b/include/kernel/fs/smemfs.h @@ -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__*/ diff --git a/src/kernel/fs/smemfs/file/read.c b/src/kernel/fs/smemfs/file/read.c index 3907e82..80589ce 100644 --- a/src/kernel/fs/smemfs/file/read.c +++ b/src/kernel/fs/smemfs/file/read.c @@ -3,10 +3,10 @@ #include /* 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)) { diff --git a/src/kernel/fs/smemfs/inode/find_first_child.c b/src/kernel/fs/smemfs/inode/find_first_child.c index 65a2fa8..7f47ddb 100644 --- a/src/kernel/fs/smemfs/inode/find_first_child.c +++ b/src/kernel/fs/smemfs/inode/find_first_child.c @@ -1,14 +1,11 @@ #include #include -// 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)); } diff --git a/src/kernel/fs/smemfs/inode/find_next_sibling.c b/src/kernel/fs/smemfs/inode/find_next_sibling.c index 6f44dad..b77f4fd 100644 --- a/src/kernel/fs/smemfs/inode/find_next_sibling.c +++ b/src/kernel/fs/smemfs/inode/find_next_sibling.c @@ -1,14 +1,10 @@ #include #include -// 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)); } diff --git a/src/kernel/fs/smemfs/inode/find_parent.c b/src/kernel/fs/smemfs/inode/find_parent.c index 04a101b..1199a7d 100644 --- a/src/kernel/fs/smemfs/inode/find_parent.c +++ b/src/kernel/fs/smemfs/inode/find_parent.c @@ -1,21 +1,27 @@ #include -// 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)); } diff --git a/src/kernel/fs/smemfs/inode/get_mode.c b/src/kernel/fs/smemfs/inode/get_mode.c index 2364870..2a2fad5 100644 --- a/src/kernel/fs/smemfs/inode/get_mode.c +++ b/src/kernel/fs/smemfs/inode/get_mode.c @@ -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 diff --git a/src/kernel/fs/smemfs/inode/get_name.c b/src/kernel/fs/smemfs/inode/get_name.c index 95514dc..c751714 100644 --- a/src/kernel/fs/smemfs/inode/get_name.c +++ b/src/kernel/fs/smemfs/inode/get_name.c @@ -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) diff --git a/src/kernel/fs/smemfs/inode/walk.c b/src/kernel/fs/smemfs/inode/walk.c index d6bd34f..155d5a5 100644 --- a/src/kernel/fs/smemfs/inode/walk.c +++ b/src/kernel/fs/smemfs/inode/walk.c @@ -1,42 +1,38 @@ #include -#include -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); }