diff options
| author | ngkaho1234 <ngkaho1234@gmail.com> | 2015-10-26 10:30:03 +0000 |
|---|---|---|
| committer | ngkaho1234 <ngkaho1234@gmail.com> | 2015-10-26 10:30:03 +0000 |
| commit | daf0d53c33e9427c3eb66b6e572798017249011b (patch) | |
| tree | 40d843b5fffd7e836982b247d3b1a12fe5e811fe | |
| parent | 72e4738cc40a0a1c2b1e944353badcd5a169c8f4 (diff) | |
FIX: directory checksum entry not initialized.
| -rw-r--r-- | lwext4/ext4_dir.c | 13 | ||||
| -rw-r--r-- | lwext4/ext4_dir.h | 3 | ||||
| -rw-r--r-- | lwext4/ext4_dir_idx.c | 27 |
3 files changed, 41 insertions, 2 deletions
diff --git a/lwext4/ext4_dir.c b/lwext4/ext4_dir.c index b17ec7a..8294191 100644 --- a/lwext4/ext4_dir.c +++ b/lwext4/ext4_dir.c @@ -105,6 +105,14 @@ ext4_dir_checksum_verify(struct ext4_inode_ref *inode_ref, 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 @@ int ext4_dir_add_entry(struct ext4_inode_ref *parent, const char *name, 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; diff --git a/lwext4/ext4_dir.h b/lwext4/ext4_dir.h index 7603327..c2ca270 100644 --- a/lwext4/ext4_dir.h +++ b/lwext4/ext4_dir.h @@ -266,6 +266,9 @@ int ext4_dir_destroy_result(struct ext4_inode_ref *parent, 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_ */ /** diff --git a/lwext4/ext4_dir_idx.c b/lwext4/ext4_dir_idx.c index 97878ca..1da545f 100644 --- a/lwext4/ext4_dir_idx.c +++ b/lwext4/ext4_dir_idx.c @@ -371,8 +371,12 @@ 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_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 @@ int ext4_dir_dx_init(struct ext4_inode_ref *dir) 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 @@ int ext4_dir_dx_init(struct ext4_inode_ref *dir) 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 @@ static int ext4_dir_dx_split_data(struct ext4_inode_ref *inode_ref, } /* 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 @@ 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) @@ -1153,9 +1169,13 @@ 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_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 @@ 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_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); |
