X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=lwext4%2Fext4_dir_idx.c;h=59f0c5675298efb199ef58b227be5501bd9af1ee;hb=e5f33a98b0385a0281138abb60645db92f309e8a;hp=fcf65472d375e826afe9fe4cb05846e1660c30fe;hpb=39cfadf99cd75b56c4ee677098960623b5eccce3;p=lwext4.git diff --git a/lwext4/ext4_dir_idx.c b/lwext4/ext4_dir_idx.c index fcf6547..59f0c56 100644 --- a/lwext4/ext4_dir_idx.c +++ b/lwext4/ext4_dir_idx.c @@ -40,6 +40,8 @@ #include "ext4_blockdev.h" #include "ext4_fs.h" #include "ext4_super.h" +#include "ext4_inode.h" +#include "ext4_crc32c.h" #include "ext4_hash.h" #include @@ -202,13 +204,159 @@ static int ext4_dir_dx_hash_string(struct ext4_hash_info *hinfo, int len, &hinfo->hash, &hinfo->minor_hash); } +#if CONFIG_META_CSUM_ENABLE +static uint32_t +ext4_dir_dx_checksum(struct ext4_inode_ref *inode_ref, + void *dirent, + int count_offset, int count, struct ext4_directory_dx_tail *t) +{ + uint32_t orig_checksum, checksum = 0; + struct ext4_sblock *sb = &inode_ref->fs->sb; + int size; + + /* Compute the checksum only if the filesystem supports it */ + if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) { + uint32_t ino_index = to_le32(inode_ref->index); + uint32_t ino_gen = + to_le32(ext4_inode_get_generation(inode_ref->inode)); + + size = count_offset + + (count * sizeof(struct ext4_directory_dx_tail)); + orig_checksum = t->checksum; + t->checksum = 0; + /* First calculate crc32 checksum against fs uuid */ + checksum = ext4_crc32c(EXT4_CRC32_INIT, sb->uuid, + sizeof(sb->uuid)); + /* Then calculate crc32 checksum against inode number + * and inode generation */ + checksum = ext4_crc32c(checksum, &ino_index, + sizeof(ino_index)); + checksum = ext4_crc32c(checksum, &ino_gen, + sizeof(ino_gen)); + /* After that calculate crc32 checksum against all the dx_entry */ + checksum = ext4_crc32c(checksum, dirent, size); + /* Finally calculate crc32 checksum for dx_tail */ + checksum = ext4_crc32c(checksum, t, + sizeof(struct ext4_directory_dx_tail)); + t->checksum = orig_checksum; + } + return checksum; +} + +static struct ext4_directory_dx_countlimit * +ext4_dir_dx_get_countlimit(struct ext4_inode_ref *inode_ref, + struct ext4_directory_entry_ll *dirent, + int *offset) +{ + struct ext4_directory_entry_ll *dp; + struct ext4_directory_dx_root *root; + struct ext4_sblock *sb = &inode_ref->fs->sb; + int count_offset; + + if (ext4_dir_entry_ll_get_entry_length(dirent) == + ext4_sb_get_block_size(sb)) + count_offset = 8; + else if (ext4_dir_entry_ll_get_entry_length(dirent) == 12) { + root = (struct ext4_directory_dx_root *)dirent; + dp = (struct ext4_directory_entry_ll *)&root->dots[1]; + if (ext4_dir_entry_ll_get_entry_length(dp) != + ext4_sb_get_block_size(sb) - 12) + return NULL; + if (root->info.reserved_zero || + root->info.info_length != sizeof(struct ext4_directory_dx_root_info)) + return NULL; + count_offset = 32; + } else + return NULL; + + if (offset) + *offset = count_offset; + return (struct ext4_directory_dx_countlimit *)(((char *)dirent) + count_offset); +} + +/* + * BIG FAT NOTES: + * Currently we do not verify the checksum of HTree node. + */ +static bool +ext4_dir_dx_checksum_verify(struct ext4_inode_ref *inode_ref, + struct ext4_directory_entry_ll *dirent) +{ + struct ext4_sblock *sb = &inode_ref->fs->sb; + int count_offset, limit, count; + + if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) { + struct ext4_directory_dx_countlimit *countlimit = + ext4_dir_dx_get_countlimit(inode_ref, dirent, &count_offset); + if (!countlimit) { + /* Directory seems corrupted. */ + return true; + } + struct ext4_directory_dx_tail *t; + limit = ext4_dir_dx_countlimit_get_limit(countlimit); + count = ext4_dir_dx_countlimit_get_count(countlimit); + if (count_offset + (limit * sizeof(struct ext4_directory_dx_entry)) > + ext4_sb_get_block_size(sb) - + sizeof(struct ext4_directory_dx_tail)) { + /* There is no space to hold the checksum */ + return true; + } + t = (struct ext4_directory_dx_tail *) + (((struct ext4_directory_dx_entry *)countlimit) + limit); + + if (t->checksum != to_le32(ext4_dir_dx_checksum(inode_ref, + dirent, + count_offset, + count, t))) + return false; + } + return true; +} + + +static void +ext4_dir_set_dx_checksum(struct ext4_inode_ref *inode_ref, + struct ext4_directory_entry_ll *dirent) +{ + int count_offset, limit, count; + struct ext4_sblock *sb = &inode_ref->fs->sb; + + if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) { + struct ext4_directory_dx_countlimit *countlimit = + ext4_dir_dx_get_countlimit(inode_ref, dirent, &count_offset); + if (!countlimit) { + /* Directory seems corrupted. */ + return; + } + struct ext4_directory_dx_tail *t; + limit = ext4_dir_dx_countlimit_get_limit(countlimit); + count = ext4_dir_dx_countlimit_get_count(countlimit); + if (count_offset + (limit * sizeof(struct ext4_directory_dx_entry)) > + ext4_sb_get_block_size(sb) - + sizeof(struct ext4_directory_dx_tail)) { + /* There is no space to hold the checksum */ + return; + } + t = (struct ext4_directory_dx_tail *) + (((struct ext4_directory_dx_entry *)countlimit) + limit); + + t->checksum = + to_le32(ext4_dir_dx_checksum(inode_ref, dirent, count_offset, count, t)); + } +} +#else +#define ext4_dir_set_dx_checksum(...) +#endif + /****************************************************************************/ -int ext4_dir_dx_init(struct ext4_inode_ref *dir) +int ext4_dir_dx_init(struct ext4_inode_ref *dir, struct ext4_inode_ref *parent) { /* Load block 0, where will be index root located */ ext4_fsblk_t fblock; - int rc = ext4_fs_get_inode_data_block_index(dir, 0, &fblock); + uint32_t iblock; + struct ext4_sblock *sb = &dir->fs->sb; + int rc = ext4_fs_append_inode_block(dir, &fblock, &iblock); if (rc != EOK) return rc; @@ -221,6 +369,21 @@ int ext4_dir_dx_init(struct ext4_inode_ref *dir) struct ext4_directory_dx_root *root = (void *)block.data; struct ext4_directory_dx_root_info *info = &(root->info); + /* Initialize dot entries */ + ext4_dir_write_entry(&dir->fs->sb, + (struct ext4_directory_entry_ll *)root->dots, + 12, + dir, + ".", + strlen(".")); + + ext4_dir_write_entry(&dir->fs->sb, + (struct ext4_directory_entry_ll *)(root->dots + 1), + ext4_sb_get_block_size(sb) - 12, + parent, + "..", + strlen("..")); + /* Initialize root info structure */ uint8_t hash_version = ext4_get8(&dir->fs->sb, default_hash_version); @@ -238,12 +401,15 @@ int ext4_dir_dx_init(struct ext4_inode_ref *dir) uint32_t entry_space = block_size - 2 * sizeof(struct ext4_directory_dx_dot_entry) - sizeof(struct ext4_directory_dx_root_info); + if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) + entry_space -= sizeof(struct ext4_directory_dx_tail); + uint16_t root_limit = entry_space / sizeof(struct ext4_directory_dx_entry); + ext4_dir_dx_countlimit_set_limit(countlimit, root_limit); /* Append new block, where will be new entries inserted in the future */ - uint32_t iblock; rc = ext4_fs_append_inode_block(dir, &fblock, &iblock); if (rc != EOK) { ext4_block_set(dir->fs->bdev, &block); @@ -261,7 +427,25 @@ int ext4_dir_dx_init(struct ext4_inode_ref *dir) /* Fill the whole block with empty entry */ struct ext4_directory_entry_ll *block_entry = (void *)new_block.data; - ext4_dir_entry_ll_set_entry_length(block_entry, block_size); + if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) { + ext4_dir_entry_ll_set_entry_length(block_entry, + block_size - + sizeof(struct ext4_directory_entry_tail)); + ext4_dir_entry_ll_set_name_length(sb, + block_entry, + 0); + ext4_dir_entry_ll_set_inode_type(sb, + block_entry, + EXT4_DIRENTRY_UNKNOWN); + + initialize_dir_tail(EXT4_DIRENT_TAIL(block_entry, + ext4_sb_get_block_size(sb))); + ext4_dir_set_checksum(dir, + (struct ext4_directory_entry_ll *)new_block.data); + } else { + ext4_dir_entry_ll_set_entry_length(block_entry, block_size); + } + ext4_dir_entry_ll_set_inode(block_entry, 0); new_block.dirty = true; @@ -275,6 +459,8 @@ int ext4_dir_dx_init(struct ext4_inode_ref *dir) struct ext4_directory_dx_entry *entry = root->entries; ext4_dir_dx_entry_set_block(entry, iblock); + ext4_dir_set_dx_checksum(dir, + (struct ext4_directory_entry_ll *)block.data); block.dirty = true; return ext4_block_set(dir->fs->bdev, &block); @@ -314,6 +500,8 @@ static int ext4_dir_hinfo_init(struct ext4_hash_info *hinfo, uint32_t entry_space = block_size; entry_space -= 2 * sizeof(struct ext4_directory_dx_dot_entry); entry_space -= sizeof(struct ext4_directory_dx_root_info); + if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) + entry_space -= sizeof(struct ext4_directory_dx_tail); entry_space = entry_space / sizeof(struct ext4_directory_dx_entry); uint16_t limit = ext4_dir_dx_countlimit_get_limit( @@ -413,7 +601,7 @@ static int ext4_dir_dx_get_leaf(struct ext4_hash_info *hinfo, ext4_fsblk_t fblock; int rc = ext4_fs_get_inode_data_block_index( - inode_ref, next_block, &fblock); + inode_ref, next_block, &fblock, false); if (rc != EOK) return rc; @@ -430,6 +618,10 @@ static int ext4_dir_dx_get_leaf(struct ext4_hash_info *hinfo, ext4_sb_get_block_size(&inode_ref->fs->sb) - sizeof(struct ext4_fake_directory_entry); + if (ext4_sb_feature_ro_com(&inode_ref->fs->sb, + EXT4_FRO_COM_METADATA_CSUM)) + entry_space -= sizeof(struct ext4_directory_dx_tail); + entry_space = entry_space / sizeof(struct ext4_directory_dx_entry); @@ -438,6 +630,16 @@ static int ext4_dir_dx_get_leaf(struct ext4_hash_info *hinfo, return EXT4_ERR_BAD_DX_DIR; } + if (!ext4_dir_dx_checksum_verify(inode_ref, + (struct ext4_directory_entry_ll *)tmp_block->data)) { + ext4_dbg(DEBUG_DIR_IDX, + DBG_WARN "HTree checksum failed." + "Inode: %" PRIu32", " + "Block: %" PRIu32"\n", + inode_ref->index, + next_block); + } + ++tmp_dx_block; } @@ -490,7 +692,7 @@ static int ext4_dir_dx_next_block(struct ext4_inode_ref *inode_ref, ext4_fsblk_t block_addr; int rc = ext4_fs_get_inode_data_block_index( - inode_ref, block_idx, &block_addr); + inode_ref, block_idx, &block_addr, false); if (rc != EOK) return rc; @@ -499,6 +701,16 @@ static int ext4_dir_dx_next_block(struct ext4_inode_ref *inode_ref, if (rc != EOK) return rc; + if (!ext4_dir_dx_checksum_verify(inode_ref, + (struct ext4_directory_entry_ll *)block.data)) { + ext4_dbg(DEBUG_DIR_IDX, + DBG_WARN "HTree checksum failed." + "Inode: %" PRIu32", " + "Block: %" PRIu32"\n", + inode_ref->index, + block_idx); + } + p++; /* Don't forget to put old block (prevent memory leak) */ @@ -506,7 +718,7 @@ static int ext4_dir_dx_next_block(struct ext4_inode_ref *inode_ref, if (rc != EOK) return rc; - memcpy(&p->block, &p->block, sizeof(block)); + memcpy(&p->block, &block, sizeof(block)); p->entries = ((struct ext4_directory_dx_node *)block.data)->entries; p->position = p->entries; @@ -523,7 +735,8 @@ int ext4_dir_dx_find_entry(struct ext4_directory_search_result *result, ext4_fsblk_t root_block_addr; int rc2; int rc = - ext4_fs_get_inode_data_block_index(inode_ref, 0, &root_block_addr); + ext4_fs_get_inode_data_block_index(inode_ref, + 0, &root_block_addr, false); if (rc != EOK) return rc; @@ -534,6 +747,16 @@ int ext4_dir_dx_find_entry(struct ext4_directory_search_result *result, if (rc != EOK) return rc; + if (!ext4_dir_dx_checksum_verify(inode_ref, + (struct ext4_directory_entry_ll *)root_block.data)) { + ext4_dbg(DEBUG_DIR_IDX, + DBG_WARN "HTree root checksum failed." + "Inode: %" PRIu32", " + "Block: %" PRIu32"\n", + inode_ref->index, + 0); + } + /* Initialize hash info (compute hash value) */ struct ext4_hash_info hinfo; rc = ext4_dir_hinfo_init(&hinfo, &root_block, &fs->sb, name_len, name); @@ -564,7 +787,8 @@ int ext4_dir_dx_find_entry(struct ext4_directory_search_result *result, ext4_fsblk_t leaf_block_addr; rc = ext4_fs_get_inode_data_block_index( - inode_ref, leaf_block_idx, &leaf_block_addr); + inode_ref, leaf_block_idx, &leaf_block_addr, + false); if (rc != EOK) goto cleanup; @@ -573,6 +797,16 @@ int ext4_dir_dx_find_entry(struct ext4_directory_search_result *result, if (rc != EOK) goto cleanup; + if (!ext4_dir_checksum_verify(inode_ref, + (struct ext4_directory_entry_ll *)leaf_block.data)) { + ext4_dbg(DEBUG_DIR_IDX, + DBG_WARN "HTree leaf block checksum failed." + "Inode: %" PRIu32", " + "Block: %" PRIu32"\n", + inode_ref->index, + leaf_block_idx); + } + /* Linear search inside block */ struct ext4_directory_entry_ll *res_dentry; rc = ext4_dir_find_in_block(&leaf_block, &fs->sb, name_len, @@ -679,13 +913,15 @@ static int ext4_dir_dx_entry_comparator(const void *arg1, const void *arg2) /**@brief Insert new index entry to block. * Note that space for new entry must be checked by caller. + * @param inode_ref Directory i-node * @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, +ext4_dir_dx_insert_entry(struct ext4_inode_ref *inode_ref __unused, + struct ext4_directory_dx_block *index_block, uint32_t hash, uint32_t iblock) { struct ext4_directory_dx_entry *old_index_entry = index_block->position; @@ -706,6 +942,8 @@ ext4_dir_dx_insert_entry(struct ext4_directory_dx_block *index_block, ext4_dir_dx_countlimit_set_count(countlimit, count + 1); + ext4_dir_set_dx_checksum(inode_ref, + (struct ext4_directory_entry_ll *)index_block->block.data); index_block->block.dirty = true; } @@ -841,6 +1079,9 @@ static int ext4_dir_dx_split_data(struct ext4_inode_ref *inode_ref, uint32_t offset = 0; void *ptr; + struct ext4_sblock *sb = &inode_ref->fs->sb; + if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) + block_size -= sizeof(struct ext4_directory_entry_tail); /* First part - to the old block */ for (i = 0; i < mid; ++i) { @@ -875,14 +1116,29 @@ static int ext4_dir_dx_split_data(struct ext4_inode_ref *inode_ref, offset += sort_array[i].rec_len; } + block_size = ext4_sb_get_block_size(&inode_ref->fs->sb); + /* Do some steps to finish operation */ + sb = &inode_ref->fs->sb; + if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) { + initialize_dir_tail(EXT4_DIRENT_TAIL(old_data_block->data, + block_size)); + initialize_dir_tail(EXT4_DIRENT_TAIL(new_data_block_tmp.data, + block_size)); + } + ext4_dir_set_checksum(inode_ref, + (struct ext4_directory_entry_ll *)old_data_block->data); + ext4_dir_set_checksum(inode_ref, + (struct ext4_directory_entry_ll *)new_data_block_tmp.data); old_data_block->dirty = true; new_data_block_tmp.dirty = true; free(sort_array); free(entry_buffer); - ext4_dir_dx_insert_entry(index_block, new_hash + continued, new_iblock); + ext4_dir_dx_insert_entry(inode_ref, + index_block, + new_hash + continued, new_iblock); *new_data_block = new_data_block_tmp; @@ -901,6 +1157,7 @@ ext4_dir_dx_split_index(struct ext4_inode_ref *inode_ref, struct ext4_directory_dx_block *dx_block, struct ext4_directory_dx_block **new_dx_block) { + struct ext4_sblock *sb = &inode_ref->fs->sb; struct ext4_directory_dx_entry *entries; if (dx_block == dx_blocks) @@ -991,9 +1248,12 @@ ext4_dir_dx_split_index(struct ext4_inode_ref *inode_ref, uint32_t entry_space = block_size - sizeof(struct ext4_fake_directory_entry); + if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) + entry_space -= sizeof(struct ext4_directory_dx_tail); + uint32_t node_limit = - entry_space / - sizeof(struct ext4_directory_dx_entry); + entry_space / sizeof(struct ext4_directory_dx_entry); + ext4_dir_dx_countlimit_set_limit(right_countlimit, node_limit); @@ -1001,6 +1261,10 @@ ext4_dir_dx_split_index(struct ext4_inode_ref *inode_ref, uint32_t position_index = (dx_block->position - dx_block->entries); if (position_index >= count_left) { + ext4_dir_set_dx_checksum( + inode_ref, + (struct ext4_directory_entry_ll *) + dx_block->block.data); dx_block->block.dirty = true; struct ext4_block block_tmp = dx_block->block; @@ -1015,11 +1279,21 @@ ext4_dir_dx_split_index(struct ext4_inode_ref *inode_ref, } /* Finally insert new entry */ - ext4_dir_dx_insert_entry(dx_blocks, hash_right, + ext4_dir_dx_insert_entry(inode_ref, + dx_blocks, hash_right, new_iblock); + ext4_dir_set_dx_checksum(inode_ref, + (struct ext4_directory_entry_ll *) + dx_blocks[0].block.data); + ext4_dir_set_dx_checksum(inode_ref, + (struct ext4_directory_entry_ll *) + dx_blocks[1].block.data); dx_blocks[0].block.dirty = true; dx_blocks[1].block.dirty = true; + ext4_dir_set_dx_checksum(inode_ref, + (struct ext4_directory_entry_ll *) + new_block.data); new_block.dirty = true; return ext4_block_set(inode_ref->fs->bdev, &new_block); } else { @@ -1036,9 +1310,11 @@ ext4_dir_dx_split_index(struct ext4_inode_ref *inode_ref, uint32_t entry_space = block_size - sizeof(struct ext4_fake_directory_entry); + if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) + entry_space -= sizeof(struct ext4_directory_dx_tail); + uint32_t node_limit = - entry_space / - sizeof(struct ext4_directory_dx_entry); + entry_space / sizeof(struct ext4_directory_dx_entry); ext4_dir_dx_countlimit_set_limit(new_countlimit, node_limit); @@ -1064,6 +1340,12 @@ ext4_dir_dx_split_index(struct ext4_inode_ref *inode_ref, *new_dx_block = dx_block; + ext4_dir_set_dx_checksum(inode_ref, + (struct ext4_directory_entry_ll *) + dx_blocks[0].block.data); + ext4_dir_set_dx_checksum(inode_ref, + (struct ext4_directory_entry_ll *) + dx_blocks[1].block.data); dx_blocks[0].block.dirty = true; dx_blocks[1].block.dirty = true; } @@ -1080,7 +1362,9 @@ int ext4_dir_dx_add_entry(struct ext4_inode_ref *parent, /* Get direct block 0 (index root) */ ext4_fsblk_t root_block_addr; int rc = - ext4_fs_get_inode_data_block_index(parent, 0, &root_block_addr); + ext4_fs_get_inode_data_block_index(parent, + 0, &root_block_addr, + false); if (rc != EOK) return rc; @@ -1091,6 +1375,16 @@ int ext4_dir_dx_add_entry(struct ext4_inode_ref *parent, if (rc != EOK) return rc; + if (!ext4_dir_dx_checksum_verify(parent, + (struct ext4_directory_entry_ll *)root_block.data)) { + ext4_dbg(DEBUG_DIR_IDX, + DBG_WARN "HTree root checksum failed." + "Inode: %" PRIu32", " + "Block: %" PRIu32"\n", + parent->index, + 0); + } + /* Initialize hinfo structure (mainly compute hash) */ uint32_t name_len = strlen(name); struct ext4_hash_info hinfo; @@ -1120,7 +1414,8 @@ int ext4_dir_dx_add_entry(struct ext4_inode_ref *parent, ext4_dir_dx_entry_get_block(dx_block->position); ext4_fsblk_t leaf_block_addr; rc = ext4_fs_get_inode_data_block_index(parent, leaf_block_idx, - &leaf_block_addr); + &leaf_block_addr, + false); if (rc != EOK) goto release_index; @@ -1137,8 +1432,18 @@ int ext4_dir_dx_add_entry(struct ext4_inode_ref *parent, if (rc != EOK) goto release_index; + if (!ext4_dir_checksum_verify(parent, + (struct ext4_directory_entry_ll *)target_block.data)) { + ext4_dbg(DEBUG_DIR_IDX, + DBG_WARN "HTree leaf block checksum failed." + "Inode: %" PRIu32", " + "Block: %" PRIu32"\n", + parent->index, + leaf_block_idx); + } + /* Check if insert operation passed */ - rc = ext4_dir_try_insert_entry(&fs->sb, &target_block, child, name, + rc = ext4_dir_try_insert_entry(&fs->sb, parent, &target_block, child, name, name_len); if (rc == EOK) goto release_target_index; @@ -1156,10 +1461,10 @@ int ext4_dir_dx_add_entry(struct ext4_inode_ref *parent, uint32_t new_block_hash = ext4_dir_dx_entry_get_hash(dx_block->position + 1); if (hinfo.hash >= new_block_hash) - rc = ext4_dir_try_insert_entry(&fs->sb, &new_block, child, name, + rc = ext4_dir_try_insert_entry(&fs->sb, parent, &new_block, child, name, name_len); else - rc = ext4_dir_try_insert_entry(&fs->sb, &target_block, child, + rc = ext4_dir_try_insert_entry(&fs->sb, parent, &target_block, child, name, name_len); /* Cleanup */ @@ -1198,7 +1503,7 @@ int ext4_dir_dx_reset_parent_inode(struct ext4_inode_ref *dir, { /* Load block 0, where will be index root located */ ext4_fsblk_t fblock; - int rc = ext4_fs_get_inode_data_block_index(dir, 0, &fblock); + int rc = ext4_fs_get_inode_data_block_index(dir, 0, &fblock, false); if (rc != EOK) return rc; @@ -1207,12 +1512,25 @@ int ext4_dir_dx_reset_parent_inode(struct ext4_inode_ref *dir, if (rc != EOK) return rc; + if (!ext4_dir_dx_checksum_verify(dir, + (struct ext4_directory_entry_ll *)block.data)) { + ext4_dbg(DEBUG_DIR_IDX, + DBG_WARN "HTree root checksum failed." + "Inode: %" PRIu32", " + "Block: %" PRIu32"\n", + dir->index, + 0); + } + /* 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); + ext4_dir_set_dx_checksum(dir, + (struct ext4_directory_entry_ll *) + block.data); block.dirty = true; return ext4_block_set(dir->fs->bdev, &block);