diff options
| author | ngkaho1234 <ngkaho1234@gmail.com> | 2015-10-26 12:31:35 +0000 |
|---|---|---|
| committer | ngkaho1234 <ngkaho1234@gmail.com> | 2015-10-26 12:31:35 +0000 |
| commit | 3e54b8a78e230f6c8703390e7667cd0ad80f9462 (patch) | |
| tree | bce26e9e56db8b8558d22ad01c2afe4636b2213f | |
| parent | daf0d53c33e9427c3eb66b6e572798017249011b (diff) | |
Assign correct checksum to directory entry blocks.
| -rw-r--r-- | lwext4/ext4_dir.c | 16 | ||||
| -rw-r--r-- | lwext4/ext4_dir_idx.c | 26 |
2 files changed, 28 insertions, 14 deletions
diff --git a/lwext4/ext4_dir.c b/lwext4/ext4_dir.c index 8294191..4d68d8d 100644 --- a/lwext4/ext4_dir.c +++ b/lwext4/ext4_dir.c @@ -400,14 +400,19 @@ int ext4_dir_add_entry(struct ext4_inode_ref *parent, const char *name, /* 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 @@ int ext4_dir_try_insert_entry(struct ext4_sblock *sb, 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, diff --git a/lwext4/ext4_dir_idx.c b/lwext4/ext4_dir_idx.c index 1da545f..907b6d2 100644 --- a/lwext4/ext4_dir_idx.c +++ b/lwext4/ext4_dir_idx.c @@ -408,12 +408,10 @@ int ext4_dir_dx_init(struct ext4_inode_ref *dir) 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 @@ static int ext4_dir_dx_split_data(struct ext4_inode_ref *inode_ref, 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 @@ 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 */ - 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; |
