Browse Source

FIX: directory HTree root checksum is not assigned correctly.

pull/11/head
ngkaho1234 9 years ago
parent
commit
79c8c98207
  1. 2
      lwext4/ext4.c
  2. 34
      lwext4/ext4_dir_idx.c
  3. 4
      lwext4/ext4_dir_idx.h

2
lwext4/ext4.c

@ -203,7 +203,7 @@ static int ext4_link(struct ext4_mountpoint *mp, struct ext4_inode_ref *parent,
/* Initialize directory index if supported */ /* Initialize directory index if supported */
if (ext4_sb_has_feature_compatible( if (ext4_sb_has_feature_compatible(
&mp->fs.sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) { &mp->fs.sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
rc = ext4_dir_dx_init(child); rc = ext4_dir_dx_init(child, parent);
if (rc != EOK) if (rc != EOK)
return rc; return rc;

34
lwext4/ext4_dir_idx.c

@ -40,6 +40,7 @@
#include "ext4_blockdev.h" #include "ext4_blockdev.h"
#include "ext4_fs.h" #include "ext4_fs.h"
#include "ext4_super.h" #include "ext4_super.h"
#include "ext4_inode.h"
#include "ext4_crc32c.h" #include "ext4_crc32c.h"
#include "ext4_hash.h" #include "ext4_hash.h"
@ -215,13 +216,23 @@ ext4_dir_dx_checksum(struct ext4_inode_ref *inode_ref,
/* Compute the checksum only if the filesystem supports it */ /* Compute the checksum only if the filesystem supports it */
if (ext4_sb_has_feature_read_only(sb, if (ext4_sb_has_feature_read_only(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) { EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
uint32_t ino_index = to_le32(inode_ref->index);
uint32_t ino_gen =
to_le32(ext4_inode_get_generation(inode_ref->inode));
size = count_offset + size = count_offset +
(count * sizeof(struct ext4_directory_dx_tail)); (count * sizeof(struct ext4_directory_dx_tail));
orig_checksum = t->checksum; orig_checksum = t->checksum;
t->checksum = 0; t->checksum = 0;
/* First calculate crc32 checksum against fs uuid */ /* First calculate crc32 checksum against fs uuid */
checksum = ext4_crc32c(~0, sb->uuid, sizeof(sb->uuid)); checksum = ext4_crc32c(~0, sb->uuid, sizeof(sb->uuid));
/* Then calculate crc32 checksum against all the dx_entry */ /* Then calculate crc32 checksum against inode number
* and inode generation */
checksum = ext4_crc32c(checksum, &ino_index,
sizeof(ino_index));
checksum = ext4_crc32c(checksum, &ino_gen,
sizeof(ino_gen));
/* After that calculate crc32 checksum against all the dx_entry */
checksum = ext4_crc32c(checksum, dirent, size); checksum = ext4_crc32c(checksum, dirent, size);
/* Finally calculate crc32 checksum for dx_tail */ /* Finally calculate crc32 checksum for dx_tail */
checksum = ext4_crc32c(checksum, t, checksum = ext4_crc32c(checksum, t,
@ -336,12 +347,13 @@ ext4_dir_set_dx_checksum(struct ext4_inode_ref *inode_ref,
/****************************************************************************/ /****************************************************************************/
int ext4_dir_dx_init(struct ext4_inode_ref *dir) int ext4_dir_dx_init(struct ext4_inode_ref *dir, struct ext4_inode_ref *parent)
{ {
/* Load block 0, where will be index root located */ /* Load block 0, where will be index root located */
ext4_fsblk_t fblock; ext4_fsblk_t fblock;
uint32_t iblock;
struct ext4_sblock *sb = &dir->fs->sb; struct ext4_sblock *sb = &dir->fs->sb;
int rc = ext4_fs_get_inode_data_block_index(dir, 0, &fblock, false); int rc = ext4_fs_append_inode_block(dir, &fblock, &iblock);
if (rc != EOK) if (rc != EOK)
return rc; return rc;
@ -354,6 +366,21 @@ int ext4_dir_dx_init(struct ext4_inode_ref *dir)
struct ext4_directory_dx_root *root = (void *)block.data; struct ext4_directory_dx_root *root = (void *)block.data;
struct ext4_directory_dx_root_info *info = &(root->info); struct ext4_directory_dx_root_info *info = &(root->info);
/* Initialize dot entries */
ext4_dir_write_entry(&dir->fs->sb,
(struct ext4_directory_entry_ll *)root->dots,
12,
dir,
".",
strlen("."));
ext4_dir_write_entry(&dir->fs->sb,
(struct ext4_directory_entry_ll *)(root->dots + 1),
ext4_sb_get_block_size(sb) - 12,
parent,
"..",
strlen(".."));
/* Initialize root info structure */ /* Initialize root info structure */
uint8_t hash_version = ext4_get8(&dir->fs->sb, default_hash_version); uint8_t hash_version = ext4_get8(&dir->fs->sb, default_hash_version);
@ -380,7 +407,6 @@ int ext4_dir_dx_init(struct ext4_inode_ref *dir)
ext4_dir_dx_countlimit_set_limit(countlimit, root_limit); ext4_dir_dx_countlimit_set_limit(countlimit, root_limit);
/* Append new block, where will be new entries inserted in the future */ /* Append new block, where will be new entries inserted in the future */
uint32_t iblock;
rc = ext4_fs_append_inode_block(dir, &fblock, &iblock); rc = ext4_fs_append_inode_block(dir, &fblock, &iblock);
if (rc != EOK) { if (rc != EOK) {
ext4_block_set(dir->fs->bdev, &block); ext4_block_set(dir->fs->bdev, &block);

4
lwext4/ext4_dir_idx.h

@ -50,9 +50,11 @@
/**@brief Initialize index structure of new directory. /**@brief Initialize index structure of new directory.
* @param dir Pointer to directory i-node * @param dir Pointer to directory i-node
* @param dir Pointer to parent directory i-node
* @return Error code * @return Error code
*/ */
int ext4_dir_dx_init(struct ext4_inode_ref *dir); int ext4_dir_dx_init(struct ext4_inode_ref *dir,
struct ext4_inode_ref *parent);
/**@brief Try to find directory entry using directory index. /**@brief Try to find directory entry using directory index.
* @param result Output value - if entry will be found, * @param result Output value - if entry will be found,

Loading…
Cancel
Save