diff --git a/SConscript b/SConscript index a5a09b1..8817617 100644 --- a/SConscript +++ b/SConscript @@ -20,6 +20,7 @@ src/ext4_ialloc.c src/ext4_inode.c src/ext4_journal.c src/ext4_mkfs.c +src/ext4_mp.c src/ext4_super.c src/ext4_trans.c src/ext4_xattr.c @@ -32,7 +33,7 @@ CPPDEFINES = ['CONFIG_USE_DEFAULT_CFG', 'CONFIG_HAVE_OWN_OFLAGS=0'] LOCAL_CCFLAGS = '' -group = DefineGroup('Filesystem', objs, +group = DefineGroup('Filesystem', objs, depend = ['RT_USING_DFS', 'RT_USING_DFS_LWEXT4'], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES, diff --git a/fs_test/CMakeLists.txt b/fs_test/CMakeLists.txt index 84760cf..16befb3 100644 --- a/fs_test/CMakeLists.txt +++ b/fs_test/CMakeLists.txt @@ -24,9 +24,9 @@ add_executable(lwext4-mbr lwext4_mbr.c) target_link_libraries(lwext4-mbr blockdev) target_link_libraries(lwext4-mbr lwext4) -install (TARGETS lwext4-server DESTINATION /usr/bin) -install (TARGETS lwext4-client DESTINATION /usr/bin) -install (TARGETS lwext4-generic DESTINATION /usr/bin) -install (TARGETS lwext4-mkfs DESTINATION /usr/bin) -install (TARGETS lwext4-mbr DESTINATION /usr/bin) +install (TARGETS lwext4-server DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) +install (TARGETS lwext4-client DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) +install (TARGETS lwext4-generic DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) +install (TARGETS lwext4-mkfs DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) +install (TARGETS lwext4-mbr DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) diff --git a/include/ext4.h b/include/ext4.h index 981e517..5daae72 100644 --- a/include/ext4.h +++ b/include/ext4.h @@ -50,6 +50,8 @@ extern "C" { #include #include #include +#include +#include #include @@ -123,6 +125,13 @@ int ext4_mount(struct ext4_blockdev *bd, const char *mount_point, bool read_only); +/**@brief Umount operation. + * + * @param mount_point Mount point. + * + * @return Standard error code */ +int ext4_umount_mp(struct ext4_mountpoint *mp); + /**@brief Umount operation. * * @param mount_pount Mount point. @@ -140,7 +149,7 @@ int ext4_umount(const char *mount_point); * * ext4_journal_stop("/"); * ext4_umount("/"); - * @param mount_pount Mount point. + * @param mount_point Mount point. * * @return Standard error code. */ int ext4_journal_start(const char *mount_point); @@ -148,7 +157,7 @@ int ext4_journal_start(const char *mount_point); /**@brief Stops journaling. Journaling start/stop functions are transparent * and might be used on filesystems without journaling support. * - * @param mount_pount Mount point name. + * @param mount_point Mount point name. * * @return Standard error code. */ int ext4_journal_stop(const char *mount_point); @@ -156,7 +165,7 @@ int ext4_journal_stop(const char *mount_point); /**@brief Journal recovery. * @warning Must be called after @ref ext4_mount. * - * @param mount_pount Mount point. + * @param mount_point Mount point. * * @return Standard error code. */ int ext4_recover(const char *mount_point); @@ -178,7 +187,7 @@ struct ext4_mount_stats { /**@brief Get file mount point stats. * - * @param mount_pount Mount point. + * @param mount_point Mount point. * @param stats Filesystem stats. * * @return Standard error code. */ @@ -187,7 +196,7 @@ int ext4_mount_point_stats(const char *mount_point, /**@brief Setup OS lock routines. * - * @param mount_pount Mount point. + * @param mount_point Mount point. * @param locks Lock and unlock functions * * @return Standard error code. */ @@ -196,7 +205,7 @@ int ext4_mount_setup_locks(const char *mount_point, /**@brief Acquire the filesystem superblock pointer of a mp. * - * @param mount_pount Mount point. + * @param mount_point Mount point. * @param sb Superblock handle * * @return Standard error code. */ @@ -233,7 +242,7 @@ int ext4_get_sblock(const char *mount_point, struct ext4_sblock **sb); * Write back mode is useful when you want to create a lot of empty * files/directories. * - * @param mount_pount Mount point. + * @param path Mount point. * @param on Enable/disable cache writeback mode. * * @return Standard error code. */ @@ -242,7 +251,7 @@ int ext4_cache_write_back(const char *path, bool on); /**@brief Force cache flush. * - * @param mount_pount Mount point. + * @param path Mount point. * * @return Standard error code. */ int ext4_cache_flush(const char *path); @@ -390,6 +399,9 @@ int ext4_raw_inode_fill(const char *path, uint32_t *ret_ino, * @return Standard error code.*/ int ext4_inode_exist(const char *path, int type); +void* ext4_get_inode_ref(const char *path, struct ext4_inode_ref *ref); +int ext4_put_inode_ref(struct ext4_mountpoint *mp, struct ext4_inode_ref *ref); + /**@brief Change file/directory/link mode bits. * * @param path Path to file/dir/link. @@ -517,8 +529,8 @@ int ext4_setxattr(const char *path, const char *name, size_t name_len, * @param path Path to file/directory. * @param name Name of the entry to get. * @param name_len Length of @name in bytes. - * @param data Data of the entry to get. - * @param data_size Size of data to get. + * @param buf Data of the entry to get. + * @param buf_size Size of data to get. * * @return Standard error code.*/ int ext4_getxattr(const char *path, const char *name, size_t name_len, diff --git a/include/ext4_balloc.h b/include/ext4_balloc.h index bdaa17f..d56a575 100644 --- a/include/ext4_balloc.h +++ b/include/ext4_balloc.h @@ -54,7 +54,7 @@ extern "C" { #include /**@brief Compute number of block group from block address. - * @param sb superblock pointer. + * @param s superblock pointer. * @param baddr Absolute address of block. * @return Block group index */ @@ -62,7 +62,7 @@ uint32_t ext4_balloc_get_bgid_of_block(struct ext4_sblock *s, ext4_fsblk_t baddr); /**@brief Compute the starting block address of a block group - * @param sb superblock pointer. + * @param s superblock pointer. * @param bgid block group index * @return Block address */ @@ -95,7 +95,6 @@ int ext4_balloc_free_blocks(struct ext4_inode_ref *inode_ref, /**@brief Allocate block procedure. * @param inode_ref inode reference - * @param goal * @param baddr allocated block address * @return standard error code*/ int ext4_balloc_alloc_block(struct ext4_inode_ref *inode_ref, diff --git a/include/ext4_bcache.h b/include/ext4_bcache.h index f83d4d5..163604f 100644 --- a/include/ext4_bcache.h +++ b/include/ext4_bcache.h @@ -84,6 +84,8 @@ struct ext4_buf { /**@brief Reference count table*/ uint32_t refctr; + /* refcount for read */ + uint32_t read_refctr; /**@brief The block cache this buffer belongs to. */ struct ext4_bcache *bc; @@ -185,9 +187,11 @@ static inline void ext4_bcache_clear_dirty(struct ext4_buf *buf) { /**@brief Increment reference counter of buf by 1.*/ #define ext4_bcache_inc_ref(buf) ((buf)->refctr++) +#define ext4_bcache_inc_read_ref(buf) ((buf)->read_refctr++) /**@brief Decrement reference counter of buf by 1.*/ #define ext4_bcache_dec_ref(buf) ((buf)->refctr--) +#define ext4_bcache_dec_read_ref(buf) ((buf)->read_refctr--) /**@brief Insert buffer to dirty cache list * @param bc block cache descriptor @@ -248,8 +252,7 @@ void ext4_bcache_invalidate_buf(struct ext4_bcache *bc, /**@brief Invalidate a range of buffers. * @param bc block cache descriptor * @param from starting lba - * @param cnt block counts - * @param buf buffer*/ + * @param cnt block counts*/ void ext4_bcache_invalidate_lba(struct ext4_bcache *bc, uint64_t from, uint32_t cnt); diff --git a/include/ext4_block_group.h b/include/ext4_block_group.h index 2eca999..279e1df 100644 --- a/include/ext4_block_group.h +++ b/include/ext4_block_group.h @@ -73,7 +73,6 @@ static inline uint64_t ext4_bg_get_block_bitmap(struct ext4_bgroup *bg, * @param bg pointer to block group * @param s pointer to superblock * @param blk block to set - * @return Address of block with block bitmap */ static inline void ext4_bg_set_block_bitmap(struct ext4_bgroup *bg, struct ext4_sblock *s, uint64_t blk) @@ -106,7 +105,6 @@ static inline uint64_t ext4_bg_get_inode_bitmap(struct ext4_bgroup *bg, * @param bg Pointer to block group * @param s Pointer to superblock * @param blk block to set - * @return Address of block with i-node bitmap */ static inline void ext4_bg_set_inode_bitmap(struct ext4_bgroup *bg, struct ext4_sblock *s, uint64_t blk) @@ -139,7 +137,6 @@ ext4_bg_get_inode_table_first_block(struct ext4_bgroup *bg, * @param bg Pointer to block group * @param s Pointer to superblock * @param blk block to set - * @return Address of first block of i-node table */ static inline void ext4_bg_set_inode_table_first_block(struct ext4_bgroup *bg, @@ -152,7 +149,7 @@ ext4_bg_set_inode_table_first_block(struct ext4_bgroup *bg, /**@brief Get number of free blocks in block group. * @param bg Pointer to block group - * @param sb Pointer to superblock + * @param s 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, @@ -282,7 +279,7 @@ static inline void ext4_bg_set_checksum(struct ext4_bgroup *bg, uint16_t crc) /**@brief Check if block group has a flag. * @param bg Pointer to block group - * @param flag Flag to be checked + * @param f 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) @@ -292,7 +289,7 @@ static inline bool ext4_bg_has_flag(struct ext4_bgroup *bg, uint32_t f) /**@brief Set flag of block group. * @param bg Pointer to block group - * @param flag Flag to be set + * @param f Flag to be set */ static inline void ext4_bg_set_flag(struct ext4_bgroup *bg, uint32_t f) { @@ -303,7 +300,7 @@ static inline void ext4_bg_set_flag(struct ext4_bgroup *bg, uint32_t f) /**@brief Clear flag of block group. * @param bg Pointer to block group - * @param flag Flag to be cleared + * @param f Flag to be cleared */ static inline void ext4_bg_clear_flag(struct ext4_bgroup *bg, uint32_t f) { diff --git a/include/ext4_blockdev.h b/include/ext4_blockdev.h index 2406864..5d8aa09 100644 --- a/include/ext4_blockdev.h +++ b/include/ext4_blockdev.h @@ -153,8 +153,6 @@ struct ext4_blockdev { } /**@brief Block device initialization. - * @param bdev block device descriptor - * @param bg_bsize logical block size * @param bdev block device descriptor * @return standard error code*/ int ext4_block_init(struct ext4_blockdev *bdev); @@ -185,8 +183,7 @@ int ext4_block_flush_lba(struct ext4_blockdev *bdev, uint64_t lba); /**@brief Set logical block size in block device. * @param bdev block device descriptor - * @param lb_size logical block size (in bytes) - * @return standard error code*/ + * @param lb_bsize logical block size (in bytes)*/ void ext4_block_set_lb_size(struct ext4_blockdev *bdev, uint32_t lb_bsize); /**@brief Block get function (through cache, don't read). diff --git a/include/ext4_config.h b/include/ext4_config.h index 88ebcd0..d0601a8 100644 --- a/include/ext4_config.h +++ b/include/ext4_config.h @@ -147,7 +147,7 @@ extern "C" { /**@brief Maximum mountpoint count*/ #ifndef CONFIG_EXT4_MOUNTPOINTS_COUNT -#define CONFIG_EXT4_MOUNTPOINTS_COUNT 4 +#define CONFIG_EXT4_MOUNTPOINTS_COUNT 20 #endif /**@brief Include open flags from ext4_errno or standard library.*/ diff --git a/include/ext4_crc32.h b/include/ext4_crc32.h index b873f2b..a589b77 100644 --- a/include/ext4_crc32.h +++ b/include/ext4_crc32.h @@ -57,7 +57,7 @@ uint32_t ext4_crc32(uint32_t crc, const void *buf, uint32_t size); /**@brief CRC32C algorithm. * @param crc input feed * @param buf input buffer - * @param length input buffer length (bytes) + * @param size input buffer length (bytes) * @return updated crc32c value*/ uint32_t ext4_crc32c(uint32_t crc, const void *buf, uint32_t size); diff --git a/include/ext4_debug.h b/include/ext4_debug.h index 460ad5a..1febbef 100644 --- a/include/ext4_debug.h +++ b/include/ext4_debug.h @@ -139,11 +139,11 @@ static inline const char *ext4_dmask_id2str(uint32_t m) #define DBG_ERROR "[error] " /**@brief Global mask debug set. - * @brief m new debug mask.*/ + * @param m new debug mask.*/ void ext4_dmask_set(uint32_t m); /**@brief Global mask debug clear. - * @brief m new debug mask.*/ + * @param m new debug mask.*/ void ext4_dmask_clr(uint32_t m); /**@brief Global debug mask get. diff --git a/include/ext4_dir.h b/include/ext4_dir.h index 3067e78..a4ab0ac 100644 --- a/include/ext4_dir.h +++ b/include/ext4_dir.h @@ -108,7 +108,7 @@ static inline uint16_t ext4_dir_en_get_entry_len(struct ext4_dir_en *de) /**@brief Set directory entry length. * @param de Directory entry - * @param length Entry length + * @param l Entry length */ static inline void ext4_dir_en_set_entry_len(struct ext4_dir_en *de, uint16_t l) { @@ -135,7 +135,7 @@ static inline uint16_t ext4_dir_en_get_name_len(struct ext4_sblock *sb, /**@brief Set directory entry name length. * @param sb Superblock * @param de Directory entry - * @param length Entry name length + * @param len Entry name length */ static inline void ext4_dir_en_set_name_len(struct ext4_sblock *sb, struct ext4_dir_en *de, @@ -165,7 +165,7 @@ static inline uint8_t ext4_dir_en_get_inode_type(struct ext4_sblock *sb, /**@brief Set i-node type of directory entry. * @param sb Superblock * @param de Directory entry - * @param type I-node type (file, dir, etc.) + * @param t I-node type (file, dir, etc.) */ static inline void ext4_dir_en_set_inode_type(struct ext4_sblock *sb, diff --git a/include/ext4_dir_idx.h b/include/ext4_dir_idx.h index b90096b..f6c6e62 100644 --- a/include/ext4_dir_idx.h +++ b/include/ext4_dir_idx.h @@ -66,7 +66,7 @@ struct ext4_dir_idx_block { /**@brief Initialize index structure of new directory. * @param dir Pointer to directory i-node - * @param dir Pointer to parent directory i-node + * @param parent Pointer to parent directory i-node * @return Error code */ int ext4_dir_dx_init(struct ext4_inode_ref *dir, diff --git a/include/ext4_fs.h b/include/ext4_fs.h index 022ce55..a2c3108 100644 --- a/include/ext4_fs.h +++ b/include/ext4_fs.h @@ -87,7 +87,7 @@ struct ext4_inode_ref { /**@brief Convert block address to relative index in block group. - * @param sb Superblock pointer + * @param s Superblock pointer * @param baddr Block number to convert * @return Relative number of block */ @@ -187,7 +187,7 @@ void ext4_fs_inode_blocks_init(struct ext4_fs *fs, int ext4_fs_put_inode_ref(struct ext4_inode_ref *ref); /**@brief Convert filetype to inode mode. - * @param filetype + * @param filetype File type * @return inode mode */ uint32_t ext4_fs_correspond_inode_mode(int filetype); @@ -222,7 +222,6 @@ ext4_fsblk_t ext4_fs_inode_to_goal_block(struct ext4_inode_ref *inode_ref); /**@brief Compute 'goal' for allocation algorithm (For blockmap). * @param inode_ref Reference to inode, to allocate block for - * @param goal * @return error code */ int ext4_fs_indirect_find_goal(struct ext4_inode_ref *inode_ref, @@ -260,12 +259,12 @@ int ext4_fs_append_inode_dblk(struct ext4_inode_ref *inode_ref, ext4_fsblk_t *fblock, ext4_lblk_t *iblock); /**@brief Increment inode link count. - * @param inode none handle + * @param inode_ref none handle */ void ext4_fs_inode_links_count_inc(struct ext4_inode_ref *inode_ref); /**@brief Decrement inode link count. - * @param inode none handle + * @param inode_ref none handle */ void ext4_fs_inode_links_count_dec(struct ext4_inode_ref *inode_ref); diff --git a/include/ext4_hash.h b/include/ext4_hash.h index 3be7f6a..b58e952 100644 --- a/include/ext4_hash.h +++ b/include/ext4_hash.h @@ -57,7 +57,7 @@ struct ext4_hash_info { * @param name entry name * @param len entry name length * @param hash_seed (from superblock) - * @param hash version (from superblock) + * @param hash_version version (from superblock) * @param hash_minor output value * @param hash_major output value * @return standard error code*/ diff --git a/include/ext4_inode.h b/include/ext4_inode.h index ed8ab5e..c85ec52 100644 --- a/include/ext4_inode.h +++ b/include/ext4_inode.h @@ -159,7 +159,7 @@ uint16_t ext4_inode_get_links_cnt(struct ext4_inode *inode); /**@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 + * @param cnt Number of links to i-node */ void ext4_inode_set_links_cnt(struct ext4_inode *inode, uint16_t cnt); @@ -174,7 +174,7 @@ uint64_t ext4_inode_get_blocks_count(struct ext4_sblock *sb, /**@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 + * @param cnt Number of 512-bytes blocks * @return Error code */ int ext4_inode_set_blocks_count(struct ext4_sblock *sb, @@ -200,7 +200,7 @@ uint32_t ext4_inode_get_generation(struct ext4_inode *inode); /**@brief Set file generation (used by NFS). * @param inode I-node - * @param generation File generation + * @param gen File generation */ void ext4_inode_set_generation(struct ext4_inode *inode, uint32_t gen); @@ -232,7 +232,7 @@ uint64_t ext4_inode_get_file_acl(struct ext4_inode *inode, /**@brief Set address of block, where are extended attributes located. * @param inode I-node * @param sb Superblock - * @param file_acl Block address + * @param acl Block address */ void ext4_inode_set_file_acl(struct ext4_inode *inode, struct ext4_sblock *sb, uint64_t acl); @@ -247,7 +247,7 @@ uint32_t ext4_inode_get_direct_block(struct ext4_inode *inode, uint32_t idx); /**@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 + * @param block Physical block address */ void ext4_inode_set_direct_block(struct ext4_inode *inode, uint32_t idx, uint32_t block); @@ -262,7 +262,7 @@ uint32_t ext4_inode_get_indirect_block(struct ext4_inode *inode, uint32_t idx); /**@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 + * @param block Physical block address */ void ext4_inode_set_indirect_block(struct ext4_inode *inode, uint32_t idx, uint32_t block); @@ -297,20 +297,20 @@ bool ext4_inode_is_type(struct ext4_sblock *sb, struct ext4_inode *inode, /**@brief Check if i-node has specified flag. * @param inode I-node to check flags of - * @param flag Flag to check + * @param f Flag to check * @return Result of check operation */ bool ext4_inode_has_flag(struct ext4_inode *inode, uint32_t f); /**@brief Remove specified flag from i-node. * @param inode I-node to clear flag on - * @param clear_flag Flag to be cleared + * @param f Flag to be cleared */ void ext4_inode_clear_flag(struct ext4_inode *inode, uint32_t f); /**@brief Set specified flag to i-node. * @param inode I-node to set flag on - * @param set_flag Flag to be set + * @param f Flag to be set */ void ext4_inode_set_flag(struct ext4_inode *inode, uint32_t f); diff --git a/include/ext4_mp.h b/include/ext4_mp.h new file mode 100644 index 0000000..0a972f9 --- /dev/null +++ b/include/ext4_mp.h @@ -0,0 +1,66 @@ +/** @addtogroup lwext4 + * @{ + */ +/** + * @file ext4_mp.h + * @brief mount point handle functions + */ + +#ifndef EXT4_MP_H_ +#define EXT4_MP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +#include + +/**@brief Mount point OS dependent lock*/ +#define EXT4_MP_LOCK(_m) \ + do { \ + if ((_m)->os_locks) \ + (_m)->os_locks->lock(); \ + } while (0) + +/**@brief Mount point OS dependent unlock*/ +#define EXT4_MP_UNLOCK(_m) \ + do { \ + if ((_m)->os_locks) \ + (_m)->os_locks->unlock(); \ + } while (0) + +/**@brief Mount point descriptor.*/ +struct ext4_mountpoint { + + /**@brief Mount done flag.*/ + bool mounted; + + /**@brief Mount point name (@ref ext4_mount)*/ + char name[CONFIG_EXT4_MAX_MP_NAME + 1]; + + /**@brief OS dependent lock/unlock functions.*/ + const struct ext4_lock *os_locks; + + /**@brief Ext4 filesystem internals.*/ + struct ext4_fs fs; + + /**@brief JBD fs.*/ + struct jbd_fs jbd_fs; + + /**@brief Journal.*/ + struct jbd_journal jbd_journal; + + /**@brief Block cache.*/ + struct ext4_bcache bc; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* EXT4_MP_H_ */ diff --git a/include/ext4_super.h b/include/ext4_super.h index 9ea0988..f8af160 100644 --- a/include/ext4_super.h +++ b/include/ext4_super.h @@ -61,7 +61,7 @@ static inline uint64_t ext4_sb_get_blocks_cnt(struct ext4_sblock *s) /**@brief Blocks count set in superblock. * @param s superblock descriptor - * @return count of blocks*/ + * @param cnt count of blocks*/ static inline void ext4_sb_set_blocks_cnt(struct ext4_sblock *s, uint64_t cnt) { s->blocks_count_lo = to_le32((cnt << 32) >> 32); diff --git a/include/ext4_types.h b/include/ext4_types.h index 3a9bc2f..8b8435d 100644 --- a/include/ext4_types.h +++ b/include/ext4_types.h @@ -829,10 +829,11 @@ struct jbd_sb { #else -#define ext4_malloc malloc -#define ext4_calloc calloc -#define ext4_realloc realloc -#define ext4_free free +#include +#define ext4_malloc(_sz) rt_malloc(_sz) +#define ext4_calloc(_cnt, _sz) rt_calloc(_cnt, _sz) +#define ext4_realloc(_ptr, _sz) rt_realloc(_ptr, _sz) +#define ext4_free(_ptr) rt_free(_ptr) #endif diff --git a/ports/rtthread/dfs_ext.c b/ports/rtthread/dfs_ext.c index a9f67b4..439a6fd 100644 --- a/ports/rtthread/dfs_ext.c +++ b/ports/rtthread/dfs_ext.c @@ -12,11 +12,15 @@ * 2023-01-15 bernard add RT-Thread 5.0.x support */ -#include #include + +#include + #include #include #include +#include +#include #include "ext4.h" #include "ext4_mkfs.h" @@ -25,12 +29,39 @@ #include "ext4_errno.h" #include "ext4_mbr.h" #include "ext4_super.h" -#include "ext4_debug.h" -#include "ext4_inode.h" +#include "ext4_fs.h" +#include #include "dfs_ext.h" #include "dfs_ext_blockdev.h" +#ifdef RT_USING_PAGECACHE +#include "dfs_pcache.h" +#endif + +#ifdef PKG_USING_DLOG +#include +#else +#define DLOG(...) +#endif + +struct dfs_ext4_vnode +{ + struct ext4_mountpoint *mp; + struct ext4_inode_ref inode_ref; +}; + +struct dfs_ext4_file +{ + uint32_t type; /* EXT4_DE_DIR or EXT4_DE_REG_FILE */ + union + { + ext4_file file; + ext4_dir dir; + } entry; + struct dfs_ext4_vnode vnode; +}; + static rt_mutex_t ext4_mutex = RT_NULL; static void ext4_lock(void); @@ -55,82 +86,304 @@ static void ext4_lock(void) { RT_ASSERT(0); } - return ; + return; } static void ext4_unlock(void) { rt_mutex_release(ext4_mutex); - return ; + return; +} + +static off_t dfs_ext_lseek(struct dfs_file *file, off_t offset, int whence); + +#ifdef RT_USING_PAGECACHE +static ssize_t dfs_ext_page_read(struct dfs_file *file, struct dfs_page *page); +static ssize_t dfs_ext_page_write(struct dfs_page *page); + +static struct dfs_aspace_ops dfs_ext_aspace_ops = +{ + .read = dfs_ext_page_read, + .write = dfs_ext_page_write, +}; +#endif + +/* update vnode information */ +rt_inline int ext4_vnode_update_info(struct dfs_vnode *vnode) +{ + if (vnode && vnode->data) + { + struct dfs_ext4_file *ext_file = (struct dfs_ext4_file *)vnode->data; + + vnode->mode = ext4_inode_get_mode(&ext_file->vnode.mp->fs.sb, ext_file->vnode.inode_ref.inode); + vnode->uid = ext4_inode_get_uid(ext_file->vnode.inode_ref.inode); + vnode->gid = ext4_inode_get_gid(ext_file->vnode.inode_ref.inode); + vnode->atime.tv_sec = ext4_inode_get_access_time(ext_file->vnode.inode_ref.inode); + vnode->mtime.tv_sec = ext4_inode_get_modif_time(ext_file->vnode.inode_ref.inode); + vnode->ctime.tv_sec = ext4_inode_get_change_inode_time(ext_file->vnode.inode_ref.inode); + } + + return 0; } -rt_inline const char *get_fd_file(struct dfs_file *fd) +/* file system ops */ + +static struct dfs_vnode *dfs_ext_lookup(struct dfs_dentry *dentry) { - const char *fn = NULL; + char *fn = RT_NULL; + struct dfs_vnode *vnode = RT_NULL; + struct dfs_ext4_file *ext_file = RT_NULL; - if (fd) + ext_file = (struct dfs_ext4_file *)rt_calloc(1, sizeof(struct dfs_ext4_file)); + if (ext_file) { -#if (RTTHREAD_VERSION >= RT_VERSION_CHECK(5, 0, 0)) - fn = fd->vnode->fullpath; -#else - fn = fd->path; + fn = dfs_dentry_full_path(dentry); + if (fn) + { + DLOG(msg, "ext", "vnode", DLOG_MSG, "dfs_vnode_create()"); + vnode = dfs_vnode_create(); + if (vnode) + { + ext_file->vnode.mp = ext4_get_inode_ref(fn, &(ext_file->vnode.inode_ref)); + if (ext_file->vnode.mp) + { + /* found entry */ + int type = ext4_inode_type(&(ext_file->vnode.mp->fs.sb), ext_file->vnode.inode_ref.inode); + switch (type) + { + case EXT4_INODE_MODE_FILE: + vnode->type = FT_REGULAR; + vnode->size = ext4_inode_get_size(&(ext_file->vnode.mp->fs.sb), ext_file->vnode.inode_ref.inode); +#ifdef RT_USING_PAGECACHE + vnode->aspace = dfs_aspace_create(dentry, vnode, &dfs_ext_aspace_ops); +#endif + break; + case EXT4_INODE_MODE_DIRECTORY: + vnode->type = FT_DIRECTORY; + vnode->size = 0; + break; + case EXT4_INODE_MODE_SOFTLINK: + vnode->type = FT_SYMLINK; + vnode->size = 0; + break; + } + + vnode->nlink = 1; + DLOG(msg, "ext", "mnt", DLOG_MSG, "dfs_mnt_ref(dentry->mnt, name=%s)", dentry->mnt->fs_ops->name); + vnode->mnt = dentry->mnt; + vnode->data = (void *)ext_file; + ext_file->type = EXT4_DE_UNKNOWN; + rt_mutex_init(&vnode->lock, dentry->pathname, RT_IPC_FLAG_PRIO); + + ext4_vnode_update_info(vnode); + } + else + { + /* free vnode */ + DLOG(msg, "ext", "vnode", DLOG_MSG, "dfs_vnode_destroy(no entry)"); + dfs_vnode_destroy(vnode); + vnode = RT_NULL; + } + } + rt_free(fn); + } + + if (vnode == RT_NULL) + { + rt_free(ext_file); + } + } + + return vnode; +} + +static struct dfs_vnode *dfs_ext_create_vnode(struct dfs_dentry *dentry, int type, mode_t mode) +{ + int ret = 0; + char *fn = NULL; + struct dfs_vnode *vnode = RT_NULL; + struct dfs_ext4_file *ext_file = RT_NULL; + int filetype = EXT4_DE_UNKNOWN; + + vnode = dfs_vnode_create(); + if (vnode) + { + fn = dfs_dentry_full_path(dentry); + if (fn) + { + ext_file = (struct dfs_ext4_file *)rt_calloc(1, sizeof(struct dfs_ext4_file)); + if (ext_file) + { + if (type == FT_DIRECTORY) + { + /* create dir */ + ret = ext4_dir_mk(fn); + if (ret == EOK) + { + ext4_mode_set(fn, mode); + ext_file->vnode.mp = ext4_get_inode_ref(fn, &(ext_file->vnode.inode_ref)); + if (ext_file->vnode.mp) + { + vnode->type = FT_DIRECTORY; + vnode->size = 0; + } + else + { + rt_kprintf("get inode ref failed: %s\n", fn); + } + } + } + else if (type == FT_REGULAR) + { + ext4_file file; + /* create file */ + if (!(mode & S_IFMT) || S_ISREG(mode)) + { + ret = ext4_fopen2(&file, fn, O_CREAT); + if (ret == EOK) + { + ext4_fclose(&file); + + ext4_mode_set(fn, mode); + ext_file->vnode.mp = ext4_get_inode_ref(fn, &(ext_file->vnode.inode_ref)); + if (ext_file->vnode.mp) + { + vnode->type = FT_REGULAR; + vnode->size = ext4_inode_get_size(&(ext_file->vnode.mp->fs.sb), ext_file->vnode.inode_ref.inode); + } +#ifdef RT_USING_PAGECACHE + vnode->aspace = dfs_aspace_create(dentry, vnode, &dfs_ext_aspace_ops); #endif + } + } + else + { + if (S_ISLNK(mode)) + { + filetype = EXT4_DE_SYMLINK; + } + else if (S_ISDIR(mode)) + { + filetype = EXT4_DE_DIR; + } + else if (S_ISCHR(mode)) + { + filetype = EXT4_DE_CHRDEV; + } + else if (S_ISBLK(mode)) + { + filetype = EXT4_DE_BLKDEV; + } + else if (S_ISFIFO(mode)) + { + filetype = EXT4_DE_FIFO; + } + else if (S_ISSOCK(mode)) + { + filetype = EXT4_DE_SOCK; + } + + ret = ext4_mknod(fn, filetype, 0); + } + } + + if (ret != EOK) + { + rt_free(ext_file); + ext_file = NULL; + + dfs_vnode_destroy(vnode); + vnode = NULL; + } + else + { + DLOG(msg, "ext", "mnt", DLOG_MSG, "dfs_mnt_ref(dentry->mnt, name=%s)", dentry->mnt->fs_ops->name); + vnode->mnt = dentry->mnt; + vnode->data = (void *)ext_file; + vnode->mode = mode; + ext_file->type = filetype; + rt_mutex_init(&vnode->lock, dentry->pathname, RT_IPC_FLAG_PRIO); + } + } + + rt_free(fn); + fn = NULL; + } + else + { + dfs_vnode_destroy(vnode); + vnode = NULL; + } + } + + return vnode; +} + +static int dfs_ext_free_vnode(struct dfs_vnode *vnode) +{ + if (vnode) + { + struct dfs_ext4_file *ext_file = (struct dfs_ext4_file *)vnode->data; + if (ext_file) + { + if (ext_file->vnode.mp) + { + ext4_put_inode_ref(ext_file->vnode.mp, &(ext_file->vnode.inode_ref)); + } + rt_mutex_detach(&vnode->lock); + rt_free(ext_file); + vnode->data = RT_NULL; + } } - return fn; + return RT_EOK; } -static int dfs_ext_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data) +static int dfs_ext_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void *data) { int rc = 0; struct ext4_blockdev *bd = NULL; struct dfs_ext4_blockdev *dbd = NULL; /* create dfs ext4 block device */ - dbd = dfs_ext4_blockdev_create(fs->dev_id); - if (!dbd) return -RT_ERROR; + dbd = dfs_ext4_blockdev_create(mnt->dev_id); + if (!dbd) return RT_NULL; bd = &dbd->bd; - rc = ext4_mount(bd, fs->path, false); - if (rc != RT_EOK) + rc = ext4_mount(bd, mnt->fullpath, false); + if (rc != EOK) { dfs_ext4_blockdev_destroy(dbd); rc = -rc; } else { - ext4_mount_setup_locks(fs->path, &ext4_lock_ops); + ext4_mount_setup_locks(mnt->fullpath, &ext4_lock_ops); /* set file system data to dbd */ - fs->data = (void*)dbd; + dbd->data = bd->journal; + bd->journal = 0; + mnt->data = (void *)dbd; } return rc; } -static int dfs_ext_unmount(struct dfs_filesystem *fs) +static int dfs_ext_unmount(struct dfs_mnt *mnt) { - int rc = -RT_ERROR; + int rc = EPERM; struct dfs_ext4_blockdev *dbd = NULL; - dbd = (struct dfs_ext4_blockdev *)fs->data; + dbd = (struct dfs_ext4_blockdev *)mnt->data; if (dbd) { - char *mp = fs->path; /*mount point */ - - rc = ext4_umount(mp); + rc = ext4_umount_mp(dbd->data); if (rc == 0) { dfs_ext4_blockdev_destroy(dbd); - } - else - { - rc = -rc; + mnt->data = NULL; } } - else - { - rc = -RT_EINVAL; - } + return rc; } @@ -171,365 +424,493 @@ static int dfs_ext_mkfs(rt_device_t devid, const char *fs_name) return rc; } -static int dfs_ext_statfs(struct dfs_filesystem *fs, struct statfs *buf) +static int dfs_ext_statfs(struct dfs_mnt *mnt, struct statfs *buf) { struct ext4_sblock *sb = NULL; int error = RT_EOK; - error = ext4_get_sblock(fs->path, &sb); - if (error != RT_EOK) + if (mnt) { - return -error; + error = ext4_get_sblock(mnt->fullpath, &sb); + if (error != RT_EOK) + { + return -error; + } + + buf->f_bsize = ext4_sb_get_block_size(sb); + buf->f_blocks = ext4_sb_get_blocks_cnt(sb); + buf->f_bfree = ext4_sb_get_free_blocks_cnt(sb); + //TODO this is not accurate, because it is free blocks available to unprivileged user, but ... + buf->f_bavail = buf->f_bfree; } - buf->f_bsize = ext4_sb_get_block_size(sb); - buf->f_blocks = ext4_sb_get_blocks_cnt(sb); - buf->f_bfree = ext4_sb_get_free_blocks_cnt(sb); - //TODO this is not accurate, because it is free blocks available to unprivileged user, but ... - buf->f_bavail = buf->f_bfree; return error; - } -static int dfs_ext_ioctl(struct dfs_file *fd, int cmd, void *args) -{ - int r = RT_EOK; - switch (cmd) - { - case RT_FIOFTRUNCATE: - { - ext4_file *file = fd->data; - uint64_t fpos, length; - RT_ASSERT(file != RT_NULL); - fpos = file->fpos; - length = *(uint64_t *)args; - if (length <= ext4_fsize(file)) - { - file->fpos = length; - r = ext4_ftruncate(file, length); - } - else - { - r = ext4_fseek(file, (int64_t)length, SEEK_SET); - } - file->fpos = fpos; - return r; - } - case F_GETLK: - return 0; - case F_SETLK: - return 0; - } - return -RT_EIO; -} +/* file ops */ -static int dfs_ext_read(struct dfs_file *fd, void *buf, size_t count) +static ssize_t dfs_ext_read(struct dfs_file *file, void *buf, size_t count, off_t *pos) { - size_t bytesread = 0; - ext4_file *file = fd->data; int r; + size_t bytesread = 0; + struct dfs_ext4_file *ext_file; - RT_ASSERT(file != RT_NULL); - r = ext4_fread(file, buf, count, &bytesread); - if (r != 0) + if (file && file->data && file->vnode->size > *pos) { - bytesread = 0; + ext_file = (struct dfs_ext4_file *)file->data; + if (ext_file->vnode.mp) + { + rt_mutex_take(&file->vnode->lock, RT_WAITING_FOREVER); + dfs_ext_lseek(file, *pos, SEEK_SET); + r = ext4_fread(&ext_file->entry.file, buf, count, &bytesread); + if (r != 0) + { + bytesread = 0; + } + *pos = ext_file->entry.file.fpos; + rt_mutex_release(&file->vnode->lock); + } } -#if (RTTHREAD_VERSION >= RT_VERSION_CHECK(5, 0, 0)) - fd->pos = file->fpos; -#endif return bytesread; } -static int dfs_ext_write(struct dfs_file *fd, const void *buf, size_t count) +static ssize_t dfs_ext_write(struct dfs_file *file, const void *buf, size_t count, off_t *pos) { - size_t byteswritten = 0; - ext4_file *file = fd->data; int r; + size_t byteswritten = 0; + struct dfs_ext4_file *ext_file; - RT_ASSERT(file != RT_NULL); - r = ext4_fwrite(file, buf, count, &byteswritten); - if (r != 0) + if (file && file->data) { - byteswritten = 0; - } + ext_file = (struct dfs_ext4_file *)file->data; + if (ext_file->vnode.mp) + { + rt_mutex_take(&file->vnode->lock, RT_WAITING_FOREVER); + dfs_ext_lseek(file, *pos, SEEK_SET); + r = ext4_fwrite(&(ext_file->entry.file), buf, count, &byteswritten); + if (r != 0) + { + byteswritten = 0; + } -#if (RTTHREAD_VERSION >= RT_VERSION_CHECK(5, 0, 0)) - fd->pos = file->fpos; - fd->vnode->size = ext4_fsize(file); -#endif + file->vnode->size = ext4_fsize(&(ext_file->entry.file)); + *pos = ext_file->entry.file.fpos; + rt_mutex_release(&file->vnode->lock); + } + } return byteswritten; } -static int dfs_ext_flush(struct dfs_file *fd) +static int dfs_ext_flush(struct dfs_file *file) { + char *fn = RT_NULL; int error = RT_EOK; - error = ext4_cache_flush(get_fd_file(fd)); + if (file && file->dentry) + { + fn = dfs_dentry_full_path(file->dentry); + if (fn) + { + error = ext4_cache_flush(fn); + + rt_free(fn); + } + } + if (error != RT_EOK) { - return -error; + error = -error; } return error; } -static int dfs_ext_lseek(struct dfs_file *fd, off_t offset) +static off_t dfs_ext_lseek(struct dfs_file *file, off_t offset, int whence) { - int r; - ext4_file *file = fd->data; + off_t ret = -EPERM; + struct dfs_ext4_file *ext_file; - r = ext4_fseek(file, (int64_t)offset, SEEK_SET); - if (r == RT_EOK) + if (file && file->data) { - return file->fpos; + ext_file = (struct dfs_ext4_file *)file->data; + rt_mutex_take(&file->vnode->lock, RT_WAITING_FOREVER); + if (ext_file->type == EXT4_DE_DIR) + { + if (offset == 0) + { + ext4_dir_entry_rewind(&(ext_file->entry.dir)); + ret = 0; + } + } + else if (ext_file->type == EXT4_DE_REG_FILE) + { + ret = generic_dfs_lseek(file, offset, whence); + if (ret >= 0) + { + ext_file->entry.file.fpos = ret; + } + } + rt_mutex_release(&file->vnode->lock); } - return -r; + return ret; } static int dfs_ext_close(struct dfs_file *file) { - int r; + int ret = 0; + struct dfs_ext4_file *ext_file = RT_NULL; - r = ext4_fclose(file->data); - if (r == EOK) + if (file) { - rt_free(file->data); - file->data = NULL; + RT_ASSERT(file->vnode->ref_count > 0); + if (file->vnode->ref_count > 1) + { + return ret; + } + ext_file = (struct dfs_ext4_file *)file->data; + if (ext_file) + { + if (ext_file->type == EXT4_DE_DIR) + { + ret = ext4_dir_close(&ext_file->entry.dir); + } + else if (ext_file->type == EXT4_DE_REG_FILE) + { + ret = ext4_fclose(&ext_file->entry.file); + } + + if (ret == EOK) + { + ext_file->type = EXT4_DE_UNKNOWN; + file->data = NULL; + } + } } - return -r; + return -ret; } static int dfs_ext_open(struct dfs_file *file) { - int r = EOK; - ext4_dir *dir; - ext4_file *f; + int ret = EOK; + struct dfs_ext4_file *ext_file = RT_NULL; - if (file->flags & O_DIRECTORY) + if (file && file->vnode) { - if (file->flags & O_CREAT) + ext_file = (struct dfs_ext4_file *)file->vnode->data; + + RT_ASSERT(file->vnode->ref_count > 0); + if (ext_file && ext_file->type != EXT4_DE_UNKNOWN) { - r = ext4_dir_mk(get_fd_file(file)); + if (file->vnode->type == FT_DIRECTORY + && !(file->flags & O_DIRECTORY)) + { + return -ENOENT; + } + if (file->vnode->type == FT_DIRECTORY) + { + file->data = rt_calloc(1, sizeof(struct dfs_ext4_file)); + rt_memcpy(file->data, ext_file, sizeof(struct dfs_ext4_file)); + ext_file = (struct dfs_ext4_file *)file->data; + ext_file->entry.dir.next_off = 0; + } + else + { + file->data = ext_file; + } + + file->fpos = 0; + return ret; } - if (EOK == r) + + if (ext_file) { - dir = rt_calloc(1, sizeof(ext4_dir)); - if (dir) + char *fn = NULL; + + fn = dfs_dentry_full_path(file->dentry); + if (fn) { - r = ext4_dir_open(dir, get_fd_file(file)); - if (r == EOK) + if (file->vnode->type == FT_DIRECTORY) { - file->data = dir; + /* open dir */ + ret = ext4_dir_open(&ext_file->entry.dir, fn); + if (ret == EOK) + { + ext_file->type = EXT4_DE_DIR; + file->fpos = 0; + } } else { - rt_free(dir); + /* open regular file */ + ret = ext4_fopen2(&ext_file->entry.file, fn, file->flags); + if (ret == EOK) + { + ext_file->type = EXT4_DE_REG_FILE; + if (file->flags & O_TRUNC) + { + file->vnode->size = 0; + } + file->fpos = ext_file->entry.file.fpos; + } } + + if (ret == EOK) + { + file->data = ext_file; + } + + rt_free(fn); } } } else { - f = rt_calloc(1, sizeof(ext4_file)); - if (f) + ret = ENOENT; + } + + return -ret; +} + +static int dfs_ext_readlink(struct dfs_dentry *dentry, char *buf, int len) +{ + int ret = EOK; + char *fn = NULL; + + if (dentry && buf) + { + fn = dfs_dentry_full_path(dentry); + if (fn) { - r = ext4_fopen2(f, get_fd_file(file), file->flags); - if (r == EOK) - { - file->data = f; -#if (RTTHREAD_VERSION >= RT_VERSION_CHECK(5, 0, 0)) - file->vnode->flags = f->flags; - file->pos = f->fpos; - file->vnode->size = (size_t)f->fsize; -#endif - } - else + size_t size; + ret = ext4_readlink(fn, buf, len, &size); + rt_free(fn); + if (ret == EOK) { - rt_free(f); + buf[size] = '\0'; + return size; } } + else + { + ret = ENOMEM; + } } - return -r; + else + { + ret = EBADF; + } + + return -ret; } -static int dfs_ext_unlink(struct dfs_filesystem *fs, const char *pathname) +static int dfs_ext_link(struct dfs_dentry *src_dentry, struct dfs_dentry *dst_dentry) { - int r; - char *stat_path; + char *src_path = NULL, *dst_path = NULL; - union - { - ext4_dir dir; - ext4_file f; - } var; + src_path = dfs_dentry_full_path(src_dentry); + dst_path = dfs_dentry_full_path(dst_dentry); - if (fs->ops->flags & DFS_FS_FLAG_FULLPATH) + if (src_path && dst_path) { - stat_path = (char *)pathname; + ext4_flink(src_path, dst_path); + + rt_free(src_path); + rt_free(dst_path); } - else + + return EOK; +} + +static int dfs_ext_symlink(struct dfs_dentry *parent_dentry, const char *target, const char *linkpath) +{ + int ret = EOK; + char *fn = NULL; + + if (parent_dentry && linkpath[0] != '/') { - if (strlen(fs->path) != 1) + char *full = dfs_dentry_full_path(parent_dentry); + if (full) { - stat_path = malloc(strlen(fs->path) + strlen(pathname) + 1); - snprintf((char *)stat_path, strlen(fs->path) + strlen(pathname) + 1, "%s%s", fs->path, pathname); - } - else - { - stat_path = (char *)pathname; + fn = dfs_normalize_path(full, linkpath); + rt_free(full); } } - - r = ext4_dir_open(&(var.dir), stat_path); - if (r == 0) + else { - (void) ext4_dir_close(&(var.dir)); - ext4_dir_rm(stat_path); + fn = (char *)linkpath; + } + if (fn) + { + ret = ext4_fsymlink(target, fn); + if (fn != linkpath) + rt_free(fn); } else { - r = ext4_fremove(stat_path); + ret = ENOMEM; } - return -r; + return -ret; } -static int dfs_ext_stat(struct dfs_filesystem *fs, const char *path, struct stat *st) +static int dfs_ext_unlink(struct dfs_dentry *dentry) { - int r; - uint32_t mode = 0; - uint32_t uid; - uint32_t gid; - uint32_t atime; - uint32_t mtime; - uint32_t ctime; - char *stat_path; - struct ext4_inode inode; - uint32_t ino = 0; - uint32_t dev = 0; - - union - { - ext4_dir dir; - ext4_file f; - } var; + int ret = EPERM; + char *fn = NULL; + struct dfs_ext4_file file; - if (fs->ops->flags & DFS_FS_FLAG_FULLPATH) + fn = dfs_dentry_full_path(dentry); + if (fn) { - stat_path = (char *)path; - } - else - { - if (strlen(fs->path) != 1) + ret = ext4_dir_open(&(file.entry.dir), fn); + if (ret == 0) { - stat_path = malloc(strlen(fs->path) + strlen(path) + 1); - snprintf((char *)stat_path, strlen(fs->path) + strlen(path) + 1, "%s%s", fs->path, path); + ext4_dir_close(&(file.entry.dir)); + ret = ext4_dir_rm(fn); } else { - stat_path = (char *)path; + ret = ext4_fremove(fn); } + + rt_free(fn); } - r = ext4_dir_open(&(var.dir), stat_path); - if (r == 0) - { - (void) ext4_dir_close(&(var.dir)); - ext4_mode_get(stat_path, &mode); - ext4_owner_get(stat_path, &uid, &gid); - ext4_atime_get(stat_path, &atime); - ext4_mtime_get(stat_path, &mtime); - ext4_ctime_get(stat_path, &ctime); + return -ret; +} - if (ext4_raw_inode_fill(stat_path, &ino, &inode) == EOK) - { - dev = ext4_inode_get_dev(&inode); - } - st->st_dev = (dev_t)(fs->dev_id); - st->st_ino = ino; - st->st_mode = mode; - st->st_size = var.dir.f.fsize; - st->st_uid = uid; - st->st_gid = gid; - st->st_atime = atime; - st->st_mtime = mtime; - st->st_ctime = ctime; - } - else +static int dfs_ext_stat(struct dfs_dentry *dentry, struct stat *st) +{ + int ret = 0; + char *stat_path; + + stat_path = dfs_dentry_full_path(dentry); + if (stat_path) { - r = ext4_fopen(&(var.f), stat_path, "rb"); - if (r == 0) + struct ext4_inode_ref inode_ref; + struct ext4_mountpoint *mp = ext4_get_inode_ref(stat_path, &inode_ref); + + if (mp) { - ext4_mode_get(stat_path, &mode); - ext4_owner_get(stat_path, &uid, &gid); - ext4_atime_get(stat_path, &atime); - ext4_mtime_get(stat_path, &mtime); - ext4_ctime_get(stat_path, &ctime); - if (ext4_raw_inode_fill(stat_path, &ino, &inode) == EOK) + st->st_mode = ext4_inode_get_mode(&mp->fs.sb, inode_ref.inode); + st->st_uid = ext4_inode_get_uid(inode_ref.inode); + st->st_gid = ext4_inode_get_gid(inode_ref.inode); + if (S_ISDIR(st->st_mode)) + { + st->st_size = ext4_inode_get_size(&mp->fs.sb, inode_ref.inode); + } + else { - dev = ext4_inode_get_dev(&inode); +#ifdef RT_USING_PAGECACHE + st->st_size = (dentry->vnode && dentry->vnode->aspace) ? dentry->vnode->size : ext4_inode_get_size(&mp->fs.sb, inode_ref.inode); +#else + st->st_size = ext4_inode_get_size(&mp->fs.sb, inode_ref.inode); +#endif } - st->st_dev = (dev_t)(fs->dev_id); - st->st_ino = ino; - st->st_mode = mode; - st->st_size = ext4_fsize(&(var.f)); - st->st_uid = uid; - st->st_gid = gid; - st->st_atime = atime; - st->st_mtime = mtime; - st->st_ctime = ctime; + st->st_atime = ext4_inode_get_access_time(inode_ref.inode); + st->st_mtime = ext4_inode_get_modif_time(inode_ref.inode); + st->st_ctime = ext4_inode_get_change_inode_time(inode_ref.inode); + + st->st_dev = (dev_t)(dentry->mnt->dev_id); + st->st_ino = inode_ref.index; - (void)ext4_fclose(&(var.f)); + st->st_blksize = ext4_sb_get_block_size(&mp->fs.sb); + // man say st_blocks is number of 512B blocks allocated + st->st_blocks = RT_ALIGN(st->st_size, st->st_blksize) / 512; + + ext4_put_inode_ref(mp, &inode_ref); } + else + { + ret = ENOENT; + } + + rt_free(stat_path); } - if (r == 0) + return -ret; +} + +int dfs_ext_setattr(struct dfs_dentry *dentry, struct dfs_attr *attr) +{ + int ret = 0; + char *fn = NULL; + + fn = dfs_dentry_full_path(dentry); + if (fn) { - struct ext4_mount_stats s; - r = ext4_mount_point_stats(stat_path, &s); - if (r == 0) + if (attr->ia_valid & ATTR_MODE_SET) { - st->st_blksize = s.block_size; - // man say st_blocks is number of 512B blocks allocated - st->st_blocks = RT_ALIGN(st->st_size, st->st_blksize) / 512; + ret = ext4_mode_set(fn, attr->st_mode); + } + if (attr->ia_valid & ATTR_ATIME_SET) + { + ret = ext4_atime_set(fn, attr->ia_atime.tv_sec); } + if (attr->ia_valid & ATTR_MTIME_SET) + { + ret = ext4_mtime_set(fn, attr->ia_mtime.tv_sec); + } + if (attr->ia_valid & ATTR_UID_SET) + { + uint32_t unuse = 0, gid = 0; + ext4_owner_get(fn, &unuse, &gid); + ret = ext4_owner_set(fn, attr->st_uid, gid); + } + if (attr->ia_valid & ATTR_GID_SET) + { + uint32_t unuse = 0, uid = 0; + ext4_owner_get(fn, &uid, &unuse); + ret = ext4_owner_set(fn, uid, attr->st_gid); + } + ext4_vnode_update_info(dentry->vnode); + rt_free(fn); + } + else + { + ret = ENOENT; } - return -r; + return ret; } static int dfs_ext_getdents(struct dfs_file *file, struct dirent *dirp, rt_uint32_t count) { int index; struct dirent *d; + struct dfs_ext4_file *ext_file; const ext4_direntry *rentry; /* make integer count */ count = (count / sizeof(struct dirent)) * sizeof(struct dirent); - if (count == 0) + if (count == 0 || file->data == RT_NULL) { return -RT_EINVAL; } index = 0; + ext_file = (struct dfs_ext4_file *)file->data; while (1) { d = dirp + index; - rentry = ext4_dir_entry_next(file->data); - if (NULL != rentry) + rentry = ext4_dir_entry_next(&(ext_file->entry.dir)); + if (rentry != NULL) { - strncpy(d->d_name, (char *)rentry->name, DFS_PATH_MAX); - if (EXT4_DE_DIR == rentry->inode_type) + strncpy(d->d_name, (char *)rentry->name, DIRENT_NAME_MAX); + if (rentry->inode_type == EXT4_DE_DIR) { d->d_type = DT_DIR; } + else if (rentry->inode_type == EXT4_DE_SYMLINK) + { + d->d_type = DT_SYMLINK; + } else { d->d_type = DT_REG; @@ -547,46 +928,162 @@ static int dfs_ext_getdents(struct dfs_file *file, struct dirent *dirp, rt_uint3 } } - file->pos += index * sizeof(struct dirent); + file->fpos += index * sizeof(struct dirent); return index * sizeof(struct dirent); } -static int dfs_ext_rename(struct dfs_filesystem *fs, const char *oldpath, const char *newpath) +static int dfs_ext_rename(struct dfs_dentry *old_dentry, struct dfs_dentry *new_dentry) { - int r; + int r = EPERM; + char *oldpath, *newpath; + + oldpath = dfs_dentry_full_path(old_dentry); + newpath = dfs_dentry_full_path(new_dentry); + + if (oldpath && newpath) + { + r = ext4_frename(oldpath, newpath); + } - r = ext4_frename(oldpath, newpath); + rt_free(oldpath); + rt_free(newpath); return -r; } -static const struct dfs_file_ops _ext_fops = +static int dfs_ext_truncate(struct dfs_file *file, off_t offset) { - dfs_ext_open, - dfs_ext_close, - dfs_ext_ioctl, - dfs_ext_read, - dfs_ext_write, - dfs_ext_flush, - dfs_ext_lseek, - dfs_ext_getdents, -}; + struct dfs_ext4_file *ext_file = (struct dfs_ext4_file *)file->data; + + if (ext_file) + { + ext4_ftruncate(&(ext_file->entry.file), offset); + } + + if (file->vnode->size < offset) + { + file->vnode->size = offset; + } + + return 0; +} -static const struct dfs_filesystem_ops _ext_fs = +static int dfs_ext_ioctl(struct dfs_file *file, int cmd, void *args) { - "ext", - DFS_FS_FLAG_DEFAULT, - &_ext_fops, + int ret = RT_EOK; - dfs_ext_mount, - dfs_ext_unmount, - dfs_ext_mkfs, - dfs_ext_statfs, /* statfs */ + switch (cmd) + { + case RT_FIOFTRUNCATE: + { + off_t offset = (off_t)(size_t)(args); + ret = dfs_ext_truncate(file, offset); + } + break; + + case F_GETLK: + case F_SETLK: + ret = RT_EOK; + break; + + default: + ret = -RT_EIO; + break; + } + + return ret; +} + +#ifdef RT_USING_PAGECACHE +static ssize_t dfs_ext_page_read(struct dfs_file *file, struct dfs_page *page) +{ + ssize_t ret = -EINVAL; + + if (page->page) + { + uint32_t flags; + off_t fpos = page->fpos; + + if (file && file->data) + { + struct dfs_ext4_file *ext_file = (struct dfs_ext4_file *)file->data; + + rt_mutex_take(&file->vnode->lock, RT_WAITING_FOREVER); + flags = ext_file->entry.file.flags; + ext_file->entry.file.flags = O_RDWR; + ret = dfs_ext_read(file, page->page, page->size, &fpos); + ext_file->entry.file.flags = flags; + rt_mutex_release(&file->vnode->lock); + } + } - dfs_ext_unlink, - dfs_ext_stat, - dfs_ext_rename + return ret; +} + +static ssize_t dfs_ext_page_write(struct dfs_page *page) +{ + int r; + size_t byteswritten = 0; + struct dfs_ext4_file *ext_file; + + if (page && page->aspace->vnode && page->aspace->vnode->data) + { + ext_file = (struct dfs_ext4_file *)page->aspace->vnode->data; + rt_mutex_take(&page->aspace->vnode->lock, RT_WAITING_FOREVER); + ext4_fseek(&(ext_file->entry.file), (int64_t)page->fpos, SEEK_SET); + r = ext4_fwrite(&(ext_file->entry.file), page->page, page->len, &byteswritten); + if (r != 0) + { + byteswritten = 0; + } + rt_mutex_release(&page->aspace->vnode->lock); + } + + return byteswritten; +} +#endif + +static const struct dfs_file_ops _extfs_fops = +{ + .open = dfs_ext_open, + .close = dfs_ext_close, + .ioctl = dfs_ext_ioctl, + .read = dfs_ext_read, + .write = dfs_ext_write, + .flush = dfs_ext_flush, + .lseek = dfs_ext_lseek, + .truncate = dfs_ext_truncate, + .getdents = dfs_ext_getdents, +}; + +static const struct dfs_filesystem_ops _extfs_ops = +{ + .name = "ext", + .flags = FS_NEED_DEVICE, + .default_fops = &_extfs_fops, + + .mount = dfs_ext_mount, + .umount = dfs_ext_unmount, + .mkfs = dfs_ext_mkfs, + .statfs = dfs_ext_statfs, /* statfs */ + + .readlink = dfs_ext_readlink, + .link = dfs_ext_link, + .unlink = dfs_ext_unlink, + .symlink = dfs_ext_symlink, + .stat = dfs_ext_stat, + .setattr = dfs_ext_setattr, + .rename = dfs_ext_rename, + + .lookup = dfs_ext_lookup, + .create_vnode = dfs_ext_create_vnode, + .free_vnode = dfs_ext_free_vnode, +}; + +static struct dfs_filesystem_type _extfs = +{ + .fs_ops = &_extfs_ops, }; int dfs_ext_init(void) @@ -602,7 +1099,7 @@ int dfs_ext_init(void) } /* register rom file system */ - dfs_register(&_ext_fs); + dfs_register(&_extfs); return 0; } INIT_COMPONENT_EXPORT(dfs_ext_init); diff --git a/ports/rtthread/dfs_ext_blockdev.h b/ports/rtthread/dfs_ext_blockdev.h index 2af0441..99d97f5 100644 --- a/ports/rtthread/dfs_ext_blockdev.h +++ b/ports/rtthread/dfs_ext_blockdev.h @@ -18,6 +18,7 @@ struct dfs_ext4_blockdev rt_device_t devid; struct ext4_blockdev bd; uint8_t ph_bbuf[4096]; + void *data; }; struct ext4_blockdev *ext4_blockdev_from_devid(struct rt_device *devid); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3b82fcf..257b8cc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,6 +17,6 @@ else() endif() if (DEFINED INSTALL_LIB) -INSTALL(TARGETS lwext4 DESTINATION /usr/local/lib) -INSTALL(DIRECTORY ${PROJECT_BINARY_DIR}/include/. DESTINATION /usr/local/include/lwext4) -endif() \ No newline at end of file +INSTALL(TARGETS lwext4 DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) +INSTALL(DIRECTORY ${PROJECT_BINARY_DIR}/include/. DESTINATION ${CMAKE_INSTALL_PREFIX}/include/lwext4) +endif() diff --git a/src/ext4.c b/src/ext4.c index ac5421b..0e17327 100644 --- a/src/ext4.c +++ b/src/ext4.c @@ -53,49 +53,11 @@ #include #include +#include "ext4_mp.h" #include #include -/**@brief Mount point OS dependent lock*/ -#define EXT4_MP_LOCK(_m) \ - do { \ - if ((_m)->os_locks) \ - (_m)->os_locks->lock(); \ - } while (0) - -/**@brief Mount point OS dependent unlock*/ -#define EXT4_MP_UNLOCK(_m) \ - do { \ - if ((_m)->os_locks) \ - (_m)->os_locks->unlock(); \ - } while (0) - -/**@brief Mount point descriptor.*/ -struct ext4_mountpoint { - - /**@brief Mount done flag.*/ - bool mounted; - - /**@brief Mount point name (@ref ext4_mount)*/ - char name[CONFIG_EXT4_MAX_MP_NAME + 1]; - - /**@brief OS dependent lock/unlock functions.*/ - const struct ext4_lock *os_locks; - - /**@brief Ext4 filesystem internals.*/ - struct ext4_fs fs; - - /**@brief JBD fs.*/ - struct jbd_fs jbd_fs; - - /**@brief Journal.*/ - struct jbd_journal jbd_journal; - - /**@brief Block cache.*/ - struct ext4_bcache bc; -}; - /**@brief Mountpoints.*/ static struct ext4_mountpoint s_mp[CONFIG_EXT4_MOUNTPOINTS_COUNT]; @@ -323,8 +285,8 @@ int ext4_mount(struct ext4_blockdev *bd, const char *mount_point, break; } - if (!strcmp(s_mp[i].name, mount_point)) - return EOK; + /*if (!strcmp(s_mp[i].name, mount_point)) + return EOK;*/ } if (!mp) @@ -364,9 +326,39 @@ int ext4_mount(struct ext4_blockdev *bd, const char *mount_point, bd->fs = &mp->fs; mp->mounted = 1; + bd->journal = (void *)mp; + + ext4_cache_write_back(mp->name, true); + return r; } +int ext4_umount_mp(struct ext4_mountpoint *mp) +{ + int ret = ENODEV; + + if (mp && mp->mounted) + { + ext4_cache_write_back(mp->name, false); + + ret = ext4_fs_fini(&mp->fs); + if (ret == EOK) + { + mp->mounted = 0; + + ext4_bcache_cleanup(mp->fs.bdev->bc); + ext4_bcache_fini_dynamic(mp->fs.bdev->bc); + + ret = ext4_block_fini(mp->fs.bdev); + } + + mp->fs.bdev->fs = NULL; + memset(mp, 0, sizeof(struct ext4_mountpoint)); + } + + return ret; +} + int ext4_umount(const char *mount_point) { int i; @@ -383,19 +375,8 @@ int ext4_umount(const char *mount_point) if (!mp) return ENODEV; - r = ext4_fs_fini(&mp->fs); - if (r != EOK) - goto Finish; - - mp->mounted = 0; + r = ext4_umount_mp(mp); - ext4_bcache_cleanup(mp->fs.bdev->bc); - ext4_bcache_fini_dynamic(mp->fs.bdev->bc); - - r = ext4_block_fini(mp->fs.bdev); -Finish: - mp->fs.bdev->fs = NULL; - memset(mp, 0, sizeof(struct ext4_mountpoint)); return r; } @@ -890,14 +871,16 @@ static int ext4_generic_open2(ext4_file *f, const char *path, int flags, f->flags = flags; /*Skip mount point*/ - path += strlen(mp->name); + len = strlen(mp->name); + path += len; if (path[0] == '/') { path += 1; + len += 1; } if (name_off) - *name_off = strlen(mp->name); + *name_off = len; /*Load root*/ r = ext4_fs_get_inode_ref(fs, EXT4_INODE_ROOT_INDEX, &ref); @@ -1542,6 +1525,10 @@ int ext4_fclose(ext4_file *file) { ext4_assert(file && file->mp); + EXT4_MP_LOCK(file->mp); + ext4_block_cache_flush(file->mp->fs.bdev); + EXT4_MP_UNLOCK(file->mp); + file->mp = 0; file->flags = 0; file->inode = 0; @@ -1694,7 +1681,7 @@ int ext4_fread(ext4_file *file, void *buf, size_t size, size_t *rcnt) r = ext4_fs_get_inode_dblk_idx(&ref, iblock_idx, &fblock, true); if (r != EOK) goto Finish; - + /* Do we get an unwritten range? */ if (fblock != 0) { uint64_t off = fblock * block_size + unalg; @@ -1737,8 +1724,14 @@ int ext4_fread(ext4_file *file, void *buf, size_t size, size_t *rcnt) fblock_count++; } - r = ext4_blocks_get_direct(file->mp->fs.bdev, u8_buf, fblock_start, + if (fblock_start == 0) { + memset(u8_buf, 0, block_size * fblock_count); + r = EOK; + } else { + r = ext4_blocks_get_direct(file->mp->fs.bdev, u8_buf, fblock_start, fblock_count); + } + if (r != EOK) goto Finish; @@ -1769,7 +1762,7 @@ int ext4_fread(ext4_file *file, void *buf, size_t size, size_t *rcnt) if (rcnt) *rcnt += size; } - + Finish: ext4_fs_put_inode_ref(&ref); @@ -1822,6 +1815,11 @@ int ext4_fwrite(ext4_file *file, const void *buf, size_t size, size_t *wcnt) /*Sync file size*/ file->fsize = ext4_inode_get_size(sb, ref.inode); + if (file->fpos > file->fsize) { + file->fsize = file->fpos; + ext4_inode_set_size(ref.inode, file->fsize); + ref.dirty = true; + } block_size = ext4_sb_get_block_size(sb); iblock_last = (uint32_t)((file->fpos + size) / block_size); @@ -1967,29 +1965,30 @@ int ext4_fwrite(ext4_file *file, const void *buf, size_t size, size_t *wcnt) int ext4_fseek(ext4_file *file, int64_t offset, uint32_t origin) { + int ret = EOK; + off_t new_offset = 0; + switch (origin) { case SEEK_SET: - if (offset < 0) - return EINVAL; + new_offset = offset; + break; - file->fpos = offset; - return EOK; case SEEK_CUR: - if ((offset < 0 && (uint64_t)(-offset) > file->fpos) || - (offset > 0 && - (uint64_t)offset > (file->fsize - file->fpos))) - return EINVAL; + new_offset = file->fpos + offset; + break; - file->fpos += offset; - return EOK; case SEEK_END: - if (offset < 0 || (uint64_t)offset > file->fsize) - return EINVAL; + new_offset = file->fsize + offset; + break; + } - file->fpos = file->fsize - offset; - return EOK; + if (new_offset < 0) ret = EINVAL; + else + { + file->fpos = new_offset; } - return EINVAL; + + return ret; } uint64_t ext4_ftell(ext4_file *file) @@ -2022,6 +2021,8 @@ static int ext4_trans_get_inode_ref(const char *path, return r; } + ext4_bcache_inc_read_ref(inode_ref->block.buf); + return r; } @@ -2030,6 +2031,7 @@ static int ext4_trans_put_inode_ref(struct ext4_mountpoint *mp, { int r; + ext4_bcache_dec_read_ref(inode_ref->block.buf); r = ext4_fs_put_inode_ref(inode_ref); if (r != EOK) ext4_trans_abort(mp); @@ -2092,6 +2094,34 @@ int ext4_inode_exist(const char *path, int type) return r; } +void* ext4_get_inode_ref(const char *path, struct ext4_inode_ref *ref) +{ + int ret; + struct ext4_mountpoint *mp = ext4_get_mount(path); + + if (!mp) + return NULL; + + EXT4_MP_LOCK(mp); + ret = ext4_trans_get_inode_ref(path, mp, ref); + EXT4_MP_UNLOCK(mp); + + if (ret != EOK) mp = NULL; + + return mp; +} + +int ext4_put_inode_ref(struct ext4_mountpoint *mp, struct ext4_inode_ref *ref) +{ + int ret = EOK; + + EXT4_MP_LOCK(mp); + ret = ext4_trans_put_inode_ref(mp, ref); + EXT4_MP_UNLOCK(mp); + + return ret; +} + int ext4_mode_set(const char *path, uint32_t mode) { int r; diff --git a/src/ext4_balloc.c b/src/ext4_balloc.c index b02576f..1b561ac 100644 --- a/src/ext4_balloc.c +++ b/src/ext4_balloc.c @@ -54,7 +54,7 @@ #include /**@brief Compute number of block group from block address. - * @param sb superblock pointer. + * @param s superblock pointer. * @param baddr Absolute address of block. * @return Block group index */ @@ -68,7 +68,7 @@ uint32_t ext4_balloc_get_bgid_of_block(struct ext4_sblock *s, } /**@brief Compute the starting block address of a block group - * @param sb superblock pointer. + * @param s superblock pointer. * @param bgid block group index * @return Block address */ diff --git a/src/ext4_bcache.c b/src/ext4_bcache.c index af7f19c..bdf92e4 100644 --- a/src/ext4_bcache.c +++ b/src/ext4_bcache.c @@ -285,6 +285,21 @@ int ext4_bcache_free(struct ext4_bcache *bc, struct ext4_block *b) /*Just decrease reference counter*/ ext4_bcache_dec_ref(buf); + if (buf->refctr && buf->refctr == buf->read_refctr) { + /* This buffer is ready to be flushed. */ + if (ext4_bcache_test_flag(buf, BC_DIRTY) && + ext4_bcache_test_flag(buf, BC_UPTODATE)) { + if (bc->bdev->cache_write_back && + !ext4_bcache_test_flag(buf, BC_FLUSH) && + !ext4_bcache_test_flag(buf, BC_TMP)) + ext4_bcache_insert_dirty_node(bc, buf); + else { + ext4_block_flush_buf(bc->bdev, buf); + ext4_bcache_clear_flag(buf, BC_FLUSH); + } + } + } + /* We are the last one touching this buffer, do the cleanups. */ if (!buf->refctr) { RB_INSERT(ext4_buf_lru, &bc->lru_root, buf); diff --git a/src/ext4_dir_idx.c b/src/ext4_dir_idx.c index e3eac01..0534a07 100644 --- a/src/ext4_dir_idx.c +++ b/src/ext4_dir_idx.c @@ -54,7 +54,7 @@ #include /**@brief Get hash version used in directory index. - * @param root_info Pointer to root info structure of index + * @param ri Pointer to root info structure of index * @return Hash algorithm version */ static inline uint8_t @@ -64,7 +64,7 @@ ext4_dir_dx_rinfo_get_hash_version(struct ext4_dir_idx_rinfo *ri) } /**@brief Set hash version, that will be used in directory index. - * @param root_info Pointer to root info structure of index + * @param ri Pointer to root info structure of index * @param v Hash algorithm version */ static inline void @@ -74,7 +74,7 @@ ext4_dir_dx_rinfo_set_hash_version(struct ext4_dir_idx_rinfo *ri, uint8_t v) } /**@brief Get length of root_info structure in bytes. - * @param root_info Pointer to root info structure of index + * @param ri Pointer to root info structure of index * @return Length of the structure */ static inline uint8_t @@ -84,8 +84,8 @@ ext4_dir_dx_rinfo_get_info_length(struct ext4_dir_idx_rinfo *ri) } /**@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 + * @param ri Pointer to root info structure of index + * @param len Length of the structure */ static inline void ext4_dir_dx_root_info_set_info_length(struct ext4_dir_idx_rinfo *ri, @@ -95,7 +95,7 @@ ext4_dir_dx_root_info_set_info_length(struct ext4_dir_idx_rinfo *ri, } /**@brief Get number of indirect levels of HTree. - * @param root_info Pointer to root info structure of index + * @param ri Pointer to root info structure of index * @return Height of HTree (actually only 0 or 1) */ static inline uint8_t @@ -105,8 +105,8 @@ ext4_dir_dx_rinfo_get_indirect_levels(struct ext4_dir_idx_rinfo *ri) } /**@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) + * @param ri Pointer to root info structure of index + * @param l Height of HTree (actually only 0 or 1) */ static inline void ext4_dir_dx_rinfo_set_indirect_levels(struct ext4_dir_idx_rinfo *ri, uint8_t l) @@ -834,7 +834,6 @@ int ext4_dir_dx_find_entry(struct ext4_dir_search_result *result, * 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) @@ -1067,9 +1066,9 @@ static int ext4_dir_dx_split_data(struct ext4_inode_ref *inode_ref, } /**@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 + * @param ino_ref Directory i-node + * @param dx_blks Array with path from root to leaf node + * @param dxb Leaf block to be split if needed * @return Error code */ static int diff --git a/src/ext4_fs.c b/src/ext4_fs.c index 96659ea..d5fd4fb 100644 --- a/src/ext4_fs.c +++ b/src/ext4_fs.c @@ -817,7 +817,7 @@ void ext4_fs_inode_blocks_init(struct ext4_fs *fs, return; } -#if CONFIG_EXTENT_ENABLE +#if CONFIG_EXTENT_ENABLE && CONFIG_EXTENTS_ENABLE /* Initialize extents if needed */ if (ext4_sb_feature_incom(&fs->sb, EXT4_FINCOM_EXTENTS)) { ext4_inode_set_flag(inode, EXT4_INODE_FLAG_EXTENTS); @@ -936,7 +936,7 @@ int ext4_fs_free_inode(struct ext4_inode_ref *inode_ref) uint32_t offset; uint32_t suboff; int rc; -#if CONFIG_EXTENT_ENABLE +#if CONFIG_EXTENT_ENABLE && CONFIG_EXTENTS_ENABLE /* For extents must be data block destroyed by other way */ if ((ext4_sb_feature_incom(&fs->sb, EXT4_FINCOM_EXTENTS)) && (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { @@ -1224,7 +1224,7 @@ int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref, uint64_t new_size) uint32_t new_blocks_cnt = (uint32_t)((new_size + block_size - 1) / block_size); uint32_t old_blocks_cnt = (uint32_t)((old_size + block_size - 1) / block_size); uint32_t diff_blocks_cnt = old_blocks_cnt - new_blocks_cnt; -#if CONFIG_EXTENT_ENABLE +#if CONFIG_EXTENT_ENABLE && CONFIG_EXTENTS_ENABLE if ((ext4_sb_feature_incom(sb, EXT4_FINCOM_EXTENTS)) && (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { @@ -1270,7 +1270,6 @@ ext4_fsblk_t ext4_fs_inode_to_goal_block(struct ext4_inode_ref *inode_ref) /**@brief Compute 'goal' for allocation algorithm (For blockmap). * @param inode_ref Reference to inode, to allocate block for - * @param goal * @return error code */ int ext4_fs_indirect_find_goal(struct ext4_inode_ref *inode_ref, @@ -1359,7 +1358,7 @@ static int ext4_fs_get_inode_dblk_idx_internal(struct ext4_inode_ref *inode_ref, ext4_fsblk_t current_block; (void)extent_create; -#if CONFIG_EXTENT_ENABLE +#if CONFIG_EXTENT_ENABLE && CONFIG_EXTENTS_ENABLE /* Handle i-node using extents */ if ((ext4_sb_feature_incom(&fs->sb, EXT4_FINCOM_EXTENTS)) && (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { @@ -1478,7 +1477,7 @@ static int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref, { struct ext4_fs *fs = inode_ref->fs; -#if CONFIG_EXTENT_ENABLE +#if CONFIG_EXTENT_ENABLE && CONFIG_EXTENTS_ENABLE /* Handle inode using extents */ if ((ext4_sb_feature_incom(&fs->sb, EXT4_FINCOM_EXTENTS)) && (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { @@ -1642,7 +1641,7 @@ static int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref, int ext4_fs_append_inode_dblk(struct ext4_inode_ref *inode_ref, ext4_fsblk_t *fblock, ext4_lblk_t *iblock) { -#if CONFIG_EXTENT_ENABLE +#if CONFIG_EXTENT_ENABLE && CONFIG_EXTENTS_ENABLE /* Handle extents separately */ if ((ext4_sb_feature_incom(&inode_ref->fs->sb, EXT4_FINCOM_EXTENTS)) && (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { diff --git a/src/ext4_journal.c b/src/ext4_journal.c index 0617b65..a3ee081 100644 --- a/src/ext4_journal.c +++ b/src/ext4_journal.c @@ -640,7 +640,7 @@ struct tag_info { /**@brief Extract information from a block tag. * @param __tag pointer to the block tag * @param tag_bytes block tag size of this jbd filesystem - * @param remaining size in buffer containing the block tag + * @param remain_buf_size size in buffer containing the block tag * @param tag_info information of this tag. * @return EOK when succeed, otherwise return EINVAL.*/ static int @@ -717,7 +717,7 @@ jbd_extract_block_tag(struct jbd_fs *jbd_fs, /**@brief Write information to a block tag. * @param __tag pointer to the block tag - * @param remaining size in buffer containing the block tag + * @param remain_buf_size size in buffer containing the block tag * @param tag_info information of this tag. * @return EOK when succeed, otherwise return EINVAL.*/ static int @@ -994,7 +994,7 @@ static void jbd_destroy_revoke_tree(struct recover_info *info) /**@brief Add entries in a revoke block to revoke tree. * @param jbd_fs jbd filesystem * @param header revoke block header - * @param recover_info journal replay info*/ + * @param info journal replay info*/ static void jbd_build_revoke_tree(struct jbd_fs *jbd_fs, struct jbd_bhdr *header, struct recover_info *info) @@ -1055,7 +1055,7 @@ static void jbd_replay_descriptor_block(struct jbd_fs *jbd_fs, /**@brief The core routine of journal replay. * @param jbd_fs jbd filesystem - * @param recover_info journal replay info + * @param info journal replay info * @param action action needed to be taken * @return standard error code*/ static int jbd_iterate_log(struct jbd_fs *jbd_fs, @@ -1720,8 +1720,7 @@ int jbd_trans_try_revoke_block(struct jbd_trans *trans, /**@brief Free a transaction * @param journal current journal session * @param trans transaction - * @param abort discard all the modifications on the block? - * @return standard error code*/ + * @param abort discard all the modifications on the block?*/ void jbd_journal_free_trans(struct jbd_journal *journal, struct jbd_trans *trans, bool abort) diff --git a/src/ext4_mp.c b/src/ext4_mp.c new file mode 100644 index 0000000..c15dec3 --- /dev/null +++ b/src/ext4_mp.c @@ -0,0 +1 @@ +#include "ext4_mp.h"