Browse Source

METADATA_CSUM: inode added.

pull/11/head
ngkaho1234 9 years ago
parent
commit
76ccc5426e
  1. 58
      lwext4/ext4_fs.c
  2. 25
      lwext4/ext4_inode.c
  3. 15
      lwext4/ext4_inode.h
  4. 5
      lwext4/ext4_types.h

58
lwext4/ext4_fs.c

@ -546,6 +546,12 @@ int ext4_fs_get_block_group_ref(struct ext4_fs *fs, uint32_t bgid,
return EOK;
}
/*
* BIG FAT NOTES:
* Currently we do not verify the checksum of block_group_desc
* and inode.
*/
/**@brief Compute checksum of block group descriptor.
* @param sb Superblock
* @param bgid Index of block group in the filesystem
@ -633,10 +639,53 @@ int ext4_fs_put_block_group_ref(struct ext4_block_group_ref *ref)
return ext4_block_set(ref->fs->bdev, &ref->block);
}
/*
* BIG FAT NOTES:
* Currently we do not verify the checksum of block_group_desc.
*/
static uint32_t ext4_fs_inode_checksum(struct ext4_inode_ref *inode_ref)
{
uint32_t checksum = 0;
struct ext4_sblock *sb = &inode_ref->fs->sb;
uint16_t inode_size = ext4_get16(sb, inode_size);
if (ext4_sb_has_feature_read_only(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
uint32_t orig_checksum;
uint32_t ino_index = to_le32(inode_ref->index);
uint32_t ino_gen =
to_le32(ext4_inode_get_generation(inode_ref->inode));
/* Preparation: temporarily set bg checksum to 0 */
orig_checksum = ext4_inode_get_checksum(sb, inode_ref->inode);
ext4_inode_set_checksum(sb, inode_ref->inode, 0);
/* First calculate crc32 checksum against fs uuid */
checksum = ext4_crc32c(~0, sb->uuid, sizeof(sb->uuid));
/* 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));
/* Finally calculate crc32 checksum against
* the entire inode */
checksum = ext4_crc32c(checksum, inode_ref->inode,
inode_size);
ext4_inode_set_checksum(sb, inode_ref->inode,
orig_checksum);
}
return checksum;
}
static void ext4_fs_set_inode_checksum(struct ext4_inode_ref *inode_ref)
{
struct ext4_sblock *sb = &inode_ref->fs->sb;
if (!ext4_sb_has_feature_read_only(sb,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
return;
ext4_inode_set_checksum(sb, inode_ref->inode,
ext4_fs_inode_checksum(inode_ref));
}
int ext4_fs_get_inode_ref(struct ext4_fs *fs, uint32_t index,
struct ext4_inode_ref *ref)
{
@ -700,6 +749,7 @@ int ext4_fs_put_inode_ref(struct ext4_inode_ref *ref)
/* Check if reference modified */
if (ref->dirty) {
/* Mark block dirty for writing changes to physical device */
ext4_fs_set_inode_checksum(ref);
ref->block.dirty = true;
}

25
lwext4/ext4_inode.c

@ -108,6 +108,31 @@ void ext4_inode_set_size(struct ext4_inode *inode, uint64_t size)
inode->size_hi = to_le32(size >> 32);
}
uint32_t
ext4_inode_get_checksum(struct ext4_sblock *sb, struct ext4_inode *inode)
{
uint16_t inode_size = ext4_get16(sb, inode_size);
uint32_t v = to_le16(inode->osd2.linux2.checksum_lo);
if (inode_size > EXT4_GOOD_OLD_INODE_SIZE)
v |= ((uint32_t)to_le16(inode->checksum_hi)) << 16;
return v;
}
void
ext4_inode_set_checksum(struct ext4_sblock *sb, struct ext4_inode *inode,
uint32_t checksum)
{
uint16_t inode_size = ext4_get16(sb, inode_size);
inode->osd2.linux2.checksum_lo =
to_le16((checksum << 16) >> 16);
if (inode_size > EXT4_GOOD_OLD_INODE_SIZE)
inode->checksum_hi = to_le16(checksum >> 16);
}
uint32_t ext4_inode_get_access_time(struct ext4_inode *inode)
{
return to_le32(inode->access_time);

15
lwext4/ext4_inode.h

@ -280,6 +280,21 @@ void ext4_inode_clear_flag(struct ext4_inode *inode, uint32_t f);
*/
void ext4_inode_set_flag(struct ext4_inode *inode, uint32_t f);
/**@brief Get inode checksum(crc32)
* @param sb Superblock
* @param inode I-node to get checksum value from
*/
uint32_t
ext4_inode_get_checksum(struct ext4_sblock *sb, struct ext4_inode *inode);
/**@brief Get inode checksum(crc32)
* @param sb Superblock
* @param inode I-node to get checksum value from
*/
void
ext4_inode_set_checksum(struct ext4_sblock *sb, struct ext4_inode *inode,
uint32_t checksum);
/**@brief Check if i-node can be truncated.
* @param sb Superblock
* @param inode I-node to check

5
lwext4/ext4_types.h

@ -393,7 +393,8 @@ struct ext4_inode {
uint16_t file_acl_high;
uint16_t uid_high;
uint16_t gid_high;
uint32_t reserved2;
uint16_t checksum_lo; /* crc32c(uuid+inum+inode) LE */
uint16_t reserved2;
} linux2;
struct {
uint16_t reserved1;
@ -405,7 +406,7 @@ struct ext4_inode {
} __attribute__((packed)) osd2;
uint16_t extra_isize;
uint16_t pad1;
uint16_t checksum_hi; /* crc32c(uuid+inum+inode) BE */
uint32_t ctime_extra; /* Extra change time (nsec << 2 | epoch) */
uint32_t mtime_extra; /* Extra Modification time (nsec << 2 | epoch) */
uint32_t atime_extra; /* Extra Access time (nsec << 2 | epoch) */

Loading…
Cancel
Save