Index: sys/fs/ext2fs/ext2_csum.c =================================================================== --- sys/fs/ext2fs/ext2_csum.c +++ sys/fs/ext2fs/ext2_csum.c @@ -590,7 +590,7 @@ E2FS_REV0_INODE_SIZE, offset - 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, csum_size); offset += csum_size; @@ -615,12 +615,12 @@ if (!EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) return (0); - provided = ei->e2di_chksum_lo; + provided = le16toh(ei->e2di_chksum_lo); calculated = ext2_ei_csum(ip, ei); if ((EXT2_INODE_SIZE(fs) > E2FS_REV0_INODE_SIZE && - ei->e2di_extra_isize >= EXT2_INODE_CSUM_HI_EXTRA_END)) { - hi = ei->e2di_chksum_hi; + le16toh(ei->e2di_extra_isize) >= EXT2_INODE_CSUM_HI_EXTRA_END)) { + hi = le16toh(ei->e2di_chksum_hi); provided |= hi << 16; } else calculated &= 0xFFFF; @@ -655,10 +655,10 @@ 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 && - ei->e2di_extra_isize >= EXT2_INODE_CSUM_HI_EXTRA_END)) - ei->e2di_chksum_hi = crc >> 16; + le16toh(ei->e2di_extra_isize) >= EXT2_INODE_CSUM_HI_EXTRA_END)) + ei->e2di_chksum_hi = htole16(crc >> 16); } static uint16_t Index: sys/fs/ext2fs/ext2_extattr.c =================================================================== --- sys/fs/ext2fs/ext2_extattr.c +++ sys/fs/ext2fs/ext2_extattr.c @@ -216,7 +216,7 @@ /* Check attributes magic value */ header = (struct ext2fs_extattr_dinode_header *)((char *)dinode + - E2FS_REV0_INODE_SIZE + dinode->e2di_extra_isize); + E2FS_REV0_INODE_SIZE + le16toh(dinode->e2di_extra_isize)); if (header->h_magic != EXTATTR_MAGIC) { brelse(bp); @@ -356,7 +356,7 @@ /* Check attributes magic value */ header = (struct ext2fs_extattr_dinode_header *)((char *)dinode + - E2FS_REV0_INODE_SIZE + dinode->e2di_extra_isize); + E2FS_REV0_INODE_SIZE + le16toh(dinode->e2di_extra_isize)); if (header->h_magic != EXTATTR_MAGIC) { brelse(bp); @@ -557,7 +557,7 @@ /* Check attributes magic value */ header = (struct ext2fs_extattr_dinode_header *)((char *)dinode + - E2FS_REV0_INODE_SIZE + dinode->e2di_extra_isize); + E2FS_REV0_INODE_SIZE + le16toh(dinode->e2di_extra_isize)); if (header->h_magic != EXTATTR_MAGIC) { brelse(bp); @@ -920,7 +920,7 @@ /* Check attributes magic value */ header = (struct ext2fs_extattr_dinode_header *)((char *)dinode + - E2FS_REV0_INODE_SIZE + dinode->e2di_extra_isize); + E2FS_REV0_INODE_SIZE + le16toh(dinode->e2di_extra_isize)); if (header->h_magic != EXTATTR_MAGIC) { brelse(bp); @@ -955,7 +955,7 @@ } max_size = EXT2_INODE_SIZE(fs) - E2FS_REV0_INODE_SIZE - - dinode->e2di_extra_isize; + le16toh(dinode->e2di_extra_isize); if (!EXT2_IS_LAST_ENTRY(entry)) { size = ext2_extattr_get_size(EXT2_IFIRST(header), entry, Index: sys/fs/ext2fs/ext2_inode_cnv.c =================================================================== --- sys/fs/ext2fs/ext2_inode_cnv.c +++ sys/fs/ext2fs/ext2_inode_cnv.c @@ -49,9 +49,6 @@ */ SDT_PROBE_DEFINE2(ext2fs, , trace, inode_cnv, "int", "char*"); -#define XTIME_TO_NSEC(x) ((x & EXT3_NSEC_MASK) >> 2) -#define NSEC_TO_XTIME(t) (le32toh(t << 2) & EXT3_NSEC_MASK) - #ifdef EXT2FS_PRINT_EXTENTS void ext2_print_inode(struct inode *in) @@ -94,13 +91,19 @@ } #endif /* EXT2FS_PRINT_EXTENTS */ + +#define XTIME_TO_NSEC(x) ((le32toh(x) & EXT3_NSEC_MASK) >> 2) + /* - * raw ext2 inode to inode + * raw ext2 inode LE to host inode conversion */ int ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip) { struct m_ext2fs *fs = ip->i_e2fs; + uint32_t e2_flags; + uint16_t e2_extra_isize; + int i; if ((ip->i_number < EXT2_FIRST_INO(fs) && ip->i_number != EXT2_ROOTINO) || (ip->i_number < EXT2_ROOTINO) || @@ -109,16 +112,17 @@ return (EINVAL); } - if (ip->i_number == EXT2_ROOTINO && ei->e2di_nlink == 0) { + ip->i_nlink = le16toh(ei->e2di_nlink); + if (ip->i_number == EXT2_ROOTINO && ip->i_nlink == 0) { SDT_PROBE2(ext2fs, , trace, inode_cnv, 1, "root inode unallocated"); return (EINVAL); } - ip->i_nlink = ei->e2di_nlink; /* Check extra inode size */ + e2_extra_isize = le16toh(ei->e2di_extra_isize); if (EXT2_INODE_SIZE(fs) > E2FS_REV0_INODE_SIZE) { - if (E2FS_REV0_INODE_SIZE + ei->e2di_extra_isize > - EXT2_INODE_SIZE(fs) || (ei->e2di_extra_isize & 3)) { + if (E2FS_REV0_INODE_SIZE + e2_extra_isize > + EXT2_INODE_SIZE(fs) || (e2_extra_isize & 3)) { SDT_PROBE2(ext2fs, , trace, inode_cnv, 1, "bad extra inode size"); return (EINVAL); @@ -131,75 +135,83 @@ * setting i_mode to zero - why ? I can see that this might lead to * problems in an undelete. */ - ip->i_mode = ei->e2di_nlink ? ei->e2di_mode : 0; - ip->i_size = ei->e2di_size; + ip->i_mode = ip->i_nlink ? le16toh(ei->e2di_mode) : 0; + ip->i_size = le32toh(ei->e2di_size); if (S_ISREG(ip->i_mode)) - ip->i_size |= ((u_int64_t)ei->e2di_size_high) << 32; - ip->i_atime = ei->e2di_atime; - ip->i_mtime = ei->e2di_mtime; - ip->i_ctime = ei->e2di_ctime; + ip->i_size |= le64toh(ei->e2di_size_high) << 32; + ip->i_atime = le32toh(ei->e2di_atime); + ip->i_mtime = le32toh(ei->e2di_mtime); + ip->i_ctime = le32toh(ei->e2di_ctime); if (E2DI_HAS_XTIME(ip)) { ip->i_atimensec = XTIME_TO_NSEC(ei->e2di_atime_extra); ip->i_mtimensec = XTIME_TO_NSEC(ei->e2di_mtime_extra); ip->i_ctimensec = XTIME_TO_NSEC(ei->e2di_ctime_extra); - ip->i_birthtime = ei->e2di_crtime; + ip->i_birthtime = le32toh(ei->e2di_crtime); ip->i_birthnsec = XTIME_TO_NSEC(ei->e2di_crtime_extra); } ip->i_flags = 0; - ip->i_flags |= (ei->e2di_flags & EXT2_APPEND) ? SF_APPEND : 0; - ip->i_flags |= (ei->e2di_flags & EXT2_IMMUTABLE) ? SF_IMMUTABLE : 0; - ip->i_flags |= (ei->e2di_flags & EXT2_NODUMP) ? UF_NODUMP : 0; - ip->i_flag |= (ei->e2di_flags & EXT3_INDEX) ? IN_E3INDEX : 0; - ip->i_flag |= (ei->e2di_flags & EXT4_EXTENTS) ? IN_E4EXTENTS : 0; - ip->i_blocks = ei->e2di_nblock; - ip->i_facl = ei->e2di_facl; + e2_flags = le32toh(ei->e2di_flags); + ip->i_flags |= (e2_flags & EXT2_APPEND) ? SF_APPEND : 0; + ip->i_flags |= (e2_flags & EXT2_IMMUTABLE) ? SF_IMMUTABLE : 0; + ip->i_flags |= (e2_flags & EXT2_NODUMP) ? UF_NODUMP : 0; + ip->i_flag |= (e2_flags & EXT3_INDEX) ? IN_E3INDEX : 0; + ip->i_flag |= (e2_flags & EXT4_EXTENTS) ? IN_E4EXTENTS : 0; + ip->i_blocks = le32toh(ei->e2di_nblock); + ip->i_facl = le32toh(ei->e2di_facl); if (E2DI_HAS_HUGE_FILE(ip)) { - ip->i_blocks |= (uint64_t)ei->e2di_nblock_high << 32; - ip->i_facl |= (uint64_t)ei->e2di_facl_high << 32; - if (ei->e2di_flags & EXT4_HUGE_FILE) + ip->i_blocks |= (uint64_t)le16toh(ei->e2di_nblock_high) << 32; + ip->i_facl |= (uint64_t)le16toh(ei->e2di_facl_high) << 32; + if (e2_flags & EXT4_HUGE_FILE) ip->i_blocks = fsbtodb(ip->i_e2fs, ip->i_blocks); } - ip->i_gen = ei->e2di_gen; - ip->i_uid = ei->e2di_uid; - ip->i_gid = ei->e2di_gid; - ip->i_uid |= (uint32_t)ei->e2di_uid_high << 16; - ip->i_gid |= (uint32_t)ei->e2di_gid_high << 16; + ip->i_gen = le32toh(ei->e2di_gen); + ip->i_uid = le16toh(ei->e2di_uid); + ip->i_gid = le16toh(ei->e2di_gid); + ip->i_uid |= (uint32_t)le16toh(ei->e2di_uid_high) << 16; + ip->i_gid |= (uint32_t)le16toh(ei->e2di_gid_high) << 16; - memcpy(ip->i_data, ei->e2di_blocks, sizeof(ei->e2di_blocks)); + for (i = 0; i < EXT2_NDADDR; i++) + ip->i_db[i] = le32toh(ei->e2di_blocks[i]); + for (i = 0; i < EXT2_NIADDR; i++) + ip->i_ib[i] = le32toh(ei->e2di_blocks[EXT2_NDIR_BLOCKS + i]); /* Verify inode csum. */ return (ext2_ei_csum_verify(ip, ei)); } +#define NSEC_TO_XTIME(t) (htole32((t << 2) & EXT3_NSEC_MASK)) + /* - * inode to raw ext2 inode + * inode to raw ext2 LE inode conversion */ int ext2_i2ei(struct inode *ip, struct ext2fs_dinode *ei) { struct m_ext2fs *fs; + int i; fs = ip->i_e2fs; - ei->e2di_mode = ip->i_mode; - ei->e2di_nlink = ip->i_nlink; + ei->e2di_mode = htole16(ip->i_mode); + ei->e2di_nlink = htole16(ip->i_nlink); + ei->e2di_size = htole32(ip->i_size); + if (S_ISREG(ip->i_mode)) + ei->e2di_size_high = htole32(ip->i_size >> 32); + ei->e2di_atime = htole32(ip->i_atime); + ei->e2di_mtime = htole32(ip->i_mtime); + ei->e2di_ctime = htole32(ip->i_ctime); /* * Godmar thinks: if dtime is nonzero, ext2 says this inode has been * deleted, this would correspond to a zero link count */ - ei->e2di_dtime = ei->e2di_nlink ? 0 : ip->i_mtime; - ei->e2di_size = ip->i_size; - if (S_ISREG(ip->i_mode)) - ei->e2di_size_high = ip->i_size >> 32; - ei->e2di_atime = ip->i_atime; - ei->e2di_mtime = ip->i_mtime; - ei->e2di_ctime = ip->i_ctime; + ei->e2di_dtime = ei->e2di_nlink ? 0 : ei->e2di_mtime; if (E2DI_HAS_XTIME(ip)) { ei->e2di_ctime_extra = NSEC_TO_XTIME(ip->i_ctimensec); ei->e2di_mtime_extra = NSEC_TO_XTIME(ip->i_mtimensec); ei->e2di_atime_extra = NSEC_TO_XTIME(ip->i_atimensec); - ei->e2di_crtime = ip->i_birthtime; + ei->e2di_crtime = htole32(ip->i_birthtime); ei->e2di_crtime_extra = NSEC_TO_XTIME(ip->i_birthnsec); } + /* Keep these in host endian for a while since they change a lot */ ei->e2di_flags = 0; ei->e2di_flags |= (ip->i_flags & SF_APPEND) ? EXT2_APPEND : 0; ei->e2di_flags |= (ip->i_flags & SF_IMMUTABLE) ? EXT2_IMMUTABLE : 0; @@ -219,15 +231,23 @@ ei->e2di_nblock = dbtofsb(fs, ip->i_blocks); ei->e2di_nblock_high = dbtofsb(fs, ip->i_blocks) >> 32 & 0xffff; } - ei->e2di_facl = ip->i_facl & 0xffffffff; - ei->e2di_facl_high = ip->i_facl >> 32 & 0xffff; - ei->e2di_gen = ip->i_gen; - ei->e2di_uid = ip->i_uid & 0xffff; - ei->e2di_uid_high = ip->i_uid >> 16 & 0xffff; - ei->e2di_gid = ip->i_gid & 0xffff; - ei->e2di_gid_high = ip->i_gid >> 16 & 0xffff; + /* Catch up with the conversion */ + ei->e2di_flags = htole32(ei->e2di_flags); + ei->e2di_nblock = htole32(ei->e2di_nblock); + ei->e2di_nblock_high = htole16(ei->e2di_nblock_high); - memcpy(ei->e2di_blocks, ip->i_data, sizeof(ei->e2di_blocks)); + ei->e2di_facl = htole32(ip->i_facl & 0xffffffff); + ei->e2di_facl_high = htole16(ip->i_facl >> 32 & 0xffff); + ei->e2di_gen = htole32(ip->i_gen); + ei->e2di_uid = htole16(ip->i_uid & 0xffff); + ei->e2di_uid_high = htole16(ip->i_uid >> 16 & 0xffff); + ei->e2di_gid = htole16(ip->i_gid & 0xffff); + ei->e2di_gid_high = htole16(ip->i_gid >> 16 & 0xffff); + + for (i = 0; i < EXT2_NDADDR; i++) + ei->e2di_blocks[i] = htole32(ip->i_db[i]); + for (i = 0; i < EXT2_NIADDR; i++) + ei->e2di_blocks[EXT2_NDIR_BLOCKS + i] = htole32(ip->i_ib[i]); /* Set inode csum. */ ext2_ei_csum_set(ip, ei);