ref: daf0d53c33e9427c3eb66b6e572798017249011b
parent: 72e4738cc40a0a1c2b1e944353badcd5a169c8f4
author: ngkaho1234 <[email protected]>
date: Mon Oct 26 06:30:03 EDT 2015
FIX: directory checksum entry not initialized.
--- a/lwext4/ext4_dir.c
+++ b/lwext4/ext4_dir.c
@@ -105,6 +105,14 @@
return 1;
}
+/* checksumming functions */
+void initialize_dir_tail(struct ext4_directory_entry_tail *t)
+{
+ memset(t, 0, sizeof(struct ext4_directory_entry_tail));
+ t->rec_len = to_le16(sizeof(struct ext4_directory_entry_tail));
+ t->reserved_ft = EXT4_DIRENTRY_DIR_CSUM;
+}
+
void ext4_dir_set_checksum(struct ext4_inode_ref *inode_ref,
struct ext4_directory_entry_ll *dirent)
{
@@ -396,6 +404,11 @@
name_len);
/* Save new block */
+ if (ext4_sb_has_feature_read_only(&fs->sb,
+ EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+ initialize_dir_tail(EXT4_DIRENT_TAIL(new_block.data,
+ ext4_sb_get_block_size(&fs->sb)));
+
ext4_dir_set_checksum(parent,
(struct ext4_directory_entry_ll *)new_block.data);
new_block.dirty = true;
--- a/lwext4/ext4_dir.h
+++ b/lwext4/ext4_dir.h
@@ -266,6 +266,9 @@
void ext4_dir_set_checksum(struct ext4_inode_ref *inode_ref,
struct ext4_directory_entry_ll *dirent);
+/* checksumming functions */
+void initialize_dir_tail(struct ext4_directory_entry_tail *t);
+
#endif /* EXT4_DIR_H_ */
/**
--- a/lwext4/ext4_dir_idx.c
+++ b/lwext4/ext4_dir_idx.c
@@ -371,8 +371,12 @@
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))
+ 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 */
@@ -397,6 +401,7 @@
if (ext4_sb_has_feature_read_only(sb,
EXT4_FEATURE_RO_COMPAT_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,
@@ -404,6 +409,11 @@
ext4_dir_entry_ll_set_inode_type(sb,
block_entry,
EXT4_DIRENTRY_DIR_CSUM);
+ if (ext4_sb_has_feature_read_only(sb,
+ EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+ 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 {
@@ -1032,9 +1042,14 @@
}
/* Do some steps to finish operation */
- ext4_dir_set_dx_checksum(inode_ref,
+ ext4_dir_set_checksum(inode_ref,
(struct ext4_directory_entry_ll *)old_data_block->data);
- ext4_dir_set_dx_checksum(inode_ref,
+ if (ext4_sb_has_feature_read_only(&inode_ref->fs->sb,
+ EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+ initialize_dir_tail(EXT4_DIRENT_TAIL(new_data_block_tmp.data,
+ ext4_sb_get_block_size(&inode_ref->fs->sb)));
+
+ 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;
@@ -1063,6 +1078,7 @@
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)
@@ -1153,9 +1169,13 @@
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))
+ entry_space -= sizeof(struct ext4_directory_dx_tail);
uint32_t node_limit =
entry_space /
sizeof(struct ext4_directory_dx_entry);
+
ext4_dir_dx_countlimit_set_limit(right_countlimit,
node_limit);
@@ -1212,6 +1232,9 @@
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))
+ entry_space -= sizeof(struct ext4_directory_dx_tail);
uint32_t node_limit =
entry_space /
sizeof(struct ext4_directory_dx_entry);