1
0
mirror of https://github.com/bobranten/Ext4Fsd.git synced 2025-10-30 05:18:31 -05:00

more work on inode checksums

This commit is contained in:
Bo Brantén
2020-02-05 23:47:39 +01:00
parent 114d102c32
commit 11149fa115
2 changed files with 26 additions and 27 deletions

View File

@@ -370,7 +370,7 @@ static __le32 ext4_inode_csum_seed(struct inode *inode)
} }
static __u32 ext4_inode_csum(struct inode *inode, struct ext4_inode *raw, static __u32 ext4_inode_csum(struct inode *inode, struct ext4_inode *raw,
struct ext4_inode_info *ei) struct ext4_inode_info *unused)
{ {
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
__u32 csum; __u32 csum;
@@ -378,7 +378,8 @@ static __u32 ext4_inode_csum(struct inode *inode, struct ext4_inode *raw,
int offset = offsetof(struct ext4_inode, i_checksum_lo); int offset = offsetof(struct ext4_inode, i_checksum_lo);
unsigned int csum_size = sizeof(dummy_csum); unsigned int csum_size = sizeof(dummy_csum);
csum = ext4_chksum(sbi, ext4_inode_csum_seed(inode), (__u8 *)raw, offset); csum = ext4_inode_csum_seed(inode);
csum = ext4_chksum(sbi, csum, (__u8 *)raw, offset);
csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, csum_size); csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, csum_size);
offset += csum_size; offset += csum_size;
csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset,
@@ -389,7 +390,7 @@ static __u32 ext4_inode_csum(struct inode *inode, struct ext4_inode *raw,
csum = ext4_chksum(sbi, csum, (__u8 *)raw + csum = ext4_chksum(sbi, csum, (__u8 *)raw +
EXT4_GOOD_OLD_INODE_SIZE, EXT4_GOOD_OLD_INODE_SIZE,
offset - EXT4_GOOD_OLD_INODE_SIZE); offset - EXT4_GOOD_OLD_INODE_SIZE);
if (EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) { if (offsetof(struct ext4_inode, i_checksum_hi) + sizeof(raw->i_checksum_hi) <= EXT4_GOOD_OLD_INODE_SIZE + raw->i_extra_isize) {
csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum,
csum_size); csum_size);
offset += csum_size; offset += csum_size;
@@ -402,45 +403,42 @@ static __u32 ext4_inode_csum(struct inode *inode, struct ext4_inode *raw,
} }
int ext4_inode_csum_verify(struct inode *inode, struct ext4_inode *raw, int ext4_inode_csum_verify(struct inode *inode, struct ext4_inode *raw,
struct ext4_inode_info *ei) struct ext4_inode_info *unused)
{ {
__u32 provided, calculated, isz; __u32 provided, calculated;
if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != if (!ext4_has_metadata_csum(inode->i_sb))
cpu_to_le32(EXT4_OS_LINUX) ||
!ext4_has_feature_metadata_csum(inode->i_sb))
return 1; return 1;
provided = le16_to_cpu(raw->i_checksum_lo); provided = le16_to_cpu(raw->i_checksum_lo);
calculated = ext4_inode_csum(inode, raw, ei); calculated = ext4_inode_csum(inode, raw, unused);
if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE && if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE &&
EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) offsetof(struct ext4_inode, i_checksum_hi) + sizeof(raw->i_checksum_hi) <= EXT4_GOOD_OLD_INODE_SIZE + raw->i_extra_isize)
{provided |= ((__u32)le16_to_cpu(raw->i_checksum_hi)) << 16;isz=EXT4_INODE_SIZE(inode->i_sb);} provided |= ((__u32)le16_to_cpu(raw->i_checksum_hi)) << 16;
else else
{calculated &= 0xFFFF;isz=EXT4_GOOD_OLD_INODE_SIZE;} calculated &= 0xFFFF;
if (provided != calculated) { if (provided != calculated)
DbgPrint("inod %d checksum invalid: %lx!=%lx, isz=%u\n", inode->i_ino, provided, calculated, isz); DbgPrint("checksum verify failed on inode %u: %lx != %lx\n", inode->i_ino, provided, calculated);
}
return provided == calculated; return provided == calculated;
} }
void ext4_inode_csum_set(struct inode *inode, struct ext4_inode *raw, void ext4_inode_csum_set(struct inode *inode, struct ext4_inode *raw,
struct ext4_inode_info *ei) struct ext4_inode_info *unused)
{ {
__u32 csum; __u32 csum;
if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != if (!ext4_has_metadata_csum(inode->i_sb))
cpu_to_le32(EXT4_OS_LINUX) ||
!ext4_has_feature_metadata_csum(inode->i_sb))
return; return;
csum = ext4_inode_csum(inode, raw, ei); csum = ext4_inode_csum(inode, raw, unused);
raw->i_checksum_lo = cpu_to_le16(csum & 0xFFFF); raw->i_checksum_lo = cpu_to_le16(csum & 0xFFFF);
if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE && if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE &&
EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) offsetof(struct ext4_inode, i_checksum_hi) + sizeof(raw->i_checksum_hi) <= EXT4_GOOD_OLD_INODE_SIZE + raw->i_extra_isize)
raw->i_checksum_hi = cpu_to_le16(csum >> 16); raw->i_checksum_hi = cpu_to_le16(csum >> 16);
DbgPrint("set checksum on inode %u: csum == %lx\n", inode->i_ino, csum);
ext4_inode_csum_verify(inode, raw, unused);
} }
/* /*

View File

@@ -962,7 +962,7 @@ struct move_extent {
#define EXT4_EPOCH_BITS 2 #define EXT4_EPOCH_BITS 2
#define EXT4_EPOCH_MASK ((1 << EXT4_EPOCH_BITS) - 1) #define EXT4_EPOCH_MASK ((1 << EXT4_EPOCH_BITS) - 1)
#define EXT4_NSEC_MASK (~0UL << EXT4_EPOCH_BITS) #define EXT4_NSEC_MASK (~0UL << EXT4_EPOCH_BITS)
#if 0
/* /*
* Extended fields will fit into an inode if the filesystem was formatted * Extended fields will fit into an inode if the filesystem was formatted
* with large inodes (-I 256 or larger) and there are not currently any EAs * with large inodes (-I 256 or larger) and there are not currently any EAs
@@ -973,12 +973,13 @@ struct move_extent {
* This macro checks if a certain field fits in the inode. Note that * This macro checks if a certain field fits in the inode. Note that
* inode-size = GOOD_OLD_INODE_SIZE + i_extra_isize * inode-size = GOOD_OLD_INODE_SIZE + i_extra_isize
*/ */
/*#define EXT4_FITS_IN_INODE(ext4_inode, einode, field) \ #define EXT4_FITS_IN_INODE(ext4_inode, einode, field) \
((offsetof(typeof(*ext4_inode), field) + \ ((offsetof(typeof(*ext4_inode), field) + \
sizeof((ext4_inode)->field)) \ sizeof((ext4_inode)->field)) \
<= (EXT4_GOOD_OLD_INODE_SIZE + \ <= (EXT4_GOOD_OLD_INODE_SIZE + \
(einode)->i_extra_isize))*/ (einode)->i_extra_isize)) \
#define EXT4_FITS_IN_INODE(ext4_inode, einode, field) 1
#endif
/* /*
* We use an encoding that preserves the times for extra epoch "00": * We use an encoding that preserves the times for extra epoch "00":
* *
@@ -1026,7 +1027,7 @@ static inline void ext4_decode_extra_time(struct timespec64 *time,
} }
time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS; time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS;
} }
#if 0
#define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \ #define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \
do { \ do { \
(raw_inode)->xtime = cpu_to_le32((inode)->xtime.tv_sec); \ (raw_inode)->xtime = cpu_to_le32((inode)->xtime.tv_sec); \
@@ -1070,7 +1071,7 @@ do { \
else \ else \
(einode)->xtime.tv_nsec = 0; \ (einode)->xtime.tv_nsec = 0; \
} while (0) } while (0)
#endif
#define i_disk_version osd1.linux1.l_i_version #define i_disk_version osd1.linux1.l_i_version
#if defined(__KERNEL__) || defined(__linux__) #if defined(__KERNEL__) || defined(__linux__)