* @brief More complex filesystem functions.
*/
-#include "ext4_config.h"
-#include "ext4_types.h"
-#include "ext4_misc.h"
-#include "ext4_errno.h"
-#include "ext4_debug.h"
-
-#include "ext4_trans.h"
-#include "ext4_fs.h"
-#include "ext4_blockdev.h"
-#include "ext4_super.h"
-#include "ext4_crc32.h"
-#include "ext4_block_group.h"
-#include "ext4_balloc.h"
-#include "ext4_bitmap.h"
-#include "ext4_inode.h"
-#include "ext4_ialloc.h"
-#include "ext4_extent.h"
+#include <ext4_config.h>
+#include <ext4_types.h>
+#include <ext4_misc.h>
+#include <ext4_errno.h>
+#include <ext4_debug.h>
+
+#include <ext4_trans.h>
+#include <ext4_fs.h>
+#include <ext4_blockdev.h>
+#include <ext4_super.h>
+#include <ext4_crc32.h>
+#include <ext4_block_group.h>
+#include <ext4_balloc.h>
+#include <ext4_bitmap.h>
+#include <ext4_inode.h>
+#include <ext4_ialloc.h>
+#include <ext4_extent.h>
#include <string.h>
struct ext4_sblock *sb = &bg_ref->fs->sb;
struct ext4_bgroup *bg = bg_ref->block_group;
- uint32_t inode_size = ext4_get32(sb, inode_size);
+ uint32_t inode_size = ext4_get16(sb, inode_size);
uint32_t block_size = ext4_sb_get_block_size(sb);
uint32_t inodes_per_block = block_size / inode_size;
uint32_t inodes_in_group = ext4_inodes_in_group_cnt(sb, bg_ref->index);
void ext4_fs_inode_blocks_init(struct ext4_fs *fs,
struct ext4_inode_ref *inode_ref)
{
- int i;
struct ext4_inode *inode = inode_ref->inode;
- for (i = 0; i < EXT4_INODE_BLOCKS; i++)
- inode->blocks[i] = 0;
+ /* Reset blocks array. For inode which is not directory or file, just
+ * fill in blocks with 0 */
+ switch (ext4_inode_type(&fs->sb, inode_ref->inode)) {
+ case EXT4_INODE_MODE_FILE:
+ case EXT4_INODE_MODE_DIRECTORY:
+ break;
+ default:
+ return;
+ }
- (void)fs;
#if CONFIG_EXTENT_ENABLE
/* Initialize extents if needed */
if (ext4_sb_feature_incom(&fs->sb, EXT4_FINCOM_EXTENTS)) {
/* Initialize extent root header */
ext4_extent_tree_init(inode_ref);
}
+
+ inode_ref->dirty = true;
#endif
}
return EXT4_INODE_MODE_FILE;
case EXT4_DE_SYMLINK:
return EXT4_INODE_MODE_SOFTLINK;
- default:
- /* FIXME: right now we only support 3 file type. */
- ext4_assert(0);
+ case EXT4_DE_CHRDEV:
+ return EXT4_INODE_MODE_CHARDEV;
+ case EXT4_DE_BLKDEV:
+ return EXT4_INODE_MODE_BLOCKDEV;
+ case EXT4_DE_FIFO:
+ return EXT4_INODE_MODE_FIFO;
+ case EXT4_DE_SOCK:
+ return EXT4_INODE_MODE_SOCKET;
}
- return 0;
+ /* FIXME: unsupported filetype */
+ return EXT4_INODE_MODE_FILE;
}
int ext4_fs_alloc_inode(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref,
/* Initialize i-node */
struct ext4_inode *inode = inode_ref->inode;
+ memset(inode, 0, inode_size);
+
uint32_t mode;
if (is_dir) {
/*
mode = 0777;
mode |= EXT4_INODE_MODE_DIRECTORY;
+ } else if (filetype == EXT4_DE_SYMLINK) {
+ /*
+ * Default symbolic link permissions to be compatible with other systems
+ * 0777 (octal) == rwxrwxrwx
+ */
+
+ mode = 0777;
+ mode |= EXT4_INODE_MODE_SOFTLINK;
} else {
/*
* Default file permissions to be compatible with other systems
ext4_inode_set_flags(inode, 0);
ext4_inode_set_generation(inode, 0);
if (inode_size > EXT4_GOOD_OLD_INODE_SIZE) {
- uint16_t off = offsetof(struct ext4_inode, extra_isize);
- uint16_t size = sizeof(struct ext4_inode) - off;
- ext4_inode_set_extra_isize(inode, size);
- }
-
- /* Reset blocks array. For symbolic link inode, just
- * fill in blocks with 0 */
- if (ext4_inode_is_type(&fs->sb, inode, EXT4_INODE_MODE_SOFTLINK)) {
- for (int i = 0; i < EXT4_INODE_BLOCKS; i++)
- inode->blocks[i] = 0;
-
- } else {
- ext4_fs_inode_blocks_init(fs, inode_ref);
+ uint16_t size = ext4_get16(&fs->sb, want_extra_isize);
+ ext4_inode_set_extra_isize(&fs->sb, inode, size);
}
+ memset(inode->blocks, 0, sizeof(inode->blocks));
inode_ref->dirty = true;
return EOK;
struct ext4_sblock *sb = &inode_ref->fs->sb;
uint32_t i;
int r;
+ bool v;
/* Check flags, if i-node can be truncated */
if (!ext4_inode_can_truncate(sb, inode_ref->inode))
if (old_size < new_size)
return EINVAL;
- bool v;
+ /* For symbolic link which is small enough */
v = ext4_inode_is_type(sb, inode_ref->inode, EXT4_INODE_MODE_SOFTLINK);
if (v && old_size < sizeof(inode_ref->inode->blocks) &&
!ext4_inode_get_blocks_count(sb, inode_ref->inode)) {
return EOK;
}
+ i = ext4_inode_type(sb, inode_ref->inode);
+ if (i == EXT4_INODE_MODE_CHARDEV ||
+ i == EXT4_INODE_MODE_BLOCKDEV ||
+ i == EXT4_INODE_MODE_SOCKET) {
+ inode_ref->inode->blocks[0] = 0;
+ inode_ref->inode->blocks[1] = 0;
+
+ inode_ref->dirty = true;
+ return EOK;
+ }
+
/* Compute how many blocks will be released */
uint32_t block_size = ext4_sb_get_block_size(sb);
uint32_t new_blocks_cnt = (uint32_t)((new_size + block_size - 1) / block_size);