ref: 69e6bc56cee09945f574051fa4df0d63eb1c8625
parent: 191fb80f249b0e82bd77b860d090741e0ace9450
author: root <ngkaho1234@gmail.com>
date: Sun Sep 20 12:00:06 EDT 2015
ext4_dir_dx_reset_parent_inode proposed.
--- a/lwext4/ext4.c
+++ b/lwext4/ext4.c
@@ -232,30 +232,34 @@
parent->dirty = true;
} else {
if (ext4_inode_is_type(&mp->fs.sb, child->inode,
- EXT4_INODE_MODE_DIRECTORY)) {
- /* FIXME: SO TRICKY. */
- int has_flag_index = ext4_inode_has_flag(
- child->inode, EXT4_INODE_FLAG_INDEX);
+ EXT4_INODE_MODE_DIRECTORY)) {
+ int has_flag_index =
+ ext4_inode_has_flag(child->inode,
+ EXT4_INODE_FLAG_INDEX);
struct ext4_directory_search_result result;
- if (has_flag_index)
- ext4_inode_clear_flag(child->inode,
- EXT4_INODE_FLAG_INDEX);
+ if (!has_flag_index) {
+ rc = ext4_dir_find_entry(&result,
+ child, "..",
+ strlen(".."));
+ if (rc != EOK)
+ return EIO;
- rc = ext4_dir_find_entry(&result, child, "..",
- strlen(".."));
- if (has_flag_index)
- ext4_inode_set_flag(child->inode,
- EXT4_INODE_FLAG_INDEX);
+ ext4_dir_entry_ll_set_inode(result.dentry,
+ parent->index);
+ result.block.dirty = true;
+ rc = ext4_dir_destroy_result(child, &result);
+ if (rc != EOK)
+ return rc;
- if (rc != EOK)
- return EIO;
+ } else {
+#if CONFIG_DIR_INDEX_ENABLE
+ rc = ext4_dir_dx_reset_parent_inode(parent,
+ parent->index);
+ if (rc != EOK)
+ return rc;
- ext4_dir_entry_ll_set_inode(result.dentry,
- parent->index);
- result.block.dirty = true;
- rc = ext4_dir_destroy_result(child, &result);
- if (rc != EOK)
- return rc;
+#endif
+ }
ext4_fs_inode_links_count_inc(parent);
parent->dirty = true;
--- a/lwext4/ext4_dir.h
+++ b/lwext4/ext4_dir.h
@@ -69,6 +69,16 @@
de->inode = to_le32(inode);
}
+/**@brief Set i-node number to directory entry. (For HTree root)
+ * @param de Directory entry
+ * @param inode I-node number
+ */
+static inline void
+ext4_dx_dot_entry_set_inode(struct ext4_directory_dx_dot_entry *de, uint32_t inode)
+{
+ de->inode = to_le32(inode);
+}
+
/**@brief Get directory entry length.
* @param de Directory entry
* @return Entry length
--- a/lwext4/ext4_dir_idx.c
+++ b/lwext4/ext4_dir_idx.c
@@ -1193,6 +1193,30 @@
return rc2;
}
+int ext4_dir_dx_reset_parent_inode(struct ext4_inode_ref *dir, uint32_t parent_inode)
+{
+ /* Load block 0, where will be index root located */
+ uint32_t fblock;
+ int rc = ext4_fs_get_inode_data_block_index(dir, 0, &fblock);
+ if (rc != EOK)
+ return rc;
+
+ struct ext4_block block;
+ rc = ext4_block_get(dir->fs->bdev, &block, fblock);
+ if (rc != EOK)
+ return rc;
+
+ /* Initialize pointers to data structures */
+ struct ext4_directory_dx_root *root = (void *)block.data;
+
+ /* Fill the inode field with a new parent ino. */
+ ext4_dx_dot_entry_set_inode(&root->dots[1], parent_inode);
+
+ block.dirty = true;
+
+ return ext4_block_set(dir->fs->bdev, &block);
+}
+
/**
* @}
*/
--- a/lwext4/ext4_dir_idx.h
+++ b/lwext4/ext4_dir_idx.h
@@ -75,6 +75,14 @@
int ext4_dir_dx_add_entry(struct ext4_inode_ref *parent,
struct ext4_inode_ref *child, const char *name);
+/**@brief Add new entry to indexed directory
+ * @param dir Directory i-node
+ * @param parent_inode parent inode index
+ * @return Error code
+ */
+int ext4_dir_dx_reset_parent_inode(struct ext4_inode_ref *dir,
+ uint32_t parent_inode);
+
#endif /* EXT4_DIR_IDX_H_ */
/**