Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/ext2fs/ext2_csum.c
Show First 20 Lines • Show All 195 Lines • ▼ Show 20 Lines | |||||
ext2_dirent_get_tail(struct inode *ip, struct ext2fs_direct_2 *ep) | ext2_dirent_get_tail(struct inode *ip, struct ext2fs_direct_2 *ep) | ||||
{ | { | ||||
struct ext2fs_direct_2 *dep; | struct ext2fs_direct_2 *dep; | ||||
void *top; | void *top; | ||||
unsigned int rec_len; | unsigned int rec_len; | ||||
dep = ep; | dep = ep; | ||||
top = EXT2_DIRENT_TAIL(ep, ip->i_e2fs->e2fs_bsize); | top = EXT2_DIRENT_TAIL(ep, ip->i_e2fs->e2fs_bsize); | ||||
rec_len = dep->e2d_reclen; | rec_len = le16toh(dep->e2d_reclen); | ||||
while (rec_len && !(rec_len & 0x3)) { | while (rec_len && !(rec_len & 0x3)) { | ||||
dep = (struct ext2fs_direct_2 *)(((char *)dep) + rec_len); | dep = (struct ext2fs_direct_2 *)(((char *)dep) + rec_len); | ||||
if ((void *)dep >= top) | if ((void *)dep >= top) | ||||
break; | break; | ||||
rec_len = dep->e2d_reclen; | rec_len = le16toh(dep->e2d_reclen); | ||||
} | } | ||||
if (dep != top) | if (dep != top) | ||||
return (NULL); | return (NULL); | ||||
if (ext2_is_dirent_tail(ip, dep)) | if (ext2_is_dirent_tail(ip, dep)) | ||||
return ((struct ext2fs_direct_tail *)dep); | return ((struct ext2fs_direct_tail *)dep); | ||||
Show All 39 Lines | |||||
static struct ext2fs_htree_count * | static struct ext2fs_htree_count * | ||||
ext2_get_dx_count(struct inode *ip, struct ext2fs_direct_2 *ep, int *offset) | ext2_get_dx_count(struct inode *ip, struct ext2fs_direct_2 *ep, int *offset) | ||||
{ | { | ||||
struct ext2fs_direct_2 *dp; | struct ext2fs_direct_2 *dp; | ||||
struct ext2fs_htree_root_info *root; | struct ext2fs_htree_root_info *root; | ||||
int count_offset; | int count_offset; | ||||
if (ep->e2d_reclen == EXT2_BLOCK_SIZE(ip->i_e2fs)) | if (le16toh(ep->e2d_reclen) == EXT2_BLOCK_SIZE(ip->i_e2fs)) | ||||
count_offset = 8; | count_offset = 8; | ||||
else if (ep->e2d_reclen == 12) { | else if (ep->e2d_reclen == 12) { | ||||
dp = (struct ext2fs_direct_2 *)(((char *)ep) + 12); | dp = (struct ext2fs_direct_2 *)(((char *)ep) + 12); | ||||
if (dp->e2d_reclen != EXT2_BLOCK_SIZE(ip->i_e2fs) - 12) | if (le16toh(dp->e2d_reclen) != EXT2_BLOCK_SIZE(ip->i_e2fs) - 12) | ||||
return (NULL); | return (NULL); | ||||
root = (struct ext2fs_htree_root_info *)(((char *)dp + 12)); | root = (struct ext2fs_htree_root_info *)(((char *)dp + 12)); | ||||
if (root->h_reserved1 || | if (root->h_reserved1 || | ||||
root->h_info_len != sizeof(struct ext2fs_htree_root_info)) | root->h_info_len != sizeof(struct ext2fs_htree_root_info)) | ||||
return (NULL); | return (NULL); | ||||
count_offset = 32; | count_offset = 32; | ||||
▲ Show 20 Lines • Show All 306 Lines • ▼ Show 20 Lines | crc = calculate_crc32c(crc, (uint8_t *)ei + offset, | ||||
E2FS_REV0_INODE_SIZE - offset); | E2FS_REV0_INODE_SIZE - offset); | ||||
if (EXT2_INODE_SIZE(fs) > E2FS_REV0_INODE_SIZE) { | if (EXT2_INODE_SIZE(fs) > E2FS_REV0_INODE_SIZE) { | ||||
offset = offsetof(struct ext2fs_dinode, e2di_chksum_hi); | offset = offsetof(struct ext2fs_dinode, e2di_chksum_hi); | ||||
crc = calculate_crc32c(crc, (uint8_t *)ei + | crc = calculate_crc32c(crc, (uint8_t *)ei + | ||||
E2FS_REV0_INODE_SIZE, offset - E2FS_REV0_INODE_SIZE); | E2FS_REV0_INODE_SIZE, offset - E2FS_REV0_INODE_SIZE); | ||||
if ((EXT2_INODE_SIZE(ip->i_e2fs) > E2FS_REV0_INODE_SIZE && | if ((EXT2_INODE_SIZE(ip->i_e2fs) > E2FS_REV0_INODE_SIZE && | ||||
ei->e2di_extra_isize >= EXT2_INODE_CSUM_HI_EXTRA_END)) { | le16toh(ei->e2di_extra_isize) >= EXT2_INODE_CSUM_HI_EXTRA_END)) { | ||||
crc = calculate_crc32c(crc, (uint8_t *)&dummy_csum, | crc = calculate_crc32c(crc, (uint8_t *)&dummy_csum, | ||||
csum_size); | csum_size); | ||||
offset += csum_size; | offset += csum_size; | ||||
} | } | ||||
crc = calculate_crc32c(crc, (uint8_t *)ei + offset, | crc = calculate_crc32c(crc, (uint8_t *)ei + offset, | ||||
EXT2_INODE_SIZE(fs) - offset); | EXT2_INODE_SIZE(fs) - offset); | ||||
} | } | ||||
return (crc); | return (crc); | ||||
} | } | ||||
int | int | ||||
ext2_ei_csum_verify(struct inode *ip, struct ext2fs_dinode *ei) | ext2_ei_csum_verify(struct inode *ip, struct ext2fs_dinode *ei) | ||||
{ | { | ||||
struct m_ext2fs *fs; | struct m_ext2fs *fs; | ||||
const static struct ext2fs_dinode ei_zero; | const static struct ext2fs_dinode ei_zero; | ||||
uint32_t hi, provided, calculated; | uint32_t hi, provided, calculated; | ||||
fs = ip->i_e2fs; | fs = ip->i_e2fs; | ||||
if (!EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) | if (!EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) | ||||
return (0); | return (0); | ||||
provided = ei->e2di_chksum_lo; | provided = le16toh(ei->e2di_chksum_lo); | ||||
calculated = ext2_ei_csum(ip, ei); | calculated = ext2_ei_csum(ip, ei); | ||||
if ((EXT2_INODE_SIZE(fs) > E2FS_REV0_INODE_SIZE && | if ((EXT2_INODE_SIZE(fs) > E2FS_REV0_INODE_SIZE && | ||||
ei->e2di_extra_isize >= EXT2_INODE_CSUM_HI_EXTRA_END)) { | le16toh(ei->e2di_extra_isize) >= EXT2_INODE_CSUM_HI_EXTRA_END)) { | ||||
hi = ei->e2di_chksum_hi; | hi = le16toh(ei->e2di_chksum_hi); | ||||
provided |= hi << 16; | provided |= hi << 16; | ||||
} else | } else | ||||
calculated &= 0xFFFF; | calculated &= 0xFFFF; | ||||
if (provided != calculated) { | if (provided != calculated) { | ||||
/* | /* | ||||
* If it is first time used dinode, | * If it is first time used dinode, | ||||
* it is expected that it will be zeroed | * it is expected that it will be zeroed | ||||
Show All 18 Lines | ext2_ei_csum_set(struct inode *ip, struct ext2fs_dinode *ei) | ||||
fs = ip->i_e2fs; | fs = ip->i_e2fs; | ||||
if (!EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) | if (!EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) | ||||
return; | return; | ||||
crc = ext2_ei_csum(ip, ei); | crc = ext2_ei_csum(ip, ei); | ||||
ei->e2di_chksum_lo = crc & 0xFFFF; | ei->e2di_chksum_lo = htole16(crc & 0xFFFF); | ||||
if ((EXT2_INODE_SIZE(fs) > E2FS_REV0_INODE_SIZE && | if ((EXT2_INODE_SIZE(fs) > E2FS_REV0_INODE_SIZE && | ||||
ei->e2di_extra_isize >= EXT2_INODE_CSUM_HI_EXTRA_END)) | le16toh(ei->e2di_extra_isize) >= EXT2_INODE_CSUM_HI_EXTRA_END)) | ||||
ei->e2di_chksum_hi = crc >> 16; | ei->e2di_chksum_hi = htole16(crc >> 16); | ||||
} | } | ||||
static uint16_t | static uint16_t | ||||
ext2_crc16(uint16_t crc, const void *buffer, unsigned int len) | ext2_crc16(uint16_t crc, const void *buffer, unsigned int len) | ||||
{ | { | ||||
const unsigned char *cp = buffer; | const unsigned char *cp = buffer; | ||||
/* CRC table for the CRC-16. The poly is 0x8005 (x16 + x15 + x2 + 1). */ | /* CRC table for the CRC-16. The poly is 0x8005 (x16 + x15 + x2 + 1). */ | ||||
static uint16_t const crc16_table[256] = { | static uint16_t const crc16_table[256] = { | ||||
▲ Show 20 Lines • Show All 110 Lines • Show Last 20 Lines |