ref: 3593b8d13c920daf69284391d7bd25c5da937884
parent: 2aa20fe51f1eb5f4334e142cdf099878e3a8e83c
author: gkostka <kostka.grzegorz@gmail.com>
date: Wed Jan 15 16:31:12 EST 2014
Documentation.
--- a/lwext4/ext4_balloc.c
+++ b/lwext4/ext4_balloc.c
@@ -48,7 +48,11 @@
#include <ext4_inode.h>
-
+/**@brief Compute number of block group from block address.
+ * @param sb Superblock pointer.
+ * @param baddr Absolute address of block.
+ * @return Block group index
+ */
static uint32_t ext4_balloc_get_bgid_of_block(struct ext4_sblock *s,
uint32_t baddr)
{
@@ -235,6 +239,11 @@
return EOK;
}
+
+/**@brief Compute 'goal' for allocation algorithm.
+ * @param inode_ref Reference to inode, to allocate block for
+ * @return Goal block number
+ */
static uint32_t ext4_balloc_find_goal(struct ext4_inode_ref *inode_ref)
{
uint32_t goal = 0;
--- a/lwext4/ext4_block_group.c
+++ b/lwext4/ext4_block_group.c
@@ -42,7 +42,7 @@
#include <ext4_config.h>
#include <ext4_block_group.h>
-
+/**@brief CRC-16 look up table*/
static uint16_t const crc16_tab[256] = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
--- a/lwext4/ext4_block_group.h
+++ b/lwext4/ext4_block_group.h
@@ -50,7 +50,11 @@
#include <stdint.h>
#include <stdbool.h>
-/**@brief TODO: ...*/
+/**@brief Get address of block with data block bitmap.
+ * @param bg pointer to block group
+ * @param s pointer to superblock
+ * @return Address of block with block bitmap
+ */
static inline uint64_t ext4_bg_get_block_bitmap(struct ext4_bgroup *bg,
struct ext4_sblock *s)
{
@@ -62,7 +66,11 @@
return v;
}
-/**@brief TODO: ...*/
+/**@brief Get address of block with i-node bitmap.
+ * @param bg Pointer to block group
+ * @param s Pointer to superblock
+ * @return Address of block with i-node bitmap
+ */
static inline uint64_t ext4_bg_get_inode_bitmap(struct ext4_bgroup *bg,
struct ext4_sblock *s)
{
@@ -75,7 +83,11 @@
return v;
}
-/**@brief TODO: ...*/
+/**@brief Get address of the first block of the i-node table.
+ * @param bg Pointer to block group
+ * @param s Pointer to superblock
+ * @return Address of first block of i-node table
+ */
static inline uint64_t ext4_bg_get_inode_table_first_block(
struct ext4_bgroup *bg, struct ext4_sblock *s)
{
@@ -87,7 +99,11 @@
return v;
}
-/**@brief TODO: ...*/
+/**@brief Get number of free blocks in block group.
+ * @param bg Pointer to block group
+ * @param sb Pointer to superblock
+ * @return Number of free blocks in block group
+ */
static inline uint32_t ext4_bg_get_free_blocks_count(struct ext4_bgroup *bg,
struct ext4_sblock *s)
{
@@ -99,7 +115,11 @@
return v;
}
-/**@brief TODO: ...*/
+/**@brief Set number of free blocks in block group.
+ * @param bg Pointer to block group
+ * @param s Pointer to superblock
+ * @param cnt Number of free blocks in block group
+ */
static inline void ext4_bg_set_free_blocks_count(struct ext4_bgroup *bg,
struct ext4_sblock *s, uint32_t cnt)
{
@@ -108,7 +128,11 @@
bg->free_blocks_count_hi = to_le16(cnt >> 16);
}
-/**@brief TODO: ...*/
+/**@brief Get number of free i-nodes in block group.
+ * @param bg Pointer to block group
+ * @param s Pointer to superblock
+ * @return Number of free i-nodes in block group
+ */
static inline uint32_t ext4_bg_get_free_inodes_count(struct ext4_bgroup *bg,
struct ext4_sblock *s)
{
@@ -120,7 +144,11 @@
return v;
}
-/**@brief TODO: ...*/
+/**@brief Set number of free i-nodes in block group.
+ * @param bg Pointer to block group
+ * @param s Pointer to superblock
+ * @param cnt Number of free i-nodes in block group
+ */
static inline void ext4_bg_set_free_inodes_count(struct ext4_bgroup *bg,
struct ext4_sblock *s, uint32_t cnt)
{
@@ -129,7 +157,11 @@
bg->free_inodes_count_hi = to_le16(cnt >> 16);
}
-/**@brief TODO: ...*/
+/**@brief Get number of used directories in block group.
+ * @param bg Pointer to block group
+ * @param s Pointer to superblock
+ * @return Number of used directories in block group
+ */
static inline uint32_t ext4_bg_get_used_dirs_count(struct ext4_bgroup *bg,
struct ext4_sblock *s)
{
@@ -141,7 +173,11 @@
return v;
}
-/**@brief TODO: ...*/
+/**@brief Set number of used directories in block group.
+ * @param bg Pointer to block group
+ * @param s Pointer to superblock
+ * @param cnt Number of used directories in block group
+ */
static inline void ext4_bg_set_used_dirs_count(struct ext4_bgroup *bg,
struct ext4_sblock *s, uint32_t cnt)
{
@@ -150,7 +186,11 @@
bg->used_dirs_count_hi = to_le16(cnt >> 16);
}
-/**@brief TODO: ...*/
+/**@brief Get number of unused i-nodes.
+ * @param bg Pointer to block group
+ * @param s Pointer to superblock
+ * @return Number of unused i-nodes
+ */
static inline uint32_t ext4_bg_get_itable_unused(struct ext4_bgroup *bg,
struct ext4_sblock *s)
{
@@ -163,7 +203,11 @@
return v;
}
-/**@brief TODO: ...*/
+/**@brief Set number of unused i-nodes.
+ * @param bg Pointer to block group
+ * @param s Pointer to superblock
+ * @param cnt Number of unused i-nodes
+ */
static inline void ext4_bg_set_itable_unused(struct ext4_bgroup *bg,
struct ext4_sblock *s, uint32_t cnt)
{
@@ -172,7 +216,10 @@
bg->itable_unused_hi = to_le16(cnt >> 16);
}
-/**@brief TODO: ...*/
+/**@brief Set checksum of block group.
+ * @param bg Pointer to block group
+ * @param crc Cheksum of block group
+ */
static inline void ext4_bg_set_checksum(struct ext4_bgroup *bg,
uint16_t crc)
{
@@ -179,13 +226,20 @@
bg->checksum = to_le16(crc);
}
-/**@brief TODO: ...*/
+/**@brief Check if block group has a flag.
+ * @param bg Pointer to block group
+ * @param flag Flag to be checked
+ * @return True if flag is set to 1
+ */
static inline bool ext4_bg_has_flag(struct ext4_bgroup *bg, uint32_t f)
{
return to_le16(bg->flags) & f;
}
-/**@brief TODO: ...*/
+/**@brief Set flag of block group.
+ * @param bg Pointer to block group
+ * @param flag Flag to be set
+ */
static inline void ext4_bg_set_flag(struct ext4_bgroup *bg, uint32_t f)
{
uint16_t flags = to_le16(bg->flags);
@@ -193,7 +247,10 @@
bg->flags = to_le16(flags);
}
-/**@brief TODO: ...*/
+/**@brief Clear flag of block group.
+ * @param bg Pointer to block group
+ * @param flag Flag to be cleared
+ */
static inline void ext4_bg_clear_flag(struct ext4_bgroup *bg, uint32_t f)
{
uint16_t flags = to_le16(bg->flags);
@@ -201,7 +258,11 @@
bg->flags = to_le16(flags);
}
-/**@brief TODO: ...*/
+/**@brief Calculate CRC16 of the block group.
+ * @param crc Init value
+ * @param buffer Input buffer
+ * @param len Sizeof input buffer
+ * @return Computed CRC16*/
uint16_t ext4_bg_crc16(uint16_t crc, const uint8_t *buffer, size_t len);
#endif /* EXT4_BLOCK_GROUP_H_ */
--- a/lwext4/ext4_dir.c
+++ b/lwext4/ext4_dir.c
@@ -115,7 +115,11 @@
/****************************************************************************/
-
+/**@brief Do some checks before returning iterator.
+ * @param it Iterator to be checked
+ * @param block_size Size of data block
+ * @return Error code
+ */
static int ext4_dir_iterator_set(struct ext4_directory_iterator *it,
uint32_t block_size)
{
@@ -149,6 +153,12 @@
return EOK;
}
+/**@brief Seek to next valid directory entry.
+ * Here can be jumped to the next data block.
+ * @param it Initialized iterator
+ * @param pos Position of the next entry
+ * @return Error code
+ */
static int ext4_dir_iterator_seek(struct ext4_directory_iterator *it,
uint64_t pos)
{
--- a/lwext4/ext4_dir.h
+++ b/lwext4/ext4_dir.h
@@ -49,74 +49,157 @@
#include <stdint.h>
-/**@brief TODO: ...*/
+/**@brief Get i-node number from directory entry.
+ * @param de Directory entry
+ * @return I-node number
+ */
uint32_t ext4_dir_entry_ll_get_inode(struct ext4_directory_entry_ll *de);
-/**@brief TODO: ...*/
+/**@brief Set i-node number to directory entry.
+ * @param de Directory entry
+ * @param inode I-node number
+ */
void ext4_dir_entry_ll_set_inode(struct ext4_directory_entry_ll *de,
uint32_t inode);
-/**@brief TODO: ...*/
+/**@brief Get directory entry length.
+ * @param de Directory entry
+ * @return Entry length
+ */
uint16_t ext4_dir_entry_ll_get_entry_length(struct ext4_directory_entry_ll *de);
-/**@brief TODO: ...*/
+/**@brief Set directory entry length.
+ * @param de Directory entry
+ * @param length Entry length
+ */
void ext4_dir_entry_ll_set_entry_length(struct ext4_directory_entry_ll *de,
uint16_t len);
-/**@brief TODO: ...*/
+/**@brief Get directory entry name length.
+ * @param sb Superblock
+ * @param de Directory entry
+ * @return Entry name length
+ */
uint16_t ext4_dir_entry_ll_get_name_length(struct ext4_sblock *sb,
struct ext4_directory_entry_ll *de);
-/**@brief TODO: ...*/
+/**@brief Set directory entry name length.
+ * @param sb Superblock
+ * @param de Directory entry
+ * @param length Entry name length
+ */
void ext4_dir_entry_ll_set_name_length(struct ext4_sblock *sb,
struct ext4_directory_entry_ll *de, uint16_t len);
-/**@brief TODO: ...*/
+/**@brief Get i-node type of directory entry.
+ * @param sb Superblock
+ * @param de Directory entry
+ * @return I-node type (file, dir, etc.)
+ */
uint8_t ext4_dir_entry_ll_get_inode_type(struct ext4_sblock *sb,
struct ext4_directory_entry_ll *de);
-/**@brief TODO: ...*/
+/**@brief Set i-node type of directory entry.
+ * @param sb Superblock
+ * @param de Directory entry
+ * @param type I-node type (file, dir, etc.)
+ */
void ext4_dir_entry_ll_set_inode_type(struct ext4_sblock *sb,
struct ext4_directory_entry_ll *de, uint8_t type);
-/**@brief TODO: ...*/
+/**@brief Initialize directory iterator.
+ * Set position to the first valid entry from the required position.
+ * @param it Pointer to iterator to be initialized
+ * @param inode_ref Directory i-node
+ * @param pos Position to start reading entries from
+ * @return Error code
+ */
int ext4_dir_iterator_init(struct ext4_directory_iterator *it,
struct ext4_inode_ref *inode_ref, uint64_t pos);
-/**@brief TODO: ...*/
+/**@brief Jump to the next valid entry
+ * @param it Initialized iterator
+ * @return Error code
+ */
int ext4_dir_iterator_next(struct ext4_directory_iterator *it);
-/**@brief TODO: ...*/
+/**@brief Uninitialize directory iterator.
+ * Release all allocated structures.
+ * @param it Iterator to be finished
+ * @return Error code
+ */
int ext4_dir_iterator_fini(struct ext4_directory_iterator *it);
-/**@brief TODO: ...*/
+/**@brief Write directory entry to concrete data block.
+ * @param sb Superblock
+ * @param entry Pointer to entry to be written
+ * @param entry_len Length of new entry
+ * @param child Child i-node to be written to new entry
+ * @param name Name of the new entry
+ * @param name_len Length of entry name
+ */
void ext4_dir_write_entry(struct ext4_sblock *sb,
struct ext4_directory_entry_ll *entry, uint16_t entry_len,
struct ext4_inode_ref *child, const char *name, size_t name_len);
-/**@brief TODO: ...*/
+/**@brief Add new entry to the directory.
+ * @param parent Directory i-node
+ * @param name Name of new entry
+ * @param child I-node to be referenced from new entry
+ * @return Error code
+ */
int ext4_dir_add_entry(struct ext4_inode_ref *parent, const char *name,
uint32_t name_len, struct ext4_inode_ref *child);
-/**@brief TODO: ...*/
+/**@brief Find directory entry with passed name.
+ * @param result Result structure to be returned if entry found
+ * @param parent Directory i-node
+ * @param name Name of entry to be found
+ * @param name_len Name length
+ * @return Error code
+ */
int ext4_dir_find_entry(struct ext4_directory_search_result *result,
struct ext4_inode_ref *parent, const char *name, uint32_t name_len);
-/**@brief TODO: ...*/
+/**@brief Remove directory entry.
+ * @param parent Directory i-node
+ * @param name Name of the entry to be removed
+ * @param name_len Name length
+ * @return Error code
+ */
int ext4_dir_remove_entry(struct ext4_inode_ref *parent, const char *name,
uint32_t name_len);
-/**@brief TODO: ...*/
+/**@brief Try to insert entry to concrete data block.
+ * @param sb Superblock
+ * @param target_block Block to try to insert entry to
+ * @param child Child i-node to be inserted by new entry
+ * @param name Name of the new entry
+ * @param name_len Length of the new entry name
+ * @return Error code
+ */
int ext4_dir_try_insert_entry(struct ext4_sblock *sb,
struct ext4_block *target_block, struct ext4_inode_ref *child,
const char *name, uint32_t name_len);
-/**@brief TODO: ...*/
+/**@brief Try to find entry in block by name.
+ * @param block Block containing entries
+ * @param sb Superblock
+ * @param name_len Length of entry name
+ * @param name Name of entry to be found
+ * @param res_entry Output pointer to found entry, NULL if not found
+ * @return Error code
+ */
int ext4_dir_find_in_block(struct ext4_block *block, struct ext4_sblock *sb,
size_t name_len, const char *name,
struct ext4_directory_entry_ll **res_entry);
-/**@brief TODO: ...*/
+/**@brief Simple function to release allocated data from result.
+ * @param parent Parent inode
+ * @param result Search result to destroy
+ * @return Error code
+ *
+ */
int ext4_dir_destroy_result(struct ext4_inode_ref *parent,
struct ext4_directory_search_result *result);
--- a/lwext4/ext4_dir_idx.c
+++ b/lwext4/ext4_dir_idx.c
@@ -45,6 +45,7 @@
#include <string.h>
#include <stdlib.h>
+/**@brief Sort entry item.*/
struct ext4_dx_sort_entry {
uint32_t hash;
uint32_t rec_len;
@@ -51,6 +52,7 @@
void *dentry;
};
+
static int ext4_dir_dx_hash_string(struct ext4_hash_info *hinfo, int len,
const char *name)
{
@@ -221,6 +223,14 @@
return ext4_block_set(dir->fs->bdev, &block);
}
+/**@brief Initialize hash info structure necessary for index operations.
+ * @param hinfo Pointer to hinfo to be initialized
+ * @param root_block Root block (number 0) of index
+ * @param sb Pointer to superblock
+ * @param name_len Length of name to be computed hash value from
+ * @param name Name to be computed hash value from
+ * @return Standard error code
+ */
static int ext4_dir_hinfo_init(struct ext4_hash_info *hinfo,
struct ext4_block *root_block, struct ext4_sblock *sb, size_t name_len,
const char *name)
@@ -273,7 +283,14 @@
return EOK;
}
-
+/**@brief Walk through index tree and load leaf with corresponding hash value.
+ * @param hinfo Initialized hash info structure
+ * @param inode_ref Current i-node
+ * @param root_block Root block (iblock 0), where is root node located
+ * @param dx_block Pointer to leaf node in dx_blocks array
+ * @param dx_blocks Array with the whole path from root to leaf
+ * @return Standard error code
+ */
static int ext4_dir_dx_get_leaf(struct ext4_hash_info *hinfo,
struct ext4_inode_ref *inode_ref, struct ext4_block *root_block,
struct ext4_directory_dx_block **dx_block,
@@ -366,6 +383,13 @@
return EOK;
}
+/**@brief Check if the the next block would be checked during entry search.
+ * @param inode_ref Directory i-node
+ * @param hash Hash value to check
+ * @param dx_block Current block
+ * @param dx_blocks Array with path from root to leaf node
+ * @return Standard Error codee
+ */
static int ext4_dir_dx_next_block(struct ext4_inode_ref *inode_ref,
uint32_t hash, struct ext4_directory_dx_block *dx_block,
struct ext4_directory_dx_block *dx_blocks)
@@ -527,6 +551,16 @@
return rc;
}
+
+/**@brief Compare function used to pass in quicksort implementation.
+ * It can compare two entries by hash value.
+ * @param arg1 First entry
+ * @param arg2 Second entry
+ * @param dummy Unused parameter, can be NULL
+ *
+ * @return Classic compare result
+ * (0: equal, -1: arg1 < arg2, 1: arg1 > arg2)
+ */
static int ext4_dir_dx_entry_comparator(const void *arg1, const void *arg2)
{
struct ext4_dx_sort_entry *entry1 = (void *)arg1;
@@ -541,6 +575,14 @@
return 1;
}
+
+/**@brief Insert new index entry to block.
+ * Note that space for new entry must be checked by caller.
+ * @param index_block Block where to insert new entry
+ * @param hash Hash value covered by child node
+ * @param iblock Logical number of child block
+ *
+ */
static void ext4_dir_dx_insert_entry(
struct ext4_directory_dx_block *index_block, uint32_t hash,
uint32_t iblock)
@@ -565,6 +607,13 @@
index_block->block.dirty = true;
}
+/**@brief Split directory entries to two parts preventing node overflow.
+ * @param inode_ref Directory i-node
+ * @param hinfo Hash info
+ * @param old_data_block Block with data to be split
+ * @param index_block Block where index entries are located
+ * @param new_data_block Output value for newly allocated data block
+ */
static int ext4_dir_dx_split_data(struct ext4_inode_ref *inode_ref,
struct ext4_hash_info *hinfo, struct ext4_block *old_data_block,
struct ext4_directory_dx_block *index_block,
@@ -735,14 +784,11 @@
return EOK;
}
-/** Split index node and maybe some parent nodes in the tree hierarchy.
- *
+/**@brief Split index node and maybe some parent nodes in the tree hierarchy.
* @param inode_ref Directory i-node
* @param dx_blocks Array with path from root to leaf node
* @param dx_block Leaf block to be split if needed
- *
* @return Error code
- *
*/
static int ext4_dir_dx_split_index(struct ext4_inode_ref *inode_ref,
struct ext4_directory_dx_block *dx_blocks,
--- a/lwext4/ext4_dir_idx.h
+++ b/lwext4/ext4_dir_idx.h
@@ -48,70 +48,127 @@
#include <stdint.h>
#include <stdbool.h>
-/**@brief TODO: ...*/
+/**@brief Get hash version used in directory index.
+ * @param root_info Pointer to root info structure of index
+ * @return Hash algorithm version
+ */
uint8_t ext4_dir_dx_root_info_get_hash_version(
struct ext4_directory_dx_root_info *root_info);
-/**@brief TODO: ...*/
+/**@brief Set hash version, that will be used in directory index.
+ * @param root_info Pointer to root info structure of index
+ * @param v Hash algorithm version
+ */
void ext4_dir_dx_root_info_set_hash_version(
struct ext4_directory_dx_root_info *root_info, uint8_t v);
-/**@brief TODO: ...*/
+/**@brief Get length of root_info structure in bytes.
+ * @param root_info Pointer to root info structure of index
+ * @return Length of the structure
+ */
uint8_t ext4_dir_dx_root_info_get_info_length(
struct ext4_directory_dx_root_info *root_info);
-/**@brief TODO: ...*/
+/**@brief Set length of root_info structure in bytes.
+ * @param root_info Pointer to root info structure of index
+ * @param info_length Length of the structure
+ */
void ext4_dir_dx_root_info_set_info_length(
struct ext4_directory_dx_root_info *root_info, uint8_t len);
-/**@brief TODO: ...*/
+/**@brief Get number of indirect levels of HTree.
+ * @param root_info Pointer to root info structure of index
+ * @return Height of HTree (actually only 0 or 1)
+ */
uint8_t ext4_dir_dx_root_info_get_indirect_levels(
struct ext4_directory_dx_root_info *root_info);
-/**@brief TODO: ...*/
+/**@brief Set number of indirect levels of HTree.
+ * @param root_info Pointer to root info structure of index
+ * @param lvl Height of HTree (actually only 0 or 1)
+ */
void ext4_dir_dx_root_info_set_indirect_levels(
struct ext4_directory_dx_root_info *root_info, uint8_t lvl);
-/**@brief TODO: ...*/
+/**@brief Get maximum number of index node entries.
+ * @param climit Pointer to counlimit structure
+ * @return Maximum of entries in node
+ */
uint16_t ext4_dir_dx_countlimit_get_limit(
struct ext4_directory_dx_countlimit *climit);
-/**@brief TODO: ...*/
+/**@brief Set maximum number of index node entries.
+ * @param climit Pointer to counlimit structure
+ * @param limit Maximum of entries in node
+ */
void ext4_dir_dx_countlimit_set_limit(
struct ext4_directory_dx_countlimit *climit, uint16_t limit);
-/**@brief TODO: ...*/
+/**@brief Get current number of index node entries.
+ * @param climit Pointer to counlimit structure
+ * @return Number of entries in node
+ */
uint16_t ext4_dir_dx_countlimit_get_count(
struct ext4_directory_dx_countlimit *climit);
-/**@brief TODO: ...*/
+/**@brief Set current number of index node entries.
+ * @param climit Pointer to counlimit structure
+ * @param count Number of entries in node
+ */
void ext4_dir_dx_countlimit_set_count(
struct ext4_directory_dx_countlimit *climit, uint16_t count);
-/**@brief TODO: ...*/
+/**@brief Get hash value of index entry.
+ * @param entry Pointer to index entry
+ * @return Hash value
+ */
uint32_t ext4_dir_dx_entry_get_hash(
struct ext4_directory_dx_entry *entry);
-/**@brief TODO: ...*/
+/**@brief Set hash value of index entry.
+ * @param entry Pointer to index entry
+ * @param hash Hash value
+ */
void ext4_dir_dx_entry_set_hash(
struct ext4_directory_dx_entry *entry, uint32_t hash);
-/**@brief TODO: ...*/
+/**@brief Get block address where child node is located.
+ * @param entry Pointer to index entry
+ * @return Block address of child node
+ */
uint32_t ext4_dir_dx_entry_get_block(
struct ext4_directory_dx_entry *entry);
-/**@brief TODO: ...*/
+/**@brief Set block address where child node is located.
+ * @param entry Pointer to index entry
+ * @param block Block address of child node
+ */
void ext4_dir_dx_entry_set_block(
struct ext4_directory_dx_entry *entry, uint32_t block);
-/**@brief TODO: ...*/
+/**@brief Initialize index structure of new directory.
+ * @param dir Pointer to directory i-node
+ * @return Error code
+ */
int ext4_dir_dx_init(struct ext4_inode_ref *dir);
-/**@brief TODO: ...*/
+/**@brief Try to find directory entry using directory index.
+ * @param result Output value - if entry will be found,
+ * than will be passed through this parameter
+ * @param inode_ref Directory i-node
+ * @param name_len Length of name to be found
+ * @param name Name to be found
+ * @return Error code
+ */
int ext4_dir_dx_find_entry(struct ext4_directory_search_result * result,
struct ext4_inode_ref *inode_ref, size_t name_len, const char *name);
-/**@brief TODO: ...*/
+/**@brief Add new entry to indexed directory
+ * @param parent Directory i-node
+ * @param child I-node to be referenced from directory entry
+ * @param name Name of new directory entry
+ * @return Error code
+ */
int ext4_dir_dx_add_entry(struct ext4_inode_ref *parent,
struct ext4_inode_ref *child, const char *name);
--- a/lwext4/ext4_fs.c
+++ b/lwext4/ext4_fs.c
@@ -310,7 +310,10 @@
-
+/**@brief Initialize block bitmap in block group.
+ * @param bg_ref Reference to block group
+ * @return Error code
+ */
static int ext4_fs_init_block_bitmap(struct ext4_block_group_ref *bg_ref)
{
uint32_t i;
@@ -346,6 +349,10 @@
return ext4_block_set(bg_ref->fs->bdev, &block_bitmap);
}
+/**@brief Initialize i-node bitmap in block group.
+ * @param bg_ref Reference to block group
+ * @return Error code
+ */
static int ext4_fs_init_inode_bitmap(struct ext4_block_group_ref *bg_ref)
{
/* Load bitmap */
@@ -380,6 +387,10 @@
return ext4_block_set(bg_ref->fs->bdev, &block_bitmap);
}
+/**@brief Initialize i-node table in block group.
+ * @param bg_ref Reference to block group
+ * @return Error code
+ */
static int ext4_fs_init_inode_table(struct ext4_block_group_ref *bg_ref)
{
struct ext4_sblock *sb = &bg_ref->fs->sb;
@@ -487,6 +498,12 @@
return EOK;
}
+/**@brief Compute checksum of block group descriptor.
+ * @param sb Superblock
+ * @param bgid Index of block group in the filesystem
+ * @param bg Block group to compute checksum for
+ * @return Checksum value
+ */
static uint16_t ext4_fs_bg_checksum(struct ext4_sblock *sb, uint32_t bgid,
struct ext4_bgroup *bg)
{
--- a/lwext4/ext4_fs.h
+++ b/lwext4/ext4_fs.h
@@ -48,60 +48,130 @@
#include <stdint.h>
#include <stdbool.h>
-/**@brief TODO: ...*/
+/**@brief Initialize filesystem and read all needed data.
+ * @param fs Filesystem instance to be initialized
+ * @param bdev Identifier if device with the filesystem
+ * @return Error code
+ */
int ext4_fs_init(struct ext4_fs *fs, struct ext4_blockdev *bdev);
-/**@brief TODO: ...*/
+/**@brief Destroy filesystem instance (used by unmount operation).
+ * @param fs Filesystem to be destroyed
+ * @return Error code
+ */
int ext4_fs_fini(struct ext4_fs *fs);
-/**@brief TODO: ...*/
+/**@brief Check filesystem's features, if supported by this driver
+ * Function can return EOK and set read_only flag. It mean's that
+ * there are some not-supported features, that can cause problems
+ * during some write operations.
+ * @param fs Filesystem to be checked
+ * @param read_only Flag if filesystem should be mounted only for reading
+ * @return Error code
+ */
int ext4_fs_check_features(struct ext4_fs *fs, bool *read_only);
-/**@brief TODO: ...*/
+/**@brief Convert block address to relative index in block group.
+ * @param sb Superblock pointer
+ * @param baddr Block number to convert
+ * @return Relative number of block
+ */
uint32_t ext4_fs_baddr2_index_in_group(struct ext4_sblock *s, uint32_t baddr);
-/**@brief TODO: ...*/
+/**@brief Convert relative block address in group to absolute address.
+ * @param s Superblock pointer
+ * @param index Relative block address
+ * @param bgid Block group
+ * @return Absolute block address
+ */
uint32_t ext4_fs_index_in_group2_baddr(struct ext4_sblock *s, uint32_t index,
uint32_t bgid);
-/**@brief TODO: ...*/
+/**@brief Get reference to block group specified by index.
+ * @param fs Filesystem to find block group on
+ * @param bgid Index of block group to load
+ * @param ref Output pointer for reference
+ * @return Error code
+ */
int ext4_fs_get_block_group_ref(struct ext4_fs *fs, uint32_t bgid,
struct ext4_block_group_ref *ref);
-/**@brief TODO: ...*/
+/**@brief Put reference to block group.
+ * @param ref Pointer for reference to be put back
+ * @return Error code
+ */
int ext4_fs_put_block_group_ref(struct ext4_block_group_ref *ref);
-/**@brief TODO: ...*/
+/**@brief Get reference to i-node specified by index.
+ * @param fs Filesystem to find i-node on
+ * @param index Index of i-node to load
+ * @param ref Output pointer for reference
+ * @return Error code
+ */
int ext4_fs_get_inode_ref(struct ext4_fs *fs, uint32_t index,
struct ext4_inode_ref *ref);
-/**@brief TODO: ...*/
+/**@brief Put reference to i-node.
+ * @param ref Pointer for reference to be put back
+ * @return Error code
+ */
int ext4_fs_put_inode_ref(struct ext4_inode_ref *ref);
-/**@brief TODO: ...*/
+/**@brief Allocate new i-node in the filesystem.
+ * @param fs Filesystem to allocated i-node on
+ * @param inode_ref Output pointer to return reference to allocated i-node
+ * @param flags Flags to be set for newly created i-node
+ * @return Error code
+ */
int ext4_fs_alloc_inode(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref,
bool is_directory);
-/**@brief TODO: ...*/
+/**@brief Release i-node and mark it as free.
+ * @param inode_ref I-node to be released
+ * @return Error code
+ */
int ext4_fs_free_inode(struct ext4_inode_ref *inode_ref);
-/**@brief TODO: ...*/
+/**@brief Truncate i-node data blocks.
+ * @param inode_ref I-node to be truncated
+ * @param new_size New size of inode (must be < current size)
+ * @return Error code
+ */
int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref,
uint64_t new_size);
-/**@brief TODO: ...*/
+/**@brief Get physical block address by logical index of the block.
+ * @param inode_ref I-node to read block address from
+ * @param iblock Logical index of block
+ * @param fblock Output pointer for return physical block address
+ * @return Error code
+ */
int ext4_fs_get_inode_data_block_index(struct ext4_inode_ref *inode_ref,
uint64_t iblock, uint32_t *fblock);
-/**@brief TODO: ...*/
+/**@brief Set physical block address for the block logical address into the i-node.
+ * @param inode_ref I-node to set block address to
+ * @param iblock Logical index of block
+ * @param fblock Physical block address
+ * @return Error code
+ */
int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref,
uint64_t iblock, uint32_t fblock);
-/**@brief TODO: ...*/
+/**@brief Release data block from i-node
+ * @param inode_ref I-node to release block from
+ * @param iblock Logical block to be released
+ * @return Error code
+ */
int ext4_fs_release_inode_block(struct ext4_inode_ref *inode_ref,
uint32_t iblock);
-/**@brief TODO: ...*/
+/**@brief Append following logical block to the i-node.
+ * @param inode_ref I-node to append block to
+ * @param fblock Output physical block address of newly allocated block
+ * @param iblock Output logical number of newly allocated block
+ * @return Error code
+ */
int ext4_fs_append_inode_block(struct ext4_inode_ref *inode_ref,
uint32_t *fblock, uint32_t *iblock);
--- a/lwext4/ext4_ialloc.c
+++ b/lwext4/ext4_ialloc.c
@@ -48,6 +48,12 @@
#include <ext4_block_group.h>
#include <ext4_bitmap.h>
+
+/**@brief Convert i-node number to relative index in block group.
+ * @param sb Superblock
+ * @param inode I-node number to be converted
+ * @return Index of the i-node in the block group
+ */
static uint32_t ext4_ialloc_inode2index_in_group(struct ext4_sblock *sb,
uint32_t inode)
{
@@ -55,6 +61,12 @@
return (inode - 1) % inodes_per_group;
}
+/**@brief Convert relative index of i-node to absolute i-node number.
+ * @param sb Superblock
+ * @param index Index to be converted
+ * @return Absolute number of the i-node
+ *
+ */
static uint32_t ext4_ialloc_index_in_group2inode(struct ext4_sblock *sb,
uint32_t index, uint32_t bgid)
{
@@ -62,6 +74,12 @@
return bgid * inodes_per_group + (index + 1);
}
+
+/**@brief Compute block group number from the i-node number.
+ * @param sb Superblock
+ * @param inode I-node number to be found the block group for
+ * @return Block group number computed from i-node number
+ */
static uint32_t ext4_ialloc_get_bgid_of_inode(struct ext4_sblock *sb,
uint32_t inode)
{
--- a/lwext4/ext4_ialloc.h
+++ b/lwext4/ext4_ialloc.h
@@ -49,10 +49,21 @@
#include <ext4_config.h>
#include <ext4_types.h>
-/**@brief TODO: ...*/
+/**@brief Free i-node number and modify filesystem data structers.
+ * @param fs Filesystem, where the i-node is located
+ * @param index Index of i-node to be release
+ * @param is_dir Flag us for information whether i-node is directory or not
+ */
int ext4_ialloc_free_inode(struct ext4_fs *fs, uint32_t index, bool is_dir);
-/**@brief TODO: ...*/
+/**@brief I-node allocation algorithm.
+ * This is more simple algorithm, than Orlov allocator used
+ * in the Linux kernel.
+ * @param fs Filesystem to allocate i-node on
+ * @param index Output value - allocated i-node number
+ * @param is_dir Flag if allocated i-node will be file or directory
+ * @return Error code
+ */
int ext4_ialloc_alloc_inode(struct ext4_fs *fs, uint32_t *index, bool is_dir);
#ifdef __cplusplus
--- a/lwext4/ext4_inode.c
+++ b/lwext4/ext4_inode.c
@@ -44,7 +44,10 @@
#include <ext4_inode.h>
#include <ext4_super.h>
-/**@brief TODO: ...*/
+/**@brief Compute number of bits for block count.
+ * @param block_size Filesystem block_size
+ * @return Number of bits
+ */
static uint32_t ext4_inode_block_bits_count(uint32_t block_size)
{
uint32_t bits = 8;
--- a/lwext4/ext4_inode.h
+++ b/lwext4/ext4_inode.h
@@ -45,122 +45,245 @@
#include <ext4_config.h>
#include <stdint.h>
-/**@brief TODO: ...*/
+/**@brief Get mode of the i-node.
+ * @param sb Superblock
+ * @param inode I-node to load mode from
+ * @return Mode of the i-node
+ */
uint32_t ext4_inode_get_mode(struct ext4_sblock *sb, struct ext4_inode *inode);
-
-/**@brief TODO: ...*/
+/**@brief Set mode of the i-node.
+ * @param sb Superblock
+ * @param inode I-node to set mode to
+ * @param mode Mode to set to i-node
+ */
void ext4_inode_set_mode(struct ext4_sblock *sb, struct ext4_inode *inode,
uint32_t mode);
-/**@brief TODO: ...*/
+/**@brief Get ID of the i-node owner (user id).
+ * @param inode I-node to load uid from
+ * @return User ID of the i-node owner
+ */
uint32_t ext4_inode_get_uid(struct ext4_inode *inode);
-/**@brief TODO: ...*/
+/**@brief Set ID of the i-node owner.
+ * @param inode I-node to set uid to
+ * @param uid ID of the i-node owner
+ */
void ext4_inode_set_uid(struct ext4_inode *inode, uint32_t uid);
-/**@brief TODO: ...*/
+/**@brief Get real i-node size.
+ * @param sb Superblock
+ * @param inode I-node to load size from
+ * @return Real size of i-node
+ */
uint64_t ext4_inode_get_size(struct ext4_sblock *sb, struct ext4_inode *inode);
-/**@brief TODO: ...*/
+/**@brief Set real i-node size.
+ * @param inode I-node to set size to
+ * @param size Size of the i-node
+ */
void ext4_inode_set_size(struct ext4_inode *inode, uint64_t size);
-/**@brief TODO: ...*/
+/**@brief Get time, when i-node was last accessed.
+ * @param inode I-node
+ * @return Time of the last access (POSIX)
+ */
uint32_t ext4_inode_get_access_time(struct ext4_inode *inode);
-/**@brief TODO: ...*/
+/**@brief Set time, when i-node was last accessed.
+ * @param inode I-node
+ * @param time Time of the last access (POSIX)
+ */
void ext4_inode_set_access_time(struct ext4_inode *inode, uint32_t time);
-/**@brief TODO: ...*/
+/**@brief Get time, when i-node was last changed.
+ * @param inode I-node
+ * @return Time of the last change (POSIX)
+ */
uint32_t ext4_inode_get_change_inode_time(struct ext4_inode *inode);
-/**@brief TODO: ...*/
+/**@brief Set time, when i-node was last changed.
+ * @param inode I-node
+ * @param time Time of the last change (POSIX)
+ */
void ext4_inode_set_change_inode_time(struct ext4_inode *inode,
uint32_t time);
-/**@brief TODO: ...*/
+/**@brief Get time, when i-node content was last modified.
+ * @param inode I-node
+ * @return Time of the last content modification (POSIX)
+ */
uint32_t ext4_inode_get_modification_time(struct ext4_inode *inode);
-/**@brief TODO: ...*/
+/**@brief Set time, when i-node content was last modified.
+ * @param inode I-node
+ * @param time Time of the last content modification (POSIX)
+ */
void ext4_inode_set_modification_time(struct ext4_inode *inode, uint32_t time);
-/**@brief TODO: ...*/
+/**@brief Get time, when i-node was deleted.
+ * @param inode I-node
+ * @return Time of the delete action (POSIX)
+ */
uint32_t ext4_inode_get_deletion_time(struct ext4_inode *inode);
-/**@brief TODO: ...*/
+/**@brief Set time, when i-node was deleted.
+ * @param inode I-node
+ * @param time Time of the delete action (POSIX)
+ */
void ext4_inode_set_deletion_time(struct ext4_inode *inode, uint32_t time);
-/**@brief TODO: ...*/
+/**@brief Get ID of the i-node owner's group.
+ * @param inode I-node to load gid from
+ * @return Group ID of the i-node owner
+ */
uint32_t ext4_inode_get_gid(struct ext4_inode *inode);
-/**@brief TODO: ...*/
+/**@brief Set ID ot the i-node owner's group.
+ * @param inode I-node to set gid to
+ * @param gid Group ID of the i-node owner
+ */
void ext4_inode_set_gid(struct ext4_inode *inode, uint32_t gid);
-/**@brief TODO: ...*/
+/**@brief Get number of links to i-node.
+ * @param inode I-node to load number of links from
+ * @return Number of links to i-node
+ */
uint16_t ext4_inode_get_links_count(struct ext4_inode *inode);
-/**@brief TODO: ...*/
+/**@brief Set number of links to i-node.
+ * @param inode I-node to set number of links to
+ * @param count Number of links to i-node
+ */
void ext4_inode_set_links_count(struct ext4_inode *inode, uint16_t cnt);
-/**@brief TODO: ...*/
+/**@brief Get number of 512-bytes blocks used for i-node.
+ * @param sb Superblock
+ * @param inode I-node
+ * @return Number of 512-bytes blocks
+ */
uint64_t ext4_inode_get_blocks_count(struct ext4_sblock *sb,
struct ext4_inode *inode);
-/**@brief TODO: ...*/
+/**@brief Set number of 512-bytes blocks used for i-node.
+ * @param sb Superblock
+ * @param inode I-node
+ * @param count Number of 512-bytes blocks
+ * @return Error code
+ */
int ext4_inode_set_blocks_count(struct ext4_sblock *sb,
struct ext4_inode *inode, uint64_t cnt);
-/**@brief TODO: ...*/
+/**@brief Get flags (features) of i-node.
+ * @param inode I-node to get flags from
+ * @return Flags (bitmap)
+ */
uint32_t ext4_inode_get_flags(struct ext4_inode *inode);
-/**@brief TODO: ...*/
+/**@brief Set flags (features) of i-node.
+ * @param inode I-node to set flags to
+ * @param flags Flags to set to i-node
+ */
void ext4_inode_set_flags(struct ext4_inode *inode, uint32_t flags);
-/**@brief TODO: ...*/
+/**@brief Get file generation (used by NFS).
+ * @param inode I-node
+ * @return File generation
+ */
uint32_t ext4_inode_get_generation(struct ext4_inode *inode);
-/**@brief TODO: ...*/
+/**@brief Set file generation (used by NFS).
+ * @param inode I-node
+ * @param generation File generation
+ */
void ext4_inode_set_generation(struct ext4_inode *inode, uint32_t gen);
-/**@brief TODO: ...*/
+/**@brief Get address of block, where are extended attributes located.
+ * @param inode I-node
+ * @param sb Superblock
+ * @return Block address
+ */
uint64_t ext4_inode_get_file_acl(struct ext4_inode *inode,
struct ext4_sblock *sb);
-/**@brief TODO: ...*/
+/**@brief Set address of block, where are extended attributes located.
+ * @param inode I-node
+ * @param sb Superblock
+ * @param file_acl Block address
+ */
void ext4_inode_set_file_acl(struct ext4_inode *inode,
struct ext4_sblock *sb, uint64_t acl);
-/**@brief TODO: ...*/
+/**@brief Get block address of specified direct block.
+ * @param inode I-node to load block from
+ * @param idx Index of logical block
+ * @return Physical block address
+ */
uint32_t ext4_inode_get_direct_block(struct ext4_inode *inode, uint32_t idx);
-/**@brief TODO: ...*/
+/**@brief Set block address of specified direct block.
+ * @param inode I-node to set block address to
+ * @param idx Index of logical block
+ * @param fblock Physical block address
+ */
void ext4_inode_set_direct_block(struct ext4_inode *inode, uint32_t idx,
uint32_t block);
-/**@brief TODO: ...*/
+/**@brief Get block address of specified indirect block.
+ * @param inode I-node to get block address from
+ * @param idx Index of indirect block
+ * @return Physical block address
+ */
uint32_t ext4_inode_get_indirect_block(struct ext4_inode *inode, uint32_t idx);
-/**@brief TODO: ...*/
+/**@brief Set block address of specified indirect block.
+ * @param inode I-node to set block address to
+ * @param idx Index of indirect block
+ * @param fblock Physical block address
+ */
void ext4_inode_set_indirect_block(struct ext4_inode *inode, uint32_t idx,
uint32_t block);
-/**@brief TODO: ...*/
+/**@brief Check if i-node has specified type.
+ * @param sb Superblock
+ * @param inode I-node to check type of
+ * @param type Type to check
+ * @return Result of check operation
+ */
bool ext4_inode_is_type(struct ext4_sblock *sb, struct ext4_inode *inode,
uint32_t type);
-/**@brief TODO: ...*/
+/**@brief Check if i-node has specified flag.
+ * @param inode I-node to check flags of
+ * @param flag Flag to check
+ * @return Result of check operation
+ */
bool ext4_inode_has_flag(struct ext4_inode *inode, uint32_t f);
-/**@brief TODO: ...*/
+/**@brief Remove specified flag from i-node.
+ * @param inode I-node to clear flag on
+ * @param clear_flag Flag to be cleared
+ */
void ext4_inode_clear_flag(struct ext4_inode *inode, uint32_t f);
-/**@brief TODO: ...*/
+/**@brief Set specified flag to i-node.
+ * @param inode I-node to set flag on
+ * @param set_flag Flag to be set
+ */
void ext4_inode_set_flag(struct ext4_inode *inode, uint32_t f);
-/**@brief TODO: ...*/
+/**@brief Check if i-node can be truncated.
+ * @param sb Superblock
+ * @param inode I-node to check
+ * @return Result of the check operation
+ */
bool ext4_inode_can_truncate(struct ext4_sblock *sb, struct ext4_inode *inode);
-
+/**@brief Get extent header from the root of the extent tree.
+ * @param inode I-node to get extent header from
+ * @return Pointer to extent header of the root node
+ */
struct ext4_extent_header * ext4_inode_get_extent_header(struct ext4_inode *inode);
#endif /* EXT4_INODE_H_ */
--- a/lwext4/ext4_super.h
+++ b/lwext4/ext4_super.h
@@ -47,7 +47,6 @@
#include <ext4_types.h>
-/****************************Unstandard access to superblock*****************/
/**@brief Blocks count get stored in superblock.
* @param s superblock descriptor