ref: 3e54b8a78e230f6c8703390e7667cd0ad80f9462
parent: daf0d53c33e9427c3eb66b6e572798017249011b
author: ngkaho1234 <[email protected]>
date: Mon Oct 26 08:31:35 EDT 2015
Assign correct checksum to directory entry blocks.
--- a/lwext4/ext4_dir.c
+++ b/lwext4/ext4_dir.c
@@ -400,14 +400,19 @@
/* Fill block with zeroes */
memset(new_block.data, 0, block_size);
struct ext4_directory_entry_ll *block_entry = (void *)new_block.data;
- ext4_dir_write_entry(&fs->sb, block_entry, block_size, child, name,
- name_len);
/* Save new block */
if (ext4_sb_has_feature_read_only(&fs->sb,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+ EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
+ ext4_dir_write_entry(&fs->sb, block_entry,
+ block_size - sizeof(struct ext4_directory_entry_tail),
+ child,
+ name, name_len);
initialize_dir_tail(EXT4_DIRENT_TAIL(new_block.data,
ext4_sb_get_block_size(&fs->sb)));
+ } else
+ ext4_dir_write_entry(&fs->sb, block_entry, block_size, child, name,
+ name_len);
ext4_dir_set_checksum(parent,
(struct ext4_directory_entry_ll *)new_block.data);
@@ -577,9 +582,12 @@
while (dentry < stop) {
uint32_t inode = ext4_dir_entry_ll_get_inode(dentry);
uint16_t rec_len = ext4_dir_entry_ll_get_entry_length(dentry);
+ uint8_t inode_type = ext4_dir_entry_ll_get_inode_type(sb, dentry);
/* If invalid and large enough entry, use it */
- if ((inode == 0) && (rec_len >= required_len)) {
+ if ((inode == 0) &&
+ (inode_type != EXT4_DIRENTRY_DIR_CSUM) &&
+ (rec_len >= required_len)) {
ext4_dir_write_entry(sb, dentry, rec_len, child, name,
name_len);
ext4_dir_set_checksum(inode_ref,
--- a/lwext4/ext4_dir_idx.c
+++ b/lwext4/ext4_dir_idx.c
@@ -408,12 +408,10 @@
0);
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_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 {
@@ -1008,6 +1006,10 @@
uint32_t offset = 0;
void *ptr;
+ if (ext4_sb_has_feature_read_only(&inode_ref->fs->sb,
+ EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+ block_size -= sizeof(struct ext4_directory_entry_tail);
+
/* First part - to the old block */
for (i = 0; i < mid; ++i) {
ptr = old_data_block->data + offset;
@@ -1041,14 +1043,18 @@
offset += sort_array[i].rec_len;
}
+ block_size = ext4_sb_get_block_size(&inode_ref->fs->sb);
+
/* Do some steps to finish operation */
- ext4_dir_set_checksum(inode_ref,
- (struct ext4_directory_entry_ll *)old_data_block->data);
if (ext4_sb_has_feature_read_only(&inode_ref->fs->sb,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+ EXT4_FEATURE_RO_COMPAT_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,
- ext4_sb_get_block_size(&inode_ref->fs->sb)));
-
+ 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;