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:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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__)
|
||||||
|
|||||||
Reference in New Issue
Block a user