&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 size;
/* Compute the checksum only if the filesystem supports it */
- if (ext4_sb_has_feature_read_only(sb,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
+ 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));
orig_checksum = t->checksum;
t->checksum = 0;
/* First calculate crc32 checksum against fs uuid */
- checksum = ext4_crc32c(~0, sb->uuid, sizeof(sb->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,
* BIG FAT NOTES:
* Currently we do not verify the checksum of HTree node.
*/
-__unused static int
+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_has_feature_read_only(sb,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
+ 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 1;
+ return true;
}
struct ext4_directory_dx_tail *t;
limit = ext4_dir_dx_countlimit_get_limit(countlimit);
ext4_sb_get_block_size(sb) -
sizeof(struct ext4_directory_dx_tail)) {
/* There is no space to hold the checksum */
- return 1;
+ return true;
}
t = (struct ext4_directory_dx_tail *)
(((struct ext4_directory_dx_entry *)countlimit) + limit);
dirent,
count_offset,
count, t)))
- return 0;
+ return false;
}
- return 1;
+ 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_has_feature_read_only(sb,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
+ 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) {
to_le32(ext4_dir_dx_checksum(inode_ref, dirent, count_offset, count, t));
}
}
+#else
+#define ext4_dir_set_dx_checksum(...)
+#endif
/****************************************************************************/
uint32_t entry_space = block_size -
2 * sizeof(struct ext4_directory_dx_dot_entry) -
sizeof(struct ext4_directory_dx_root_info);
- if (ext4_sb_has_feature_read_only(sb,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+ 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);
/* Fill the whole block with empty entry */
struct ext4_directory_entry_ll *block_entry = (void *)new_block.data;
- if (ext4_sb_has_feature_read_only(sb,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
+ 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));
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(
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);
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;
}
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) */
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);
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,
*
*/
static void
-ext4_dir_dx_insert_entry(struct ext4_inode_ref *inode_ref,
+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)
{
uint32_t offset = 0;
void *ptr;
-
- if (ext4_sb_has_feature_read_only(&inode_ref->fs->sb,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+ 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 */
block_size = ext4_sb_get_block_size(&inode_ref->fs->sb);
/* Do some steps to finish operation */
- if (ext4_sb_has_feature_read_only(&inode_ref->fs->sb,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
+ 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,
uint32_t entry_space =
block_size -
sizeof(struct ext4_fake_directory_entry);
- if (ext4_sb_has_feature_read_only(sb,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+ 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);
uint32_t entry_space =
block_size -
sizeof(struct ext4_fake_directory_entry);
- if (ext4_sb_has_feature_read_only(sb,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+ 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);
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;
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, parent, &target_block, child, name,
name_len);
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;