From cd3acfe7f372a8cbee8ef8f32aa896ce926154ee Mon Sep 17 00:00:00 2001 From: Fedor Uporov Date: Sun, 17 May 2020 14:52:54 +0000 Subject: [PATCH] Add BE architectures support. Author of most initial version: pfg (https://reviews.freebsd.org/D23259) Reviewed by: pfg MFC after: 3 months Differential Revision: https://reviews.freebsd.org/D24685 --- sys/fs/ext2fs/ext2_alloc.c | 155 ++++++++++++----------- sys/fs/ext2fs/ext2_balloc.c | 7 +- sys/fs/ext2fs/ext2_bmap.c | 27 ++-- sys/fs/ext2fs/ext2_csum.c | 146 ++++++++++++---------- sys/fs/ext2fs/ext2_extattr.c | 133 +++++++++++--------- sys/fs/ext2fs/ext2_extents.c | 220 +++++++++++++++++---------------- sys/fs/ext2fs/ext2_extents.h | 12 +- sys/fs/ext2fs/ext2_htree.c | 87 ++++++++----- sys/fs/ext2fs/ext2_inode.c | 5 +- sys/fs/ext2fs/ext2_inode_cnv.c | 174 +++++++++++++++----------- sys/fs/ext2fs/ext2_lookup.c | 102 +++++++-------- sys/fs/ext2fs/ext2_subr.c | 6 +- sys/fs/ext2fs/ext2_vfsops.c | 143 +++++++++++---------- sys/fs/ext2fs/ext2_vnops.c | 20 +-- sys/fs/ext2fs/ext2fs.h | 18 +-- sys/fs/ext2fs/fs.h | 12 +- 16 files changed, 695 insertions(+), 572 deletions(-) diff --git a/sys/fs/ext2fs/ext2_alloc.c b/sys/fs/ext2fs/ext2_alloc.c index 91eb846e00bf..1fa4a4c175f0 100644 --- a/sys/fs/ext2fs/ext2_alloc.c +++ b/sys/fs/ext2fs/ext2_alloc.c @@ -397,7 +397,7 @@ ext2_valloc(struct vnode *pvp, int mode, struct ucred *cred, struct vnode **vpp) ump = pip->i_ump; EXT2_LOCK(ump); - if (fs->e2fs->e2fs_ficount == 0) + if (fs->e2fs_ficount == 0) goto noinodes; /* * If it is a directory then obtain a cylinder group based on @@ -413,7 +413,7 @@ ext2_valloc(struct vnode *pvp, int mode, struct ucred *cred, struct vnode **vpp) if (fs->e2fs_contigdirs[cg] > 0) fs->e2fs_contigdirs[cg]--; } - ipref = cg * fs->e2fs->e2fs_ipg + 1; + ipref = cg * fs->e2fs_ipg + 1; ino = (ino_t)ext2_hashalloc(pip, cg, (long)ipref, mode, ext2_nodealloccg); if (ino == 0) goto noinodes; @@ -501,87 +501,87 @@ uint64_t e2fs_gd_get_b_bitmap(struct ext2_gd *gd) { - return (((uint64_t)(gd->ext4bgd_b_bitmap_hi) << 32) | - gd->ext2bgd_b_bitmap); + return (((uint64_t)(le32toh(gd->ext4bgd_b_bitmap_hi)) << 32) | + le32toh(gd->ext2bgd_b_bitmap)); } uint64_t e2fs_gd_get_i_bitmap(struct ext2_gd *gd) { - return (((uint64_t)(gd->ext4bgd_i_bitmap_hi) << 32) | - gd->ext2bgd_i_bitmap); + return (((uint64_t)(le32toh(gd->ext4bgd_i_bitmap_hi)) << 32) | + le32toh(gd->ext2bgd_i_bitmap)); } uint64_t e2fs_gd_get_i_tables(struct ext2_gd *gd) { - return (((uint64_t)(gd->ext4bgd_i_tables_hi) << 32) | - gd->ext2bgd_i_tables); + return (((uint64_t)(le32toh(gd->ext4bgd_i_tables_hi)) << 32) | + le32toh(gd->ext2bgd_i_tables)); } static uint32_t e2fs_gd_get_nbfree(struct ext2_gd *gd) { - return (((uint32_t)(gd->ext4bgd_nbfree_hi) << 16) | - gd->ext2bgd_nbfree); + return (((uint32_t)(le16toh(gd->ext4bgd_nbfree_hi)) << 16) | + le16toh(gd->ext2bgd_nbfree)); } static void e2fs_gd_set_nbfree(struct ext2_gd *gd, uint32_t val) { - gd->ext2bgd_nbfree = val & 0xffff; - gd->ext4bgd_nbfree_hi = val >> 16; + gd->ext2bgd_nbfree = htole16(val & 0xffff); + gd->ext4bgd_nbfree_hi = htole16(val >> 16); } static uint32_t e2fs_gd_get_nifree(struct ext2_gd *gd) { - return (((uint32_t)(gd->ext4bgd_nifree_hi) << 16) | - gd->ext2bgd_nifree); + return (((uint32_t)(le16toh(gd->ext4bgd_nifree_hi)) << 16) | + le16toh(gd->ext2bgd_nifree)); } static void e2fs_gd_set_nifree(struct ext2_gd *gd, uint32_t val) { - gd->ext2bgd_nifree = val & 0xffff; - gd->ext4bgd_nifree_hi = val >> 16; + gd->ext2bgd_nifree = htole16(val & 0xffff); + gd->ext4bgd_nifree_hi = htole16(val >> 16); } uint32_t e2fs_gd_get_ndirs(struct ext2_gd *gd) { - return (((uint32_t)(gd->ext4bgd_ndirs_hi) << 16) | - gd->ext2bgd_ndirs); + return (((uint32_t)(le16toh(gd->ext4bgd_ndirs_hi)) << 16) | + le16toh(gd->ext2bgd_ndirs)); } static void e2fs_gd_set_ndirs(struct ext2_gd *gd, uint32_t val) { - gd->ext2bgd_ndirs = val & 0xffff; - gd->ext4bgd_ndirs_hi = val >> 16; + gd->ext2bgd_ndirs = htole16(val & 0xffff); + gd->ext4bgd_ndirs_hi = htole16(val >> 16); } static uint32_t e2fs_gd_get_i_unused(struct ext2_gd *gd) { - return (((uint32_t)(gd->ext4bgd_i_unused_hi) << 16) | - gd->ext4bgd_i_unused); + return ((uint32_t)(le16toh(gd->ext4bgd_i_unused_hi) << 16) | + le16toh(gd->ext4bgd_i_unused)); } static void e2fs_gd_set_i_unused(struct ext2_gd *gd, uint32_t val) { - gd->ext4bgd_i_unused = val & 0xffff; - gd->ext4bgd_i_unused_hi = val >> 16; + gd->ext4bgd_i_unused = htole16(val & 0xffff); + gd->ext4bgd_i_unused_hi = htole16(val >> 16); } /* @@ -612,7 +612,7 @@ ext2_dirpref(struct inode *pip) mtx_assert(EXT2_MTX(pip->i_ump), MA_OWNED); fs = pip->i_e2fs; - avgifree = fs->e2fs->e2fs_ficount / fs->e2fs_gcount; + avgifree = fs->e2fs_ficount / fs->e2fs_gcount; avgbfree = fs->e2fs_fbcount / fs->e2fs_gcount; avgndir = fs->e2fs_total_dir / fs->e2fs_gcount; @@ -653,7 +653,8 @@ ext2_dirpref(struct inode *pip) minbfree = 1; cgsize = fs->e2fs_fsize * fs->e2fs_fpg; dirsize = AVGDIRSIZE; - curdirsize = avgndir ? (cgsize - avgbfree * fs->e2fs_bsize) / avgndir : 0; + curdirsize = avgndir ? + (cgsize - avgbfree * fs->e2fs_bsize) / avgndir : 0; if (dirsize < curdirsize) dirsize = curdirsize; maxcontigdirs = min((avgbfree * fs->e2fs_bsize) / dirsize, 255); @@ -731,7 +732,7 @@ ext2_blkpref(struct inode *ip, e2fs_lbn_t lbn, int indx, e2fs_daddr_t *bap, if (bap) for (tmp = indx - 1; tmp >= 0; tmp--) if (bap[tmp]) - return bap[tmp]; + return (le32toh(bap[tmp])); /* * Else lets fall back to the blocknr or, if there is none, follow @@ -739,7 +740,7 @@ ext2_blkpref(struct inode *ip, e2fs_lbn_t lbn, int indx, e2fs_daddr_t *bap, */ return (blocknr ? blocknr : (e2fs_daddr_t)(ip->i_block_group * - EXT2_BLOCKS_PER_GROUP(fs)) + fs->e2fs->e2fs_first_dblock); + EXT2_BLOCKS_PER_GROUP(fs)) + le32toh(fs->e2fs->e2fs_first_dblock)); } /* @@ -802,7 +803,7 @@ ext2_cg_number_gdb_nometa(struct m_ext2fs *fs, int cg) return (0); if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_META_BG)) - return (fs->e2fs->e3fs_first_meta_bg); + return (le32toh(fs->e2fs->e3fs_first_meta_bg)); return ((fs->e2fs_gcount + EXT2_DESCS_PER_BLOCK(fs) - 1) / EXT2_DESCS_PER_BLOCK(fs)); @@ -829,7 +830,7 @@ ext2_cg_number_gdb(struct m_ext2fs *fs, int cg) { unsigned long first_meta_bg, metagroup; - first_meta_bg = fs->e2fs->e3fs_first_meta_bg; + first_meta_bg = le32toh(fs->e2fs->e3fs_first_meta_bg); metagroup = cg / EXT2_DESCS_PER_BLOCK(fs); if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_META_BG) || @@ -847,10 +848,11 @@ ext2_number_base_meta_blocks(struct m_ext2fs *fs, int cg) number = ext2_cg_has_sb(fs, cg); if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_META_BG) || - cg < fs->e2fs->e3fs_first_meta_bg * EXT2_DESCS_PER_BLOCK(fs)) { + cg < le32toh(fs->e2fs->e3fs_first_meta_bg) * + EXT2_DESCS_PER_BLOCK(fs)) { if (number) { number += ext2_cg_number_gdb(fs, cg); - number += fs->e2fs->e2fs_reserved_ngdb; + number += le16toh(fs->e2fs->e2fs_reserved_ngdb); } } else { number += ext2_cg_number_gdb(fs, cg); @@ -877,7 +879,8 @@ static int ext2_get_group_number(struct m_ext2fs *fs, e4fs_daddr_t block) { - return ((block - fs->e2fs->e2fs_first_dblock) / fs->e2fs_bsize); + return ((block - le32toh(fs->e2fs->e2fs_first_dblock)) / + fs->e2fs_bsize); } static int @@ -893,7 +896,7 @@ ext2_cg_block_bitmap_init(struct m_ext2fs *fs, int cg, struct buf *bp) int bit, bit_max, inodes_per_block; uint64_t start, tmp; - if (!(fs->e2fs_gd[cg].ext4bgd_flags & EXT2_BG_BLOCK_UNINIT)) + if (!(le16toh(fs->e2fs_gd[cg].ext4bgd_flags) & EXT2_BG_BLOCK_UNINIT)) return (0); memset(bp->b_data, 0, fs->e2fs_bsize); @@ -905,7 +908,8 @@ ext2_cg_block_bitmap_init(struct m_ext2fs *fs, int cg, struct buf *bp) for (bit = 0; bit < bit_max; bit++) setbit(bp->b_data, bit); - start = (uint64_t)cg * fs->e2fs->e2fs_bpg + fs->e2fs->e2fs_first_dblock; + start = (uint64_t)cg * fs->e2fs_bpg + + le32toh(fs->e2fs->e2fs_first_dblock); /* Set bits for block and inode bitmaps, and inode table. */ tmp = e2fs_gd_get_b_bitmap(&fs->e2fs_gd[cg]); @@ -921,7 +925,7 @@ ext2_cg_block_bitmap_init(struct m_ext2fs *fs, int cg, struct buf *bp) tmp = e2fs_gd_get_i_tables(&fs->e2fs_gd[cg]); inodes_per_block = fs->e2fs_bsize/EXT2_INODE_SIZE(fs); while( tmp < e2fs_gd_get_i_tables(&fs->e2fs_gd[cg]) + - fs->e2fs->e2fs_ipg / inodes_per_block ) { + fs->e2fs_ipg / inodes_per_block ) { if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_FLEX_BG) || ext2_block_in_group(fs, tmp, cg)) setbit(bp->b_data, tmp - start); @@ -933,11 +937,12 @@ ext2_cg_block_bitmap_init(struct m_ext2fs *fs, int cg, struct buf *bp) * the blocksize * 8 ( which is the size of bitmap ), set rest * of the block bitmap to 1 */ - ext2_mark_bitmap_end(fs->e2fs->e2fs_bpg, fs->e2fs_bsize * 8, + ext2_mark_bitmap_end(fs->e2fs_bpg, fs->e2fs_bsize * 8, bp->b_data); /* Clean the flag */ - fs->e2fs_gd[cg].ext4bgd_flags &= ~EXT2_BG_BLOCK_UNINIT; + fs->e2fs_gd[cg].ext4bgd_flags = htole16(le16toh( + fs->e2fs_gd[cg].ext4bgd_flags) & ~EXT2_BG_BLOCK_UNINIT); return (0); } @@ -951,8 +956,8 @@ ext2_b_bitmap_validate(struct m_ext2fs *fs, struct buf *bp, int cg) if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_FLEX_BG)) { /* - * It is not possible to check block bitmap in case of this feature, - * because the inode and block bitmaps and inode table + * It is not possible to check block bitmap in case of this + * feature, because the inode and block bitmaps and inode table * blocks may not be in the group at all. * So, skip check in this case. */ @@ -961,8 +966,8 @@ ext2_b_bitmap_validate(struct m_ext2fs *fs, struct buf *bp, int cg) gd = &fs->e2fs_gd[cg]; max_bit = fs->e2fs_fpg; - group_first_block = ((uint64_t)cg) * fs->e2fs->e2fs_fpg + - fs->e2fs->e2fs_first_dblock; + group_first_block = ((uint64_t)cg) * fs->e2fs_fpg + + le32toh(fs->e2fs->e2fs_first_dblock); /* Check block bitmap block number */ offset = e2fs_gd_get_b_bitmap(gd) - group_first_block; @@ -1036,8 +1041,8 @@ ext2_alloccg(struct inode *ip, int cg, daddr_t bpref, int size) goto fail; /* - * Check, that another thread did not not allocate the last block in this - * group while we were waiting for the buffer. + * Check, that another thread did not not allocate the last block in + * this group while we were waiting for the buffer. */ if (e2fs_gd_get_nbfree(&fs->e2fs_gd[cg]) == 0) goto fail; @@ -1066,7 +1071,7 @@ ext2_alloccg(struct inode *ip, int cg, daddr_t bpref, int size) start = dtogd(fs, bpref) / NBBY; else start = 0; - end = howmany(fs->e2fs->e2fs_fpg, NBBY) - start; + end = howmany(fs->e2fs_fpg, NBBY) - start; retry: runlen = 0; runstart = 0; @@ -1135,7 +1140,8 @@ ext2_alloccg(struct inode *ip, int cg, daddr_t bpref, int size) EXT2_UNLOCK(ump); ext2_gd_b_bitmap_csum_set(fs, cg, bp); bdwrite(bp); - return (((uint64_t)cg) * fs->e2fs->e2fs_fpg + fs->e2fs->e2fs_first_dblock + bno); + return (((uint64_t)cg) * fs->e2fs_fpg + + le32toh(fs->e2fs->e2fs_first_dblock) + bno); fail: brelse(bp); @@ -1203,7 +1209,7 @@ ext2_clusteralloc(struct inode *ip, int cg, daddr_t bpref, int len) bpref = dtogd(fs, bpref); loc = bpref / NBBY; bit = 1 << (bpref % NBBY); - for (run = 0, got = bpref; got < fs->e2fs->e2fs_fpg; got++) { + for (run = 0, got = bpref; got < fs->e2fs_fpg; got++) { if ((bbp[loc] & bit) != 0) run = 0; else { @@ -1219,7 +1225,7 @@ ext2_clusteralloc(struct inode *ip, int cg, daddr_t bpref, int len) } } - if (got >= fs->e2fs->e2fs_fpg) + if (got >= fs->e2fs_fpg) goto fail_lock; /* Allocate the cluster that we found. */ @@ -1228,7 +1234,7 @@ ext2_clusteralloc(struct inode *ip, int cg, daddr_t bpref, int len) panic("ext2_clusteralloc: map mismatch"); bno = got - run + 1; - if (bno >= fs->e2fs->e2fs_fpg) + if (bno >= fs->e2fs_fpg) panic("ext2_clusteralloc: allocated out of group"); EXT2_LOCK(ump); @@ -1243,7 +1249,8 @@ ext2_clusteralloc(struct inode *ip, int cg, daddr_t bpref, int len) EXT2_UNLOCK(ump); bdwrite(bp); - return (cg * fs->e2fs->e2fs_fpg + fs->e2fs->e2fs_first_dblock + bno); + return (cg * fs->e2fs_fpg + le32toh(fs->e2fs->e2fs_first_dblock) + + bno); fail_lock: EXT2_LOCK(ump); @@ -1261,13 +1268,13 @@ ext2_zero_inode_table(struct inode *ip, int cg) fs = ip->i_e2fs; - if (fs->e2fs_gd[cg].ext4bgd_flags & EXT2_BG_INODE_ZEROED) + if (le16toh(fs->e2fs_gd[cg].ext4bgd_flags) & EXT2_BG_INODE_ZEROED) return (0); - all_blks = fs->e2fs->e2fs_inode_size * fs->e2fs->e2fs_ipg / + all_blks = le16toh(fs->e2fs->e2fs_inode_size) * fs->e2fs_ipg / fs->e2fs_bsize; - used_blks = howmany(fs->e2fs->e2fs_ipg - + used_blks = howmany(fs->e2fs_ipg - e2fs_gd_get_i_unused(&fs->e2fs_gd[cg]), fs->e2fs_bsize / EXT2_INODE_SIZE(fs)); @@ -1282,7 +1289,8 @@ ext2_zero_inode_table(struct inode *ip, int cg) bawrite(bp); } - fs->e2fs_gd[cg].ext4bgd_flags |= EXT2_BG_INODE_ZEROED; + fs->e2fs_gd[cg].ext4bgd_flags = htole16(le16toh( + fs->e2fs_gd[cg].ext4bgd_flags) | EXT2_BG_INODE_ZEROED); return (0); } @@ -1329,12 +1337,15 @@ ext2_nodealloccg(struct inode *ip, int cg, daddr_t ipref, int mode) } if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM) || EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) { - if (fs->e2fs_gd[cg].ext4bgd_flags & EXT2_BG_INODE_UNINIT) { + if (le16toh(fs->e2fs_gd[cg].ext4bgd_flags) & + EXT2_BG_INODE_UNINIT) { ibytes = fs->e2fs_ipg / 8; memset(bp->b_data, 0, ibytes - 1); ext2_fix_bitmap_tail(bp->b_data, ibytes, fs->e2fs_bsize - 1); - fs->e2fs_gd[cg].ext4bgd_flags &= ~EXT2_BG_INODE_UNINIT; + fs->e2fs_gd[cg].ext4bgd_flags = htole16(le16toh( + fs->e2fs_gd[cg].ext4bgd_flags) & + ~EXT2_BG_INODE_UNINIT); } ext2_gd_i_bitmap_csum_set(fs, cg, bp); error = ext2_zero_inode_table(ip, cg); @@ -1361,20 +1372,21 @@ ext2_nodealloccg(struct inode *ip, int cg, daddr_t ipref, int mode) } ibp = (char *)bp->b_data; if (ipref) { - ipref %= fs->e2fs->e2fs_ipg; + ipref %= fs->e2fs_ipg; if (isclr(ibp, ipref)) goto gotit; } start = ipref / NBBY; - len = howmany(fs->e2fs->e2fs_ipg - ipref, NBBY); + len = howmany(fs->e2fs_ipg - ipref, NBBY); loc = memcchr(&ibp[start], 0xff, len); if (loc == NULL) { len = start + 1; start = 0; loc = memcchr(&ibp[start], 0xff, len); if (loc == NULL) { - SDT_PROBE3(ext2fs, , alloc, ext2_nodealloccg_bmap_corrupted, - cg, ipref, fs->e2fs_fsmnt); + SDT_PROBE3(ext2fs, , alloc, + ext2_nodealloccg_bmap_corrupted, cg, ipref, + fs->e2fs_fsmnt); brelse(bp); EXT2_LOCK(ump); return (0); @@ -1388,12 +1400,12 @@ ext2_nodealloccg(struct inode *ip, int cg, daddr_t ipref, int mode) e2fs_gd_get_nifree(&fs->e2fs_gd[cg]) - 1); if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM) || EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) { - ifree = fs->e2fs->e2fs_ipg - e2fs_gd_get_i_unused(&fs->e2fs_gd[cg]); + ifree = fs->e2fs_ipg - e2fs_gd_get_i_unused(&fs->e2fs_gd[cg]); if (ipref + 1 > ifree) e2fs_gd_set_i_unused(&fs->e2fs_gd[cg], - fs->e2fs->e2fs_ipg - (ipref + 1)); + fs->e2fs_ipg - (ipref + 1)); } - fs->e2fs->e2fs_ficount--; + fs->e2fs_ficount--; fs->e2fs_fmod = 1; if ((mode & IFMT) == IFDIR) { e2fs_gd_set_ndirs(&fs->e2fs_gd[cg], @@ -1423,7 +1435,8 @@ ext2_blkfree(struct inode *ip, e4fs_daddr_t bno, long size) ump = ip->i_ump; cg = dtog(fs, bno); if (bno >= fs->e2fs_bcount) { - SDT_PROBE2(ext2fs, , alloc, ext2_blkfree_bad_block, ip->i_number, bno); + SDT_PROBE2(ext2fs, , alloc, ext2_blkfree_bad_block, + ip->i_number, bno); return; } error = bread(ip->i_devvp, @@ -1479,7 +1492,7 @@ ext2_vfree(struct vnode *pvp, ino_t ino, int mode) return (0); } ibp = (char *)bp->b_data; - ino = (ino - 1) % fs->e2fs->e2fs_ipg; + ino = (ino - 1) % fs->e2fs_ipg; if (isclr(ibp, ino)) { SDT_PROBE2(ext2fs, , alloc, ext2_vfree_doublefree, fs->e2fs_fsmnt, ino); @@ -1488,7 +1501,7 @@ ext2_vfree(struct vnode *pvp, ino_t ino, int mode) } clrbit(ibp, ino); EXT2_LOCK(ump); - fs->e2fs->e2fs_ficount++; + fs->e2fs_ficount++; e2fs_gd_set_nifree(&fs->e2fs_gd[cg], e2fs_gd_get_nifree(&fs->e2fs_gd[cg]) + 1); if ((mode & IFMT) == IFDIR) { @@ -1523,15 +1536,15 @@ ext2_mapsearch(struct m_ext2fs *fs, char *bbp, daddr_t bpref) start = dtogd(fs, bpref) / NBBY; else start = 0; - len = howmany(fs->e2fs->e2fs_fpg, NBBY) - start; + len = howmany(fs->e2fs_fpg, NBBY) - start; loc = memcchr(&bbp[start], 0xff, len); if (loc == NULL) { len = start + 1; start = 0; loc = memcchr(&bbp[start], 0xff, len); if (loc == NULL) { - panic("ext2_mapsearch: map corrupted: start=%d, len=%d, fs=%s", - start, len, fs->e2fs_fsmnt); + panic("ext2_mapsearch: map corrupted: start=%d, len=%d," + "fs=%s", start, len, fs->e2fs_fsmnt); /* NOTREACHED */ } } @@ -1547,8 +1560,8 @@ ext2_cg_has_sb(struct m_ext2fs *fs, int cg) return (1); if (EXT2_HAS_COMPAT_FEATURE(fs, EXT2F_COMPAT_SPARSESUPER2)) { - if (cg == fs->e2fs->e4fs_backup_bgs[0] || - cg == fs->e2fs->e4fs_backup_bgs[1]) + if (cg == le32toh(fs->e2fs->e4fs_backup_bgs[0]) || + cg == le32toh(fs->e2fs->e4fs_backup_bgs[1])) return (1); return (0); } diff --git a/sys/fs/ext2fs/ext2_balloc.c b/sys/fs/ext2fs/ext2_balloc.c index db8f20eb6db0..b2c97181c8f1 100644 --- a/sys/fs/ext2fs/ext2_balloc.c +++ b/sys/fs/ext2fs/ext2_balloc.c @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -220,7 +221,7 @@ ext2_balloc(struct inode *ip, e2fs_lbn_t lbn, int size, struct ucred *cred, return (error); } bap = (e2fs_daddr_t *)bp->b_data; - nb = bap[indirs[i].in_off]; + nb = le32toh(bap[indirs[i].in_off]); if (i == num) break; i += 1; @@ -252,7 +253,7 @@ ext2_balloc(struct inode *ip, e2fs_lbn_t lbn, int size, struct ucred *cred, brelse(bp); return (error); } - bap[indirs[i - 1].in_off] = nb; + bap[indirs[i - 1].in_off] = htole32(nb); /* * If required, write synchronously, otherwise use * delayed write. @@ -284,7 +285,7 @@ ext2_balloc(struct inode *ip, e2fs_lbn_t lbn, int size, struct ucred *cred, nbp->b_blkno = fsbtodb(fs, nb); if (flags & BA_CLRBUF) vfs_bio_clrbuf(nbp); - bap[indirs[i].in_off] = nb; + bap[indirs[i].in_off] = htole32(nb); /* * If required, write synchronously, otherwise use * delayed write. diff --git a/sys/fs/ext2fs/ext2_bmap.c b/sys/fs/ext2fs/ext2_bmap.c index 8991a7e8fdef..9e1b5d2df7e7 100644 --- a/sys/fs/ext2fs/ext2_bmap.c +++ b/sys/fs/ext2fs/ext2_bmap.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -108,7 +109,7 @@ ext4_bmapext(struct vnode *vp, int32_t bn, int64_t *bnp, int *runp, int *runb) ump = VFSTOEXT2(mp); lbn = bn; ehp = (struct ext4_extent_header *)ip->i_data; - depth = ehp->eh_depth; + depth = le16toh(ehp->eh_depth); bsize = EXT2_BLOCK_SIZE(ump->um_e2fs); *bnp = -1; @@ -125,22 +126,26 @@ ext4_bmapext(struct vnode *vp, int32_t bn, int64_t *bnp, int *runp, int *runb) ep = path[depth].ep_ext; if(ep) { - if (lbn < ep->e_blk) { + if (lbn < le32toh(ep->e_blk)) { if (runp != NULL) { - *runp = min(maxrun, ep->e_blk - lbn - 1); + *runp = min(maxrun, le32toh(ep->e_blk) - lbn - 1); } - } else if (ep->e_blk <= lbn && lbn < ep->e_blk + ep->e_len) { - *bnp = fsbtodb(fs, lbn - ep->e_blk + - (ep->e_start_lo | (daddr_t)ep->e_start_hi << 32)); + } else if (le32toh(ep->e_blk) <= lbn && + lbn < le32toh(ep->e_blk) + le16toh(ep->e_len)) { + *bnp = fsbtodb(fs, lbn - le32toh(ep->e_blk) + + (le32toh(ep->e_start_lo) | + (daddr_t)le16toh(ep->e_start_hi) << 32)); if (runp != NULL) { *runp = min(maxrun, - ep->e_len - (lbn - ep->e_blk) - 1); + le16toh(ep->e_len) - + (lbn - le32toh(ep->e_blk)) - 1); } if (runb != NULL) - *runb = min(maxrun, lbn - ep->e_blk); + *runb = min(maxrun, lbn - le32toh(ep->e_blk)); } else { if (runb != NULL) - *runb = min(maxrun, ep->e_blk + lbn - ep->e_len); + *runb = min(maxrun, le32toh(ep->e_blk) + lbn - + le16toh(ep->e_len)); } } @@ -283,7 +288,7 @@ ext2_bmaparray(struct vnode *vp, daddr_t bn, daddr_t *bnp, int *runp, int *runb) if (error != 0) return (error); - daddr = ((e2fs_daddr_t *)bp->b_data)[ap->in_off]; + daddr = le32toh(((e2fs_daddr_t *)bp->b_data)[ap->in_off]); if (num == 1 && daddr && runp) { for (bn = ap->in_off + 1; bn < MNINDIR(ump) && *runp < maxrun && @@ -395,7 +400,7 @@ ext2_bmap_seekdata(struct vnode *vp, off_t *offp) */ off = ap->in_off; do { - daddr = ((e2fs_daddr_t *)bp->b_data)[off]; + daddr = le32toh(((e2fs_daddr_t *)bp->b_data)[off]); } while (daddr == 0 && ++off < MNINDIR(ump)); nextbn += off * lbn_count(ump, num - 1); diff --git a/sys/fs/ext2fs/ext2_csum.c b/sys/fs/ext2fs/ext2_csum.c index 0ca258f12f72..550c9172a992 100644 --- a/sys/fs/ext2fs/ext2_csum.c +++ b/sys/fs/ext2fs/ext2_csum.c @@ -77,7 +77,7 @@ ext2_sb_csum_set_seed(struct m_ext2fs *fs) { if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_CSUM_SEED)) - fs->e2fs_csum_seed = fs->e2fs->e4fs_chksum_seed; + fs->e2fs_csum_seed = le32toh(fs->e2fs->e4fs_chksum_seed); else if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) { fs->e2fs_csum_seed = calculate_crc32c(~0, fs->e2fs->e2fs_uuid, sizeof(fs->e2fs->e2fs_uuid)); @@ -95,13 +95,14 @@ ext2_sb_csum_verify(struct m_ext2fs *fs) "WARNING: mount of %s denied due bad sb csum type\n", fs->e2fs_fsmnt); return (EINVAL); } - if (fs->e2fs->e4fs_sbchksum != + if (le32toh(fs->e2fs->e4fs_sbchksum) != calculate_crc32c(~0, (const char *)fs->e2fs, offsetof(struct ext2fs, e4fs_sbchksum))) { printf( "WARNING: mount of %s denied due bad sb csum=0x%x, expected=0x%x - run fsck\n", - fs->e2fs_fsmnt, fs->e2fs->e4fs_sbchksum, calculate_crc32c(~0, - (const char *)fs->e2fs, offsetof(struct ext2fs, e4fs_sbchksum))); + fs->e2fs_fsmnt, le32toh(fs->e2fs->e4fs_sbchksum), + calculate_crc32c(~0, (const char *)fs->e2fs, + offsetof(struct ext2fs, e4fs_sbchksum))); return (EINVAL); } @@ -112,8 +113,9 @@ void ext2_sb_csum_set(struct m_ext2fs *fs) { - fs->e2fs->e4fs_sbchksum = calculate_crc32c(~0, (const char *)fs->e2fs, - offsetof(struct ext2fs, e4fs_sbchksum)); + fs->e2fs->e4fs_sbchksum = + htole32(calculate_crc32c(~0, (const char *)fs->e2fs, + offsetof(struct ext2fs, e4fs_sbchksum))); } static uint32_t @@ -121,18 +123,22 @@ ext2_extattr_blk_csum(struct inode *ip, uint64_t facl, struct ext2fs_extattr_header *header) { struct m_ext2fs *fs; - uint32_t crc, old_crc; + uint32_t crc, dummy_crc = 0; + uint64_t facl_bn = htole64(facl); + int offset = offsetof(struct ext2fs_extattr_header, h_checksum); fs = ip->i_e2fs; - old_crc = header->h_checksum; + crc = calculate_crc32c(fs->e2fs_csum_seed, (uint8_t *)&facl_bn, + sizeof(facl_bn)); + crc = calculate_crc32c(crc, (uint8_t *)header, offset); + crc = calculate_crc32c(crc, (uint8_t *)&dummy_crc, + sizeof(dummy_crc)); + offset += sizeof(dummy_crc); + crc = calculate_crc32c(crc, (uint8_t *)header + offset, + fs->e2fs_bsize - offset); - header->h_checksum = 0; - crc = calculate_crc32c(fs->e2fs_csum_seed, (uint8_t *)&facl, sizeof(facl)); - crc = calculate_crc32c(crc, (uint8_t *)header, fs->e2fs_bsize); - header->h_checksum = old_crc; - - return (crc); + return (htole32(crc)); } int @@ -167,7 +173,7 @@ void ext2_init_dirent_tail(struct ext2fs_direct_tail *tp) { memset(tp, 0, sizeof(struct ext2fs_direct_tail)); - tp->e2dt_rec_len = sizeof(struct ext2fs_direct_tail); + tp->e2dt_rec_len = le16toh(sizeof(struct ext2fs_direct_tail)); tp->e2dt_reserved_ft = EXT2_FT_DIR_CSUM; } @@ -184,7 +190,7 @@ ext2_is_dirent_tail(struct inode *ip, struct ext2fs_direct_2 *ep) tp = (struct ext2fs_direct_tail *)ep; if (tp->e2dt_reserved_zero1 == 0 && - tp->e2dt_rec_len == sizeof(struct ext2fs_direct_tail) && + le16toh(tp->e2dt_rec_len) == sizeof(struct ext2fs_direct_tail) && tp->e2dt_reserved_zero2 == 0 && tp->e2dt_reserved_ft == EXT2_FT_DIR_CSUM) return (1); @@ -201,13 +207,13 @@ ext2_dirent_get_tail(struct inode *ip, struct ext2fs_direct_2 *ep) dep = ep; 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)) { dep = (struct ext2fs_direct_2 *)(((char *)dep) + rec_len); if ((void *)dep >= top) break; - rec_len = dep->e2d_reclen; + rec_len = le16toh(dep->e2d_reclen); } if (dep != top) @@ -230,8 +236,8 @@ ext2_dirent_csum(struct inode *ip, struct ext2fs_direct_2 *ep, int size) buf = (char *)ep; - inum = ip->i_number; - gen = ip->i_gen; + inum = htole32(ip->i_number); + gen = htole32(ip->i_gen); crc = calculate_crc32c(fs->e2fs_csum_seed, (uint8_t *)&inum, sizeof(inum)); crc = calculate_crc32c(crc, (uint8_t *)&gen, sizeof(gen)); crc = calculate_crc32c(crc, (uint8_t *)buf, size); @@ -250,7 +256,7 @@ ext2_dirent_csum_verify(struct inode *ip, struct ext2fs_direct_2 *ep) return (0); calculated = ext2_dirent_csum(ip, ep, (char *)tp - (char *)ep); - if (calculated != tp->e2dt_checksum) + if (calculated != le32toh(tp->e2dt_checksum)) return (EIO); return (0); @@ -263,11 +269,11 @@ ext2_get_dx_count(struct inode *ip, struct ext2fs_direct_2 *ep, int *offset) struct ext2fs_htree_root_info *root; 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; - else if (ep->e2d_reclen == 12) { + else if (le16toh(ep->e2d_reclen) == 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); root = (struct ext2fs_htree_root_info *)(((char *)dp + 12)); @@ -302,15 +308,15 @@ ext2_dx_csum(struct inode *ip, struct ext2fs_direct_2 *ep, int count_offset, old_csum = tp->ht_checksum; tp->ht_checksum = 0; - inum = ip->i_number; - gen = ip->i_gen; + inum = htole32(ip->i_number); + gen = htole32(ip->i_gen); crc = calculate_crc32c(fs->e2fs_csum_seed, (uint8_t *)&inum, sizeof(inum)); crc = calculate_crc32c(crc, (uint8_t *)&gen, sizeof(gen)); crc = calculate_crc32c(crc, (uint8_t *)buf, size); crc = calculate_crc32c(crc, (uint8_t *)tp, sizeof(struct ext2fs_htree_tail)); tp->ht_checksum = old_csum; - return (crc); + return htole32(crc); } int @@ -325,8 +331,8 @@ ext2_dx_csum_verify(struct inode *ip, struct ext2fs_direct_2 *ep) if (cp == NULL) return (0); - limit = cp->h_entries_max; - count = cp->h_entries_num; + limit = le16toh(cp->h_entries_max); + count = le16toh(cp->h_entries_num); if (count_offset + (limit * sizeof(struct ext2fs_htree_entry)) > ip->i_e2fs->e2fs_bsize - sizeof(struct ext2fs_htree_tail)) return (EIO); @@ -381,7 +387,7 @@ ext2_dirent_csum_set(struct inode *ip, struct ext2fs_direct_2 *ep) return; tp->e2dt_checksum = - ext2_dirent_csum(ip, ep, (char *)tp - (char *)ep); + htole32(ext2_dirent_csum(ip, ep, (char *)tp - (char *)ep)); } void @@ -401,8 +407,8 @@ ext2_dx_csum_set(struct inode *ip, struct ext2fs_direct_2 *ep) if (cp == NULL) return; - limit = cp->h_entries_max; - count = cp->h_entries_num; + limit = le16toh(cp->h_entries_max); + count = le16toh(cp->h_entries_num); if (count_offset + (limit * sizeof(struct ext2fs_htree_entry)) > ip->i_e2fs->e2fs_bsize - sizeof(struct ext2fs_htree_tail)) return; @@ -423,8 +429,8 @@ ext2_extent_blk_csum(struct inode *ip, struct ext4_extent_header *ehp) size = EXT4_EXTENT_TAIL_OFFSET(ehp) + offsetof(struct ext4_extent_tail, et_checksum); - inum = ip->i_number; - gen = ip->i_gen; + inum = htole32(ip->i_number); + gen = htole32(ip->i_gen); crc = calculate_crc32c(fs->e2fs_csum_seed, (uint8_t *)&inum, sizeof(inum)); crc = calculate_crc32c(crc, (uint8_t *)&gen, sizeof(gen)); crc = calculate_crc32c(crc, (uint8_t *)ehp, size); @@ -449,7 +455,7 @@ ext2_extent_blk_csum_verify(struct inode *ip, void *data) etp = (struct ext4_extent_tail *)(((char *)ehp) + EXT4_EXTENT_TAIL_OFFSET(ehp)); - provided = etp->et_checksum; + provided = le32toh(etp->et_checksum); calculated = ext2_extent_blk_csum(ip, ehp); if (provided != calculated) { @@ -476,8 +482,8 @@ ext2_extent_blk_csum_set(struct inode *ip, void *data) etp = (struct ext4_extent_tail *)(((char *)data) + EXT4_EXTENT_TAIL_OFFSET(ehp)); - etp->et_checksum = ext2_extent_blk_csum(ip, - (struct ext4_extent_header *)data); + etp->et_checksum = htole32(ext2_extent_blk_csum(ip, + (struct ext4_extent_header *)data)); } int @@ -488,11 +494,12 @@ ext2_gd_i_bitmap_csum_verify(struct m_ext2fs *fs, int cg, struct buf *bp) if (!EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) return (0); - provided = fs->e2fs_gd[cg].ext4bgd_i_bmap_csum; + provided = le16toh(fs->e2fs_gd[cg].ext4bgd_i_bmap_csum); calculated = calculate_crc32c(fs->e2fs_csum_seed, bp->b_data, - fs->e2fs->e2fs_ipg / 8); - if (fs->e2fs->e3fs_desc_size >= EXT2_BG_INODE_BITMAP_CSUM_HI_END) { - hi = fs->e2fs_gd[cg].ext4bgd_i_bmap_csum_hi; + fs->e2fs_ipg / 8); + if (le16toh(fs->e2fs->e3fs_desc_size) >= + EXT2_BG_INODE_BITMAP_CSUM_HI_END) { + hi = le16toh(fs->e2fs_gd[cg].ext4bgd_i_bmap_csum_hi); provided |= (hi << 16); } else calculated &= 0xFFFF; @@ -514,10 +521,10 @@ ext2_gd_i_bitmap_csum_set(struct m_ext2fs *fs, int cg, struct buf *bp) return; csum = calculate_crc32c(fs->e2fs_csum_seed, bp->b_data, - fs->e2fs->e2fs_ipg / 8); - fs->e2fs_gd[cg].ext4bgd_i_bmap_csum = csum & 0xFFFF; - if (fs->e2fs->e3fs_desc_size >= EXT2_BG_INODE_BITMAP_CSUM_HI_END) - fs->e2fs_gd[cg].ext4bgd_i_bmap_csum_hi = csum >> 16; + fs->e2fs_ipg / 8); + fs->e2fs_gd[cg].ext4bgd_i_bmap_csum = htole16(csum & 0xFFFF); + if (le16toh(fs->e2fs->e3fs_desc_size) >= EXT2_BG_INODE_BITMAP_CSUM_HI_END) + fs->e2fs_gd[cg].ext4bgd_i_bmap_csum_hi = htole16(csum >> 16); } int @@ -529,10 +536,11 @@ ext2_gd_b_bitmap_csum_verify(struct m_ext2fs *fs, int cg, struct buf *bp) return (0); size = fs->e2fs_fpg / 8; - provided = fs->e2fs_gd[cg].ext4bgd_b_bmap_csum; + provided = le16toh(fs->e2fs_gd[cg].ext4bgd_b_bmap_csum); calculated = calculate_crc32c(fs->e2fs_csum_seed, bp->b_data, size); - if (fs->e2fs->e3fs_desc_size >= EXT2_BG_BLOCK_BITMAP_CSUM_HI_LOCATION) { - hi = fs->e2fs_gd[cg].ext4bgd_b_bmap_csum_hi; + if (le16toh(fs->e2fs->e3fs_desc_size) >= + EXT2_BG_BLOCK_BITMAP_CSUM_HI_LOCATION) { + hi = le16toh(fs->e2fs_gd[cg].ext4bgd_b_bmap_csum_hi); provided |= (hi << 16); } else calculated &= 0xFFFF; @@ -555,9 +563,9 @@ ext2_gd_b_bitmap_csum_set(struct m_ext2fs *fs, int cg, struct buf *bp) size = fs->e2fs_fpg / 8; csum = calculate_crc32c(fs->e2fs_csum_seed, bp->b_data, size); - fs->e2fs_gd[cg].ext4bgd_b_bmap_csum = csum & 0xFFFF; - if (fs->e2fs->e3fs_desc_size >= EXT2_BG_BLOCK_BITMAP_CSUM_HI_LOCATION) - fs->e2fs_gd[cg].ext4bgd_b_bmap_csum_hi = csum >> 16; + fs->e2fs_gd[cg].ext4bgd_b_bmap_csum = htole16(csum & 0xFFFF); + if (le16toh(fs->e2fs->e3fs_desc_size) >= EXT2_BG_BLOCK_BITMAP_CSUM_HI_LOCATION) + fs->e2fs_gd[cg].ext4bgd_b_bmap_csum_hi = htole16(csum >> 16); } static uint32_t @@ -571,10 +579,10 @@ ext2_ei_csum(struct inode *ip, struct ext2fs_dinode *ei) fs = ip->i_e2fs; offset = offsetof(struct ext2fs_dinode, e2di_chksum_lo); csum_size = sizeof(dummy_csum); - inum = ip->i_number; + inum = htole32(ip->i_number); crc = calculate_crc32c(fs->e2fs_csum_seed, (uint8_t *)&inum, sizeof(inum)); - gen = ip->i_gen; + gen = htole32(ip->i_gen); inode_csum_seed = calculate_crc32c(crc, (uint8_t *)&gen, sizeof(gen)); @@ -590,7 +598,8 @@ ext2_ei_csum(struct inode *ip, struct ext2fs_dinode *ei) 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 +624,12 @@ ext2_ei_csum_verify(struct inode *ip, struct ext2fs_dinode *ei) 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 +664,10 @@ ext2_ei_csum_set(struct inode *ip, struct ext2fs_dinode *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 && - 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 @@ -716,6 +725,8 @@ ext2_gd_csum(struct m_ext2fs *fs, uint32_t block_group, struct ext2_gd *gd) offset = offsetof(struct ext2_gd, ext4bgd_csum); + block_group = htole32(block_group); + if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) { csum32 = calculate_crc32c(fs->e2fs_csum_seed, (uint8_t *)&block_group, sizeof(block_group)); @@ -724,12 +735,12 @@ ext2_gd_csum(struct m_ext2fs *fs, uint32_t block_group, struct ext2_gd *gd) csum32 = calculate_crc32c(csum32, (uint8_t *)&dummy_csum, sizeof(dummy_csum)); offset += sizeof(dummy_csum); - if (offset < fs->e2fs->e3fs_desc_size) + if (offset < le16toh(fs->e2fs->e3fs_desc_size)) csum32 = calculate_crc32c(csum32, (uint8_t *)gd + offset, - fs->e2fs->e3fs_desc_size - offset); + le16toh(fs->e2fs->e3fs_desc_size) - offset); crc = csum32 & 0xFFFF; - return (crc); + return (htole16(crc)); } else if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM)) { crc = ext2_crc16(~0, fs->e2fs->e2fs_uuid, sizeof(fs->e2fs->e2fs_uuid)); @@ -738,10 +749,10 @@ ext2_gd_csum(struct m_ext2fs *fs, uint32_t block_group, struct ext2_gd *gd) crc = ext2_crc16(crc, (uint8_t *)gd, offset); offset += sizeof(gd->ext4bgd_csum); /* skip checksum */ if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT) && - offset < fs->e2fs->e3fs_desc_size) + offset < le16toh(fs->e2fs->e3fs_desc_size)) crc = ext2_crc16(crc, (uint8_t *)gd + offset, - fs->e2fs->e3fs_desc_size - offset); - return (crc); + le16toh(fs->e2fs->e3fs_desc_size) - offset); + return (htole16(crc)); } return (0); @@ -774,6 +785,5 @@ ext2_gd_csum_set(struct m_ext2fs *fs) unsigned int i; for (i = 0; i < fs->e2fs_gcount; i++) - fs->e2fs_gd[i].ext4bgd_csum = - ext2_gd_csum(fs, i, &fs->e2fs_gd[i]); + fs->e2fs_gd[i].ext4bgd_csum = ext2_gd_csum(fs, i, &fs->e2fs_gd[i]); } diff --git a/sys/fs/ext2fs/ext2_extattr.c b/sys/fs/ext2fs/ext2_extattr.c index e68eece4799f..c60c9012d5d4 100644 --- a/sys/fs/ext2fs/ext2_extattr.c +++ b/sys/fs/ext2fs/ext2_extattr.c @@ -216,9 +216,9 @@ ext2_extattr_inode_list(struct inode *ip, int attrnamespace, /* 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) { + if (le32toh(header->h_magic) != EXTATTR_MAGIC) { brelse(bp); return (0); } @@ -285,7 +285,8 @@ ext2_extattr_block_list(struct inode *ip, int attrnamespace, /* Check attributes magic value */ header = EXT2_HDR(bp); - if (header->h_magic != EXTATTR_MAGIC || header->h_blocks != 1) { + if (le32toh(header->h_magic) != EXTATTR_MAGIC || + le32toh(header->h_blocks) != 1) { brelse(bp); return (EINVAL); } @@ -356,9 +357,9 @@ ext2_extattr_inode_get(struct inode *ip, int attrnamespace, /* 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) { + if (le32toh(header->h_magic) != EXTATTR_MAGIC) { brelse(bp); return (ENOATTR); } @@ -387,11 +388,12 @@ ext2_extattr_inode_get(struct inode *ip, int attrnamespace, if (strlen(name) == name_len && 0 == strncmp(attr_name, name, name_len)) { if (size != NULL) - *size += entry->e_value_size; + *size += le32toh(entry->e_value_size); if (uio != NULL) error = uiomove(((char *)EXT2_IFIRST(header)) + - entry->e_value_offs, entry->e_value_size, uio); + le16toh(entry->e_value_offs), + le32toh(entry->e_value_size), uio); brelse(bp); return (error); @@ -425,7 +427,8 @@ ext2_extattr_block_get(struct inode *ip, int attrnamespace, /* Check attributes magic value */ header = EXT2_HDR(bp); - if (header->h_magic != EXTATTR_MAGIC || header->h_blocks != 1) { + if (le32toh(header->h_magic) != EXTATTR_MAGIC || + le32toh(header->h_blocks) != 1) { brelse(bp); return (EINVAL); } @@ -453,11 +456,12 @@ ext2_extattr_block_get(struct inode *ip, int attrnamespace, if (strlen(name) == name_len && 0 == strncmp(attr_name, name, name_len)) { if (size != NULL) - *size += entry->e_value_size; + *size += le32toh(entry->e_value_size); if (uio != NULL) - error = uiomove(bp->b_data + entry->e_value_offs, - entry->e_value_size, uio); + error = uiomove(bp->b_data + + le16toh(entry->e_value_offs), + le32toh(entry->e_value_size), uio); brelse(bp); return (error); @@ -480,8 +484,9 @@ ext2_extattr_delete_value(char *off, min_offs = end - off; next = first_entry; while (!EXT2_IS_LAST_ENTRY(next)) { - if (min_offs > next->e_value_offs && next->e_value_offs > 0) - min_offs = next->e_value_offs; + if (min_offs > le16toh(next->e_value_offs) && + le16toh(next->e_value_offs) > 0) + min_offs = le16toh(next->e_value_offs); next = EXT2_EXTATTR_NEXT(next); } @@ -489,22 +494,22 @@ ext2_extattr_delete_value(char *off, if (entry->e_value_size == 0) return (min_offs); - memmove(off + min_offs + EXT2_EXTATTR_SIZE(entry->e_value_size), - off + min_offs, entry->e_value_offs - min_offs); + memmove(off + min_offs + EXT2_EXTATTR_SIZE(le32toh(entry->e_value_size)), + off + min_offs, le16toh(entry->e_value_offs) - min_offs); /* Adjust all value offsets */ next = first_entry; while (!EXT2_IS_LAST_ENTRY(next)) { - if (next->e_value_offs > 0 && - next->e_value_offs < entry->e_value_offs) - next->e_value_offs += - EXT2_EXTATTR_SIZE(entry->e_value_size); + if (le16toh(next->e_value_offs) > 0 && + le16toh(next->e_value_offs) < le16toh(entry->e_value_offs)) + next->e_value_offs = htole16(le16toh(next->e_value_offs) + + EXT2_EXTATTR_SIZE(le32toh(entry->e_value_size))); next = EXT2_EXTATTR_NEXT(next); } - min_offs += EXT2_EXTATTR_SIZE(entry->e_value_size); + min_offs += EXT2_EXTATTR_SIZE(le32toh(entry->e_value_size)); return (min_offs); } @@ -557,9 +562,9 @@ ext2_extattr_inode_delete(struct inode *ip, int attrnamespace, const char *name) /* 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) { + if (le32toh(header->h_magic) != EXTATTR_MAGIC) { brelse(bp); return (ENOATTR); } @@ -635,7 +640,8 @@ ext2_extattr_block_clone(struct inode *ip, struct buf **bpp) sbp = *bpp; header = EXT2_HDR(sbp); - if (header->h_magic != EXTATTR_MAGIC || header->h_refcount == 1) + if (le32toh(header->h_magic) != EXTATTR_MAGIC || + le32toh(header->h_refcount) == 1) return (EINVAL); facl = ext2_alloc_meta(ip); @@ -649,14 +655,14 @@ ext2_extattr_block_clone(struct inode *ip, struct buf **bpp) } memcpy(cbp->b_data, sbp->b_data, fs->e2fs_bsize); - header->h_refcount--; + header->h_refcount = htole32(le32toh(header->h_refcount) - 1); bwrite(sbp); ip->i_facl = facl; ext2_update(ip->i_vnode, 1); header = EXT2_HDR(cbp); - header->h_refcount = 1; + header->h_refcount = htole32(1); *bpp = cbp; @@ -684,7 +690,8 @@ ext2_extattr_block_delete(struct inode *ip, int attrnamespace, const char *name) /* Check attributes magic value */ header = EXT2_HDR(bp); - if (header->h_magic != EXTATTR_MAGIC || header->h_blocks != 1) { + if (le32toh(header->h_magic) != EXTATTR_MAGIC || + le32toh(header->h_blocks) != 1) { brelse(bp); return (EINVAL); } @@ -695,7 +702,7 @@ ext2_extattr_block_delete(struct inode *ip, int attrnamespace, const char *name) return (error); } - if (header->h_refcount > 1) { + if (le32toh(header->h_refcount) > 1) { error = ext2_extattr_block_clone(ip, &bp); if (error) { brelse(bp); @@ -774,10 +781,10 @@ allocate_entry(const char *name, int attrnamespace, uint16_t offs, entry->e_name_len = name_len; entry->e_name_index = ext2_extattr_attrnamespace_to_linux(attrnamespace, name); - entry->e_value_offs = offs; + entry->e_value_offs = htole16(offs); entry->e_value_block = 0; - entry->e_value_size = size; - entry->e_hash = hash; + entry->e_value_size = htole32(size); + entry->e_hash = htole32(hash); memcpy(entry->e_name, name, name_len); return (entry); @@ -811,7 +818,7 @@ ext2_extattr_get_size(struct ext2fs_extattr_entry *first_entry, entry = EXT2_EXTATTR_NEXT(entry)) { if (entry != exist_entry) size += EXT2_EXTATTR_LEN(entry->e_name_len) + - EXT2_EXTATTR_SIZE(entry->e_value_size); + EXT2_EXTATTR_SIZE(le32toh(entry->e_value_size)); else size += EXT2_EXTATTR_LEN(entry->e_name_len) + EXT2_EXTATTR_SIZE(new_size); @@ -830,14 +837,15 @@ ext2_extattr_set_exist_entry(char *off, min_offs = ext2_extattr_delete_value(off, first_entry, entry, end); - entry->e_value_size = uio->uio_resid; - if (entry->e_value_size) - entry->e_value_offs = min_offs - - EXT2_EXTATTR_SIZE(uio->uio_resid); + entry->e_value_size = htole32(uio->uio_resid); + if (le32toh(entry->e_value_size)) + entry->e_value_offs = htole16(min_offs - + EXT2_EXTATTR_SIZE(uio->uio_resid)); else entry->e_value_offs = 0; - uiomove(off + entry->e_value_offs, entry->e_value_size, uio); + uiomove(off + le16toh(entry->e_value_offs), + le32toh(entry->e_value_size), uio); } static struct ext2fs_extattr_entry * @@ -854,8 +862,9 @@ ext2_extattr_set_new_entry(char *off, struct ext2fs_extattr_entry *first_entry, min_offs = end - off; entry = first_entry; while (!EXT2_IS_LAST_ENTRY(entry)) { - if (min_offs > entry->e_value_offs && entry->e_value_offs > 0) - min_offs = entry->e_value_offs; + if (min_offs > le16toh(entry->e_value_offs) && + le16toh(entry->e_value_offs) > 0) + min_offs = le16toh(entry->e_value_offs); entry = EXT2_EXTATTR_NEXT(entry); } @@ -883,11 +892,12 @@ ext2_extattr_set_new_entry(char *off, struct ext2fs_extattr_entry *first_entry, free_entry(new_entry); new_entry = entry; - if (new_entry->e_value_size > 0) - new_entry->e_value_offs = min_offs - - EXT2_EXTATTR_SIZE(new_entry->e_value_size); + if (le32toh(new_entry->e_value_size) > 0) + new_entry->e_value_offs = htole16(min_offs - + EXT2_EXTATTR_SIZE(le32toh(new_entry->e_value_size))); - uiomove(off + new_entry->e_value_offs, new_entry->e_value_size, uio); + uiomove(off + le16toh(new_entry->e_value_offs), + le32toh(new_entry->e_value_size), uio); return (new_entry); } @@ -920,9 +930,9 @@ ext2_extattr_inode_set(struct inode *ip, int attrnamespace, /* 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) { + if (le32toh(header->h_magic) != EXTATTR_MAGIC) { brelse(bp); return (ENOSPC); } @@ -955,7 +965,7 @@ ext2_extattr_inode_set(struct inode *ip, int attrnamespace, } 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, @@ -1013,16 +1023,17 @@ ext2_extattr_hash_entry(struct ext2fs_extattr_header *header, } if (entry->e_value_block == 0 && entry->e_value_size != 0) { - uint32_t *value = (uint32_t *)((char *)header + entry->e_value_offs); - for (n = (entry->e_value_size + + uint32_t *value = (uint32_t *)((char *)header + + le16toh(entry->e_value_offs)); + for (n = (le32toh(entry->e_value_size) + EXT2_EXTATTR_ROUND) >> EXT2_EXTATTR_PAD_BITS; n; n--) { hash = (hash << EXT2_EXTATTR_VALUE_HASH_SHIFT) ^ (hash >> (8*sizeof(hash) - EXT2_EXTATTR_VALUE_HASH_SHIFT)) ^ - (*value++); + le32toh(*value++); } } - entry->e_hash = hash; + entry->e_hash = htole32(hash); } static void @@ -1036,7 +1047,7 @@ ext2_extattr_rehash(struct ext2fs_extattr_header *header, here = EXT2_ENTRY(header+1); while (!EXT2_IS_LAST_ENTRY(here)) { - if (!here->e_hash) { + if (here->e_hash == 0) { /* Block is not shared if an entry's hash value == 0 */ hash = 0; break; @@ -1044,12 +1055,12 @@ ext2_extattr_rehash(struct ext2fs_extattr_header *header, hash = (hash << EXT2_EXTATTR_BLOCK_HASH_SHIFT) ^ (hash >> (8*sizeof(hash) - EXT2_EXTATTR_BLOCK_HASH_SHIFT)) ^ - here->e_hash; + le32toh(here->e_hash); here = EXT2_EXTATTR_NEXT(here); } - header->h_hash = hash; + header->h_hash = htole32(hash); } int @@ -1076,7 +1087,8 @@ ext2_extattr_block_set(struct inode *ip, int attrnamespace, /* Check attributes magic value */ header = EXT2_HDR(bp); - if (header->h_magic != EXTATTR_MAGIC || header->h_blocks != 1) { + if (le32toh(header->h_magic) != EXTATTR_MAGIC || + le32toh(header->h_blocks) != 1) { brelse(bp); return (EINVAL); } @@ -1087,7 +1099,7 @@ ext2_extattr_block_set(struct inode *ip, int attrnamespace, return (error); } - if (header->h_refcount > 1) { + if (le32toh(header->h_refcount) > 1) { error = ext2_extattr_block_clone(ip, &bp); if (error) { brelse(bp); @@ -1178,9 +1190,9 @@ ext2_extattr_block_set(struct inode *ip, int attrnamespace, } header = EXT2_HDR(bp); - header->h_magic = EXTATTR_MAGIC; - header->h_refcount = 1; - header->h_blocks = 1; + header->h_magic = htole32(EXTATTR_MAGIC); + header->h_refcount = htole32(1); + header->h_blocks = htole32(1); header->h_hash = 0; memset(header->h_reserved, 0, sizeof(header->h_reserved)); memcpy(bp->b_data, header, sizeof(struct ext2fs_extattr_header)); @@ -1222,7 +1234,8 @@ int ext2_extattr_free(struct inode *ip) /* Check attributes magic value */ header = EXT2_HDR(bp); - if (header->h_magic != EXTATTR_MAGIC || header->h_blocks != 1) { + if (le32toh(header->h_magic) != EXTATTR_MAGIC || + le32toh(header->h_blocks) != 1) { brelse(bp); return (EINVAL); } @@ -1234,8 +1247,8 @@ int ext2_extattr_free(struct inode *ip) return (error); } - if (header->h_refcount > 1) { - header->h_refcount--; + if (le32toh(header->h_refcount) > 1) { + header->h_refcount = htole32(le32toh(header->h_refcount) - 1); bwrite(bp); } else { ext2_blkfree(ip, ip->i_facl, ip->i_e2fs->e2fs_bsize); diff --git a/sys/fs/ext2fs/ext2_extents.c b/sys/fs/ext2fs/ext2_extents.c index ec2dae8f6dbe..2aa9d6e13ac8 100644 --- a/sys/fs/ext2fs/ext2_extents.c +++ b/sys/fs/ext2fs/ext2_extents.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -63,8 +64,8 @@ ext4_ext_print_extent(struct ext4_extent *ep) { printf(" ext %p => (blk %u len %u start %ju)\n", - ep, ep->e_blk, ep->e_len, - (uint64_t)ep->e_start_hi << 32 | ep->e_start_lo); + ep, le32toh(ep->e_blk), le16toh(ep->e_len), + (uint64_t)le16toh(ep->e_start_hi) << 32 | le32toh(ep->e_start_lo)); } static void ext4_ext_print_header(struct inode *ip, struct ext4_extent_header *ehp); @@ -79,14 +80,15 @@ ext4_ext_print_index(struct inode *ip, struct ext4_extent_index *ex, int do_walk fs = ip->i_e2fs; printf(" index %p => (blk %u pblk %ju)\n", - ex, ex->ei_blk, (uint64_t)ex->ei_leaf_hi << 32 | ex->ei_leaf_lo); + ex, le32toh(ex->ei_blk), (uint64_t)le16toh(ex->ei_leaf_hi) << 32 | + le32toh(ex->ei_leaf_lo)); if(!do_walk) return; if ((error = bread(ip->i_devvp, - fsbtodb(fs, ((uint64_t)ex->ei_leaf_hi << 32 | ex->ei_leaf_lo)), - (int)fs->e2fs_bsize, NOCRED, &bp)) != 0) { + fsbtodb(fs, ((uint64_t)le16toh(ex->ei_leaf_hi) << 32 | + le32toh(ex->ei_leaf_lo))), (int)fs->e2fs_bsize, NOCRED, &bp)) != 0) { brelse(bp); return; } @@ -103,10 +105,10 @@ ext4_ext_print_header(struct inode *ip, struct ext4_extent_header *ehp) int i; printf("header %p => (magic 0x%x entries %d max %d depth %d gen %d)\n", - ehp, ehp->eh_magic, ehp->eh_ecount, ehp->eh_max, ehp->eh_depth, - ehp->eh_gen); + ehp, le16toh(ehp->eh_magic), le16toh(ehp->eh_ecount), + le16toh(ehp->eh_max), le16toh(ehp->eh_depth), le32toh(ehp->eh_gen)); - for (i = 0; i < ehp->eh_ecount; i++) + for (i = 0; i < le16toh(ehp->eh_ecount); i++) if (ehp->eh_depth != 0) ext4_ext_print_index(ip, (struct ext4_extent_index *)(ehp + 1 + i), 1); @@ -168,7 +170,7 @@ ext4_ext_inode_depth(struct inode *ip) struct ext4_extent_header *ehp; ehp = (struct ext4_extent_header *)ip->i_data; - return (ehp->eh_depth); + return (le16toh(ehp->eh_depth)); } static inline e4fs_daddr_t @@ -176,8 +178,8 @@ ext4_ext_index_pblock(struct ext4_extent_index *index) { e4fs_daddr_t blk; - blk = index->ei_leaf_lo; - blk |= (e4fs_daddr_t)index->ei_leaf_hi << 32; + blk = le32toh(index->ei_leaf_lo); + blk |= (e4fs_daddr_t)le16toh(index->ei_leaf_hi) << 32; return (blk); } @@ -186,8 +188,8 @@ static inline void ext4_index_store_pblock(struct ext4_extent_index *index, e4fs_daddr_t pb) { - index->ei_leaf_lo = pb & 0xffffffff; - index->ei_leaf_hi = (pb >> 32) & 0xffff; + index->ei_leaf_lo = htole32(pb & 0xffffffff); + index->ei_leaf_hi = htole16((pb >> 32) & 0xffff); } @@ -196,8 +198,8 @@ ext4_ext_extent_pblock(struct ext4_extent *extent) { e4fs_daddr_t blk; - blk = extent->e_start_lo; - blk |= (e4fs_daddr_t)extent->e_start_hi << 32; + blk = le32toh(extent->e_start_lo); + blk |= (e4fs_daddr_t)le16toh(extent->e_start_hi) << 32; return (blk); } @@ -206,8 +208,8 @@ static inline void ext4_ext_store_pblock(struct ext4_extent *ex, e4fs_daddr_t pb) { - ex->e_start_lo = pb & 0xffffffff; - ex->e_start_hi = (pb >> 32) & 0xffff; + ex->e_start_lo = htole32(pb & 0xffffffff); + ex->e_start_hi = htole16((pb >> 32) & 0xffff); } int @@ -221,10 +223,10 @@ ext4_ext_in_cache(struct inode *ip, daddr_t lbn, struct ext4_extent *ep) return (ret); if (lbn >= ecp->ec_blk && lbn < ecp->ec_blk + ecp->ec_len) { - ep->e_blk = ecp->ec_blk; - ep->e_start_lo = ecp->ec_start & 0xffffffff; - ep->e_start_hi = ecp->ec_start >> 32 & 0xffff; - ep->e_len = ecp->ec_len; + ep->e_blk = htole32(ecp->ec_blk); + ep->e_start_lo = htole32(ecp->ec_start & 0xffffffff); + ep->e_start_hi = htole16(ecp->ec_start >> 32 & 0xffff); + ep->e_len = htole16(ecp->ec_len); ret = ecp->ec_type; } return (ret); @@ -238,7 +240,7 @@ ext4_ext_check_header(struct inode *ip, struct ext4_extent_header *eh) fs = ip->i_e2fs; - if (eh->eh_magic != EXT4_EXT_MAGIC) { + if (le16toh(eh->eh_magic) != EXT4_EXT_MAGIC) { error_msg = "header: invalid magic"; goto corrupted; } @@ -246,7 +248,7 @@ ext4_ext_check_header(struct inode *ip, struct ext4_extent_header *eh) error_msg = "header: invalid eh_max"; goto corrupted; } - if (eh->eh_ecount > eh->eh_max) { + if (le16toh(eh->eh_ecount) > le16toh(eh->eh_max)) { error_msg = "header: invalid eh_entries"; goto corrupted; } @@ -266,14 +268,15 @@ ext4_ext_binsearch_index(struct ext4_extent_path *path, int blk) eh = path->ep_header; - KASSERT(eh->eh_ecount <= eh->eh_max && eh->eh_ecount > 0, + KASSERT(le16toh(eh->eh_ecount) <= le16toh(eh->eh_max) && + le16toh(eh->eh_ecount) > 0, ("ext4_ext_binsearch_index: bad args")); l = EXT_FIRST_INDEX(eh) + 1; - r = EXT_FIRST_INDEX(eh) + eh->eh_ecount - 1; + r = EXT_FIRST_INDEX(eh) + le16toh(eh->eh_ecount) - 1; while (l <= r) { m = l + (r - l) / 2; - if (blk < m->ei_blk) + if (blk < le32toh(m->ei_blk)) r = m - 1; else l = m + 1; @@ -290,18 +293,18 @@ ext4_ext_binsearch_ext(struct ext4_extent_path *path, int blk) eh = path->ep_header; - KASSERT(eh->eh_ecount <= eh->eh_max, + KASSERT(le16toh(eh->eh_ecount) <= le16toh(eh->eh_max), ("ext4_ext_binsearch_ext: bad args")); if (eh->eh_ecount == 0) return; l = EXT_FIRST_EXTENT(eh) + 1; - r = EXT_FIRST_EXTENT(eh) + eh->eh_ecount - 1; + r = EXT_FIRST_EXTENT(eh) + le16toh(eh->eh_ecount) - 1; while (l <= r) { m = l + (r - l) / 2; - if (blk < m->e_blk) + if (blk < le32toh(m->e_blk)) r = m - 1; else l = m + 1; @@ -513,8 +516,8 @@ ext4_ext_tree_init(struct inode *ip) memset(ip->i_data, 0, EXT2_NDADDR + EXT2_NIADDR); ehp = (struct ext4_extent_header *)ip->i_data; - ehp->eh_magic = EXT4_EXT_MAGIC; - ehp->eh_max = ext4_ext_space_root(ip); + ehp->eh_magic = htole16(EXT4_EXT_MAGIC); + ehp->eh_max = htole16(ext4_ext_space_root(ip)); ip->i_ext_cache.ec_type = EXT4_EXT_CACHE_NO; ip->i_flag |= IN_CHANGE | IN_UPDATE; ext2_update(ip->i_vnode, 1); @@ -549,7 +552,7 @@ ext4_ext_blkpref(struct inode *ip, struct ext4_extent_path *path, ex = path[depth].ep_ext; if (ex) { e4fs_daddr_t pblk = ext4_ext_extent_pblock(ex); - e2fs_daddr_t blk = ex->e_blk; + e2fs_daddr_t blk = le32toh(ex->e_blk); if (block > blk) return (pblk + (block - blk)); @@ -564,7 +567,7 @@ ext4_ext_blkpref(struct inode *ip, struct ext4_extent_path *path, /* Use inode's group. */ bg_start = (ip->i_block_group * EXT2_BLOCKS_PER_GROUP(ip->i_e2fs)) + - fs->e2fs->e2fs_first_dblock; + le32toh(fs->e2fs->e2fs_first_dblock); return (bg_start + block); } @@ -574,13 +577,13 @@ ext4_can_extents_be_merged(struct ext4_extent *ex1, struct ext4_extent *ex2) { - if (ex1->e_blk + ex1->e_len != ex2->e_blk) + if (le32toh(ex1->e_blk) + le16toh(ex1->e_len) != le32toh(ex2->e_blk)) return (0); - if (ex1->e_len + ex2->e_len > EXT4_MAX_LEN) + if (le16toh(ex1->e_len) + le16toh(ex2->e_len) > EXT4_MAX_LEN) return (0); - if (ext4_ext_extent_pblock(ex1) + ex1->e_len == + if (ext4_ext_extent_pblock(ex1) + le16toh(ex1->e_len) == ext4_ext_extent_pblock(ex2)) return (1); @@ -602,7 +605,7 @@ ext4_ext_next_leaf_block(struct inode *ip, struct ext4_extent_path *path) while (depth >= 0) { if (path[depth].ep_index != EXT_LAST_INDEX(path[depth].ep_header)) - return (path[depth].ep_index[1].ei_blk); + return (le32toh(path[depth].ep_index[1].ei_blk)); depth--; } @@ -650,19 +653,20 @@ ext4_ext_insert_index(struct inode *ip, struct ext4_extent_path *path, fs = ip->i_e2fs; - if (lblk == path->ep_index->ei_blk) { + if (lblk == le32toh(path->ep_index->ei_blk)) { SDT_PROBE2(ext2fs, , trace, extents, 1, "lblk == index blk => extent corrupted"); return (EIO); } - if (path->ep_header->eh_ecount >= path->ep_header->eh_max) { + if (le16toh(path->ep_header->eh_ecount) >= + le16toh(path->ep_header->eh_max)) { SDT_PROBE2(ext2fs, , trace, extents, 1, "ecout > maxcount => extent corrupted"); return (EIO); } - if (lblk > path->ep_index->ei_blk) { + if (lblk > le32toh(path->ep_index->ei_blk)) { /* Insert after. */ idx = path->ep_index + 1; } else { @@ -680,9 +684,10 @@ ext4_ext_insert_index(struct inode *ip, struct ext4_extent_path *path, return (EIO); } - idx->ei_blk = lblk; + idx->ei_blk = htole32(lblk); ext4_index_store_pblock(idx, blk); - path->ep_header->eh_ecount++; + path->ep_header->eh_ecount = + htole16(le16toh(path->ep_header->eh_ecount) + 1); return (ext4_ext_dirty(ip, path)); } @@ -750,9 +755,9 @@ ext4_ext_split(struct inode *ip, struct ext4_extent_path *path, } if (path[depth].ep_ext != EXT_MAX_EXTENT(path[depth].ep_header)) - border = path[depth].ep_ext[1].e_blk; + border = le32toh(path[depth].ep_ext[1].e_blk); else - border = newext->e_blk; + border = le32toh(newext->e_blk); /* Allocate new blocks. */ ablks = malloc(sizeof(e4fs_daddr_t) * depth, @@ -775,12 +780,13 @@ ext4_ext_split(struct inode *ip, struct ext4_extent_path *path, neh = ext4_ext_block_header(bp->b_data); neh->eh_ecount = 0; - neh->eh_max = ext4_ext_space_block(ip); - neh->eh_magic = EXT4_EXT_MAGIC; + neh->eh_max = le16toh(ext4_ext_space_block(ip)); + neh->eh_magic = le16toh(EXT4_EXT_MAGIC); neh->eh_depth = 0; ex = EXT_FIRST_EXTENT(neh); - if (path[depth].ep_header->eh_ecount != path[depth].ep_header->eh_max) { + if (le16toh(path[depth].ep_header->eh_ecount) != + le16toh(path[depth].ep_header->eh_max)) { SDT_PROBE2(ext2fs, , trace, extents, 1, "extents count out of range => extent corrupted"); error = EIO; @@ -797,7 +803,7 @@ ext4_ext_split(struct inode *ip, struct ext4_extent_path *path, if (m) { memmove(ex, path[depth].ep_ext - m, sizeof(struct ext4_extent) * m); - neh->eh_ecount = neh->eh_ecount + m; + neh->eh_ecount = htole16(le16toh(neh->eh_ecount) + m); } ext2_extent_blk_csum_set(ip, bp->b_data); @@ -807,7 +813,7 @@ ext4_ext_split(struct inode *ip, struct ext4_extent_path *path, /* Fix old leaf. */ if (m) { path[depth].ep_header->eh_ecount = - path[depth].ep_header->eh_ecount - m; + htole16(le16toh(path[depth].ep_header->eh_ecount) - m); ext4_ext_dirty(ip, path + depth); } @@ -827,12 +833,12 @@ ext4_ext_split(struct inode *ip, struct ext4_extent_path *path, } neh = (struct ext4_extent_header *)bp->b_data; - neh->eh_ecount = 1; - neh->eh_magic = EXT4_EXT_MAGIC; - neh->eh_max = ext4_ext_space_block_index(ip); - neh->eh_depth = depth - i; + neh->eh_ecount = htole16(1); + neh->eh_magic = htole16(EXT4_EXT_MAGIC); + neh->eh_max = htole16(ext4_ext_space_block_index(ip)); + neh->eh_depth = htole16(depth - i); fidx = EXT_FIRST_INDEX(neh); - fidx->ei_blk = border; + fidx->ei_blk = htole32(border); ext4_index_store_pblock(fidx, oldblk); m = 0; @@ -844,7 +850,7 @@ ext4_ext_split(struct inode *ip, struct ext4_extent_path *path, if (m) { memmove(++fidx, path[i].ep_index - m, sizeof(struct ext4_extent_index) * m); - neh->eh_ecount = neh->eh_ecount + m; + neh->eh_ecount = htole16(le16toh(neh->eh_ecount) + m); } ext2_extent_blk_csum_set(ip, bp->b_data); @@ -854,7 +860,7 @@ ext4_ext_split(struct inode *ip, struct ext4_extent_path *path, /* Fix old index. */ if (m) { path[i].ep_header->eh_ecount = - path[i].ep_header->eh_ecount - m; + htole16(le16toh(path[i].ep_header->eh_ecount) - m); ext4_ext_dirty(ip, path + i); } @@ -907,12 +913,12 @@ ext4_ext_grow_indepth(struct inode *ip, struct ext4_extent_path *path, /* Set size of new block */ neh = ext4_ext_block_header(bp->b_data); - neh->eh_magic = EXT4_EXT_MAGIC; + neh->eh_magic = htole16(EXT4_EXT_MAGIC); if (ext4_ext_inode_depth(ip)) - neh->eh_max = ext4_ext_space_block_index(ip); + neh->eh_max = htole16(ext4_ext_space_block_index(ip)); else - neh->eh_max = ext4_ext_space_block(ip); + neh->eh_max = htole16(ext4_ext_space_block(ip)); ext2_extent_blk_csum_set(ip, bp->b_data); error = bwrite(bp); @@ -921,15 +927,15 @@ ext4_ext_grow_indepth(struct inode *ip, struct ext4_extent_path *path, bp = NULL; - curpath->ep_header->eh_magic = EXT4_EXT_MAGIC; - curpath->ep_header->eh_max = ext4_ext_space_root(ip); - curpath->ep_header->eh_ecount = 1; + curpath->ep_header->eh_magic = htole16(EXT4_EXT_MAGIC); + curpath->ep_header->eh_max = htole16(ext4_ext_space_root(ip)); + curpath->ep_header->eh_ecount = htole16(1); curpath->ep_index = EXT_FIRST_INDEX(curpath->ep_header); curpath->ep_index->ei_blk = EXT_FIRST_EXTENT(path[0].ep_header)->e_blk; ext4_index_store_pblock(curpath->ep_index, newblk); neh = ext4_ext_inode_header(ip); - neh->eh_depth = path->ep_depth + 1; + neh->eh_depth = htole16(path->ep_depth + 1); ext4_ext_dirty(ip, curpath); out: brelse(bp); @@ -965,7 +971,7 @@ ext4_ext_create_new_leaf(struct inode *ip, struct ext4_extent_path *path, /* Refill path. */ ext4_ext_drop_refs(path); - error = ext4_ext_find_extent(ip, newext->e_blk, &path); + error = ext4_ext_find_extent(ip, le32toh(newext->e_blk), &path); if (error) goto out; } else { @@ -976,14 +982,14 @@ ext4_ext_create_new_leaf(struct inode *ip, struct ext4_extent_path *path, /* Refill path. */ ext4_ext_drop_refs(path); - error = ext4_ext_find_extent(ip, newext->e_blk, &path); + error = ext4_ext_find_extent(ip, le32toh(newext->e_blk), &path); if (error) goto out; /* Check and split tree if required. */ depth = ext4_ext_inode_depth(ip); - if (path[depth].ep_header->eh_ecount == - path[depth].ep_header->eh_max) + if (le16toh(path[depth].ep_header->eh_ecount) == + le16toh(path[depth].ep_header->eh_max)) goto repeat; } @@ -1014,15 +1020,15 @@ ext4_ext_correct_indexes(struct inode *ip, struct ext4_extent_path *path) return (0); k = depth - 1; - border = path[depth].ep_ext->e_blk; - path[k].ep_index->ei_blk = border; + border = le32toh(path[depth].ep_ext->e_blk); + path[k].ep_index->ei_blk = htole32(border); ext4_ext_dirty(ip, path + k); while (k--) { /* Change all left-side indexes. */ if (path[k+1].ep_index != EXT_FIRST_INDEX(path[k+1].ep_header)) break; - path[k].ep_index->ei_blk = border; + path[k].ep_index->ei_blk = htole32(border); ext4_ext_dirty(ip, path + k); } @@ -1042,12 +1048,12 @@ ext4_ext_insert_extent(struct inode *ip, struct ext4_extent_path *path, ex = path[depth].ep_ext; npath = NULL; - if (newext->e_len == 0 || path[depth].ep_header == NULL) + if (htole16(newext->e_len) == 0 || path[depth].ep_header == NULL) return (EINVAL); /* Insert block into found extent. */ if (ex && ext4_can_extents_be_merged(ex, newext)) { - ex->e_len = ex->e_len + newext->e_len; + ex->e_len = htole16(le16toh(ex->e_len) + le16toh(newext->e_len)); eh = path[depth].ep_header; nearex = ex; goto merge; @@ -1056,13 +1062,14 @@ ext4_ext_insert_extent(struct inode *ip, struct ext4_extent_path *path, repeat: depth = ext4_ext_inode_depth(ip); eh = path[depth].ep_header; - if (eh->eh_ecount < eh->eh_max) + if (le16toh(eh->eh_ecount) < le16toh(eh->eh_max)) goto has_space; /* Try next leaf */ nex = EXT_LAST_EXTENT(eh); next = ext4_ext_next_leaf_block(ip, path); - if (newext->e_blk > nex->e_blk && next != EXT4_MAX_BLOCKS) { + if (le32toh(newext->e_blk) > le32toh(nex->e_blk) && next != + EXT4_MAX_BLOCKS) { KASSERT(npath == NULL, ("ext4_ext_insert_extent: bad path")); @@ -1076,7 +1083,7 @@ ext4_ext_insert_extent(struct inode *ip, struct ext4_extent_path *path, } eh = npath[depth].ep_header; - if (eh->eh_ecount < eh->eh_max) { + if (le16toh(eh->eh_ecount) < le16toh(eh->eh_max)) { path = npath; goto repeat; } @@ -1098,7 +1105,7 @@ ext4_ext_insert_extent(struct inode *ip, struct ext4_extent_path *path, if (!nearex) { /* Create new extent in the leaf. */ path[depth].ep_ext = EXT_FIRST_EXTENT(eh); - } else if (newext->e_blk > nearex->e_blk) { + } else if (le32toh(newext->e_blk) > le32toh(nearex->e_blk)) { if (nearex != EXT_LAST_EXTENT(eh)) { len = EXT_MAX_EXTENT(eh) - nearex; len = (len - 1) * sizeof(struct ext4_extent); @@ -1113,7 +1120,7 @@ ext4_ext_insert_extent(struct inode *ip, struct ext4_extent_path *path, path[depth].ep_ext = nearex; } - eh->eh_ecount = eh->eh_ecount + 1; + eh->eh_ecount = htole16(le16toh(eh->eh_ecount) + 1); nearex = path[depth].ep_ext; nearex->e_blk = newext->e_blk; nearex->e_start_lo = newext->e_start_lo; @@ -1127,15 +1134,16 @@ ext4_ext_insert_extent(struct inode *ip, struct ext4_extent_path *path, break; /* Merge with next extent. */ - nearex->e_len = nearex->e_len + nearex[1].e_len; + nearex->e_len = htole16(le16toh(nearex->e_len) + + le16toh(nearex[1].e_len)); if (nearex + 1 < EXT_LAST_EXTENT(eh)) { len = (EXT_LAST_EXTENT(eh) - nearex - 1) * sizeof(struct ext4_extent); memmove(nearex + 1, nearex + 2, len); } - eh->eh_ecount = eh->eh_ecount - 1; - KASSERT(eh->eh_ecount != 0, + eh->eh_ecount = htole16(le16toh(eh->eh_ecount) - 1); + KASSERT(le16toh(eh->eh_ecount) != 0, ("ext4_ext_insert_extent: bad ecount")); } @@ -1208,9 +1216,9 @@ ext4_ext_get_blocks(struct inode *ip, e4fs_daddr_t iblk, if ((bpref = ext4_ext_in_cache(ip, iblk, &newex))) { if (bpref == EXT4_EXT_CACHE_IN) { /* Block is already allocated. */ - newblk = iblk - newex.e_blk + + newblk = iblk - le32toh(newex.e_blk) + ext4_ext_extent_pblock(&newex); - allocated = newex.e_len - (iblk - newex.e_blk); + allocated = le16toh(newex.e_len) - (iblk - le32toh(newex.e_blk)); goto out; } else { error = EIO; @@ -1230,8 +1238,8 @@ ext4_ext_get_blocks(struct inode *ip, e4fs_daddr_t iblk, } if ((ex = path[depth].ep_ext)) { - uint64_t lblk = ex->e_blk; - uint16_t e_len = ex->e_len; + uint64_t lblk = le32toh(ex->e_blk); + uint16_t e_len = le16toh(ex->e_len); e4fs_daddr_t e_start = ext4_ext_extent_pblock(ex); if (e_len > EXT4_MAX_LEN) @@ -1259,9 +1267,9 @@ ext4_ext_get_blocks(struct inode *ip, e4fs_daddr_t iblk, goto out2; /* Try to insert new extent into found leaf and return. */ - newex.e_blk = iblk; + newex.e_blk = htole32(iblk); ext4_ext_store_pblock(&newex, newblk); - newex.e_len = allocated; + newex.e_len = htole16(allocated); error = ext4_ext_insert_extent(ip, path, &newex); if (error) goto out2; @@ -1302,8 +1310,8 @@ static inline uint16_t ext4_ext_get_actual_len(struct ext4_extent *ext) { - return (ext->e_len <= EXT_INIT_MAX_LEN ? - ext->e_len : (ext->e_len - EXT_INIT_MAX_LEN)); + return (le16toh(ext->e_len) <= EXT_INIT_MAX_LEN ? + le16toh(ext->e_len) : (le16toh(ext->e_len) - EXT_INIT_MAX_LEN)); } static inline struct ext4_extent_header * @@ -1319,10 +1327,10 @@ ext4_remove_blocks(struct inode *ip, struct ext4_extent *ex, { unsigned long num, start; - if (from >= ex->e_blk && - to == ex->e_blk + ext4_ext_get_actual_len(ex) - 1) { + if (from >= le32toh(ex->e_blk) && + to == le32toh(ex->e_blk) + ext4_ext_get_actual_len(ex) - 1) { /* Tail cleanup. */ - num = ex->e_blk + ext4_ext_get_actual_len(ex) - from; + num = le32toh(ex->e_blk) + ext4_ext_get_actual_len(ex) - from; start = ext4_ext_extent_pblock(ex) + ext4_ext_get_actual_len(ex) - num; ext4_ext_blkfree(ip, start, num, 0); @@ -1341,7 +1349,8 @@ ext4_ext_rm_index(struct inode *ip, struct ext4_extent_path *path) leaf = ext4_ext_index_pblock(path->ep_index); KASSERT(path->ep_header->eh_ecount != 0, ("ext4_ext_rm_index: bad ecount")); - path->ep_header->eh_ecount--; + path->ep_header->eh_ecount = + htole16(le16toh(path->ep_header->eh_ecount) - 1); ext4_ext_dirty(ip, path); ext4_ext_blkfree(ip, leaf, 1, 0); return (0); @@ -1375,7 +1384,7 @@ ext4_ext_rm_leaf(struct inode *ip, struct ext4_extent_path *path, } ex = EXT_LAST_EXTENT(eh); - ex_blk = ex->e_blk; + ex_blk = le32toh(ex->e_blk); ex_len = ext4_ext_get_actual_len(ex); error = 0; @@ -1410,27 +1419,28 @@ ext4_ext_rm_leaf(struct inode *ip, struct ext4_extent_path *path, if (num == 0) { ext4_ext_store_pblock(ex, 0); - eh->eh_ecount--; + eh->eh_ecount = htole16(le16toh(eh->eh_ecount) - 1); } - ex->e_blk = block; - ex->e_len = num; + ex->e_blk = htole32(block); + ex->e_len = htole16(num); ext4_ext_dirty(ip, path + depth); ex--; - ex_blk = ex->e_blk; + ex_blk = htole32(ex->e_blk); ex_len = ext4_ext_get_actual_len(ex); }; - if (correct_index && eh->eh_ecount) + if (correct_index && le16toh(eh->eh_ecount)) error = ext4_ext_correct_indexes(ip, path); /* * If this leaf is free, we should * remove it from index block above. */ - if (error == 0 && eh->eh_ecount == 0 && path[depth].ep_data != NULL) + if (error == 0 && eh->eh_ecount == 0 && + path[depth].ep_data != NULL) error = ext4_ext_rm_index(ip, path + depth); out: @@ -1454,7 +1464,7 @@ ext4_read_extent_tree_block(struct inode *ip, e4fs_daddr_t pblk, } eh = ext4_ext_block_header(bp->b_data); - if (eh->eh_depth != depth) { + if (le16toh(eh->eh_depth) != depth) { SDT_PROBE2(ext2fs, , trace, extents, 1, "unexpected eh_depth"); goto err; @@ -1482,7 +1492,7 @@ ext4_ext_more_to_rm(struct ext4_extent_path *path) if (path->ep_index < EXT_FIRST_INDEX(path->ep_header)) return (0); - if (path->ep_header->eh_ecount == path->index_count) + if (le16toh(path->ep_header->eh_ecount) == path->index_count) return (0); return (1); @@ -1533,7 +1543,8 @@ ext4_ext_remove_space(struct inode *ip, off_t length, int flags, if (!path[i].ep_index) { /* This level hasn't touched yet. */ path[i].ep_index = EXT_LAST_INDEX(path[i].ep_header); - path[i].index_count = path[i].ep_header->eh_ecount + 1; + path[i].index_count = + le16toh(path[i].ep_header->eh_ecount) + 1; } else { /* We've already was here, see at next index. */ path[i].ep_index--; @@ -1552,7 +1563,8 @@ ext4_ext_remove_space(struct inode *ip, off_t length, int flags, ext4_ext_fill_path_bdata(&path[i+1], bp, ext4_ext_index_pblock(path[i].ep_index)); brelse(bp); - path[i].index_count = path[i].ep_header->eh_ecount; + path[i].index_count = + le16toh(path[i].ep_header->eh_ecount); i++; } else { if (path[i].ep_header->eh_ecount == 0 && i > 0) { @@ -1570,7 +1582,7 @@ ext4_ext_remove_space(struct inode *ip, off_t length, int flags, * Truncate the tree to zero. */ ext4_ext_header(ip)->eh_depth = 0; - ext4_ext_header(ip)->eh_max = ext4_ext_space_root(ip); + ext4_ext_header(ip)->eh_max = htole16(ext4_ext_space_root(ip)); ext4_ext_dirty(ip, path); } diff --git a/sys/fs/ext2fs/ext2_extents.h b/sys/fs/ext2fs/ext2_extents.h index 0a145b248788..52a96297b606 100644 --- a/sys/fs/ext2fs/ext2_extents.h +++ b/sys/fs/ext2fs/ext2_extents.h @@ -108,14 +108,14 @@ struct ext4_extent_path { sizeof(struct ext4_extent_header))) #define EXT_FIRST_INDEX(hdr) ((struct ext4_extent_index *)(((char *)(hdr)) + \ sizeof(struct ext4_extent_header))) -#define EXT_LAST_EXTENT(hdr) (EXT_FIRST_EXTENT((hdr)) + (hdr)->eh_ecount - 1) -#define EXT_LAST_INDEX(hdr) (EXT_FIRST_INDEX((hdr)) + (hdr)->eh_ecount - 1) +#define EXT_LAST_EXTENT(hdr) (EXT_FIRST_EXTENT((hdr)) + le16toh((hdr)->eh_ecount) - 1) +#define EXT_LAST_INDEX(hdr) (EXT_FIRST_INDEX((hdr)) + le16toh((hdr)->eh_ecount) - 1) #define EXT4_EXTENT_TAIL_OFFSET(hdr) (sizeof(struct ext4_extent_header) + \ - (sizeof(struct ext4_extent) * (hdr)->eh_max)) + (sizeof(struct ext4_extent) * le16toh((hdr)->eh_max))) #define EXT_HAS_FREE_INDEX(path) \ - ((path)->ep_header->eh_ecount < (path)->ep_header->eh_max) -#define EXT_MAX_EXTENT(hdr) (EXT_FIRST_EXTENT(hdr) + ((hdr)->eh_max) - 1) -#define EXT_MAX_INDEX(hdr) (EXT_FIRST_INDEX((hdr)) + (hdr)->eh_max - 1) + (le16toh((path)->ep_header->eh_ecount) < le16toh((path)->ep_header->eh_max)) +#define EXT_MAX_EXTENT(hdr) (EXT_FIRST_EXTENT(hdr) + le16toh((hdr)->eh_max) - 1) +#define EXT_MAX_INDEX(hdr) (EXT_FIRST_INDEX((hdr)) + le16toh((hdr)->eh_max) - 1) struct inode; struct m_ext2fs; diff --git a/sys/fs/ext2fs/ext2_htree.c b/sys/fs/ext2fs/ext2_htree.c index 66d236ccc8e7..44120940236a 100644 --- a/sys/fs/ext2fs/ext2_htree.c +++ b/sys/fs/ext2fs/ext2_htree.c @@ -157,49 +157,49 @@ ext2_htree_check_next(struct inode *ip, uint32_t hash, const char *name, static uint32_t ext2_htree_get_block(struct ext2fs_htree_entry *ep) { - return (ep->h_blk & 0x00FFFFFF); + return (le32toh(ep->h_blk) & 0x00FFFFFF); } static void ext2_htree_set_block(struct ext2fs_htree_entry *ep, uint32_t blk) { - ep->h_blk = blk; + ep->h_blk = htole32(blk); } static uint16_t ext2_htree_get_count(struct ext2fs_htree_entry *ep) { - return (((struct ext2fs_htree_count *)(ep))->h_entries_num); + return (le16toh(((struct ext2fs_htree_count *)(ep))->h_entries_num)); } static void ext2_htree_set_count(struct ext2fs_htree_entry *ep, uint16_t cnt) { - ((struct ext2fs_htree_count *)(ep))->h_entries_num = cnt; + ((struct ext2fs_htree_count *)(ep))->h_entries_num = htole16(cnt); } static uint32_t ext2_htree_get_hash(struct ext2fs_htree_entry *ep) { - return (ep->h_hash); + return (le32toh(ep->h_hash)); } static uint16_t ext2_htree_get_limit(struct ext2fs_htree_entry *ep) { - return (((struct ext2fs_htree_count *)(ep))->h_entries_max); + return (le16toh(((struct ext2fs_htree_count *)(ep))->h_entries_max)); } static void ext2_htree_set_hash(struct ext2fs_htree_entry *ep, uint32_t hash) { - ep->h_hash = hash; + ep->h_hash = htole32(hash); } static void ext2_htree_set_limit(struct ext2fs_htree_entry *ep, uint16_t limit) { - ((struct ext2fs_htree_count *)(ep))->h_entries_max = limit; + ((struct ext2fs_htree_count *)(ep))->h_entries_max = htole16(limit); } static void @@ -246,6 +246,14 @@ ext2_htree_node_limit(struct inode *ip) return (space / sizeof(struct ext2fs_htree_entry)); } +static void +ext2_get_hash_seed(struct ext2fs* es, uint32_t* seed) +{ + + for (int i = 0; i < 4; i++) + seed[i] = le32toh(es->e3fs_hash_seed[i]); +} + static int ext2_htree_find_leaf(struct inode *ip, const char *name, int namelen, uint32_t *hash, uint8_t *hash_ver, @@ -260,6 +268,7 @@ ext2_htree_find_leaf(struct inode *ip, const char *name, int namelen, struct ext2fs_htree_lookup_level *level_info; uint32_t hash_major = 0, hash_minor = 0; uint32_t levels, cnt; + uint32_t hash_seed[4]; uint8_t hash_version; if (name == NULL || info == NULL) @@ -285,7 +294,8 @@ ext2_htree_find_leaf(struct inode *ip, const char *name, int namelen, hash_version += m_fs->e2fs_uhash; *hash_ver = hash_version; - ext2_htree_hash(name, namelen, fs->e3fs_hash_seed, + ext2_get_hash_seed(fs, hash_seed); + ext2_htree_hash(name, namelen, hash_seed, hash_version, &hash_major, &hash_minor); *hash = hash_major; @@ -494,9 +504,9 @@ ext2_htree_cmp_sort_entry(const void *e1, const void *e2) entry1 = (const struct ext2fs_htree_sort_entry *)e1; entry2 = (const struct ext2fs_htree_sort_entry *)e2; - if (entry1->h_hash < entry2->h_hash) + if (le32toh(entry1->h_hash) < le32toh(entry2->h_hash)) return (-1); - if (entry1->h_hash > entry2->h_hash) + if (le32toh(entry1->h_hash) > le32toh(entry2->h_hash)) return (1); return (0); } @@ -512,9 +522,10 @@ ext2_append_entry(char *block, uint32_t blksize, uint16_t entry_len; entry_len = EXT2_DIR_REC_LEN(last_entry->e2d_namlen); - last_entry->e2d_reclen = entry_len; + last_entry->e2d_reclen = htole16(entry_len); last_entry = (struct ext2fs_direct_2 *)((char *)last_entry + entry_len); - new_entry->e2d_reclen = block + blksize - (char *)last_entry - csum_size; + new_entry->e2d_reclen = htole16(block + blksize - (char *)last_entry - + csum_size); memcpy(last_entry, new_entry, EXT2_DIR_REC_LEN(new_entry->e2d_namlen)); } @@ -556,17 +567,18 @@ ext2_htree_split_dirblock(struct inode *ip, char *block1, char *block2, * Fill in directory entry sort descriptors. */ while ((char *)ep < block1 + blksize - csum_size) { - if (ep->e2d_ino && ep->e2d_namlen) { + if (le32toh(ep->e2d_ino) && ep->e2d_namlen) { entry_cnt++; sort_info--; sort_info->h_size = ep->e2d_reclen; - sort_info->h_offset = (char *)ep - block1; + sort_info->h_offset = htole16((char *)ep - block1); ext2_htree_hash(ep->e2d_name, ep->e2d_namlen, hash_seed, hash_version, &sort_info->h_hash, NULL); + sort_info->h_hash = htole32(sort_info->h_hash); } ep = (struct ext2fs_direct_2 *) - ((char *)ep + ep->e2d_reclen); + ((char *)ep + le16toh(ep->e2d_reclen)); } /* @@ -579,17 +591,17 @@ ext2_htree_split_dirblock(struct inode *ip, char *block1, char *block2, * Count the number of entries to move to directory block 2. */ for (i = entry_cnt - 1; i >= 0; i--) { - if (sort_info[i].h_size + size > blksize / 2) + if (le16toh(sort_info[i].h_size) + size > blksize / 2) break; - size += sort_info[i].h_size; + size += le16toh(sort_info[i].h_size); } - *split_hash = sort_info[i + 1].h_hash; + *split_hash = le32toh(sort_info[i + 1].h_hash); /* * Set collision bit. */ - if (*split_hash == sort_info[i].h_hash) + if (*split_hash == le32toh(sort_info[i].h_hash)) *split_hash += 1; /* @@ -597,10 +609,11 @@ ext2_htree_split_dirblock(struct inode *ip, char *block1, char *block2, */ for (k = i + 1; k < entry_cnt; k++) { ep = (struct ext2fs_direct_2 *)((char *)block1 + - sort_info[k].h_offset); + le16toh(sort_info[k].h_offset)); entry_len = EXT2_DIR_REC_LEN(ep->e2d_namlen); memcpy(dest, ep, entry_len); - ((struct ext2fs_direct_2 *)dest)->e2d_reclen = entry_len; + ((struct ext2fs_direct_2 *)dest)->e2d_reclen = + htole16(entry_len); /* Mark directory entry as unused. */ ep->e2d_ino = 0; dest += entry_len; @@ -612,13 +625,13 @@ ext2_htree_split_dirblock(struct inode *ip, char *block1, char *block2, entry_len = 0; for (offset = 0; offset < blksize - csum_size; ) { ep = (struct ext2fs_direct_2 *)(block1 + offset); - offset += ep->e2d_reclen; - if (ep->e2d_ino) { + offset += le16toh(ep->e2d_reclen); + if (le32toh(ep->e2d_ino)) { last = (struct ext2fs_direct_2 *) ((char *)last + entry_len); entry_len = EXT2_DIR_REC_LEN(ep->e2d_namlen); memcpy((void *)last, (void *)ep, entry_len); - last->e2d_reclen = entry_len; + last->e2d_reclen = htole16(entry_len); } } @@ -628,14 +641,15 @@ ext2_htree_split_dirblock(struct inode *ip, char *block1, char *block2, (struct ext2fs_direct_2 *)dest, entry, csum_size); /* Adjust length field of last entry of block 1. */ - last->e2d_reclen = block1 + blksize - (char *)last - csum_size; + last->e2d_reclen = htole16(block1 + blksize - (char *)last - + csum_size); } else { /* Add entry to block 1. */ ext2_append_entry(block1, blksize, last, entry, csum_size); /* Adjust length field of last entry of block 2. */ ((struct ext2fs_direct_2 *)dest)->e2d_reclen = - block2 + blksize - dest - csum_size; + htole16(block2 + blksize - dest - csum_size); } if (csum_size) { @@ -661,6 +675,7 @@ ext2_htree_create_index(struct vnode *vp, struct componentname *cnp, struct ext2fs_htree_root *root; struct ext2fs_htree_lookup_info info; uint32_t blksize, dirlen, split_hash; + uint32_t hash_seed[4]; uint8_t hash_version; char *buf1 = NULL; char *buf2 = NULL; @@ -679,21 +694,22 @@ ext2_htree_create_index(struct vnode *vp, struct componentname *cnp, root = (struct ext2fs_htree_root *)bp->b_data; dotdot = (struct ext2fs_direct_2 *)((char *)&(root->h_dotdot)); - ep = (struct ext2fs_direct_2 *)((char *)dotdot + dotdot->e2d_reclen); + ep = (struct ext2fs_direct_2 *)((char *)dotdot + + le16toh(dotdot->e2d_reclen)); dirlen = (char *)root + blksize - (char *)ep; memcpy(buf1, ep, dirlen); ep = (struct ext2fs_direct_2 *)buf1; while ((char *)ep < buf1 + dirlen) ep = (struct ext2fs_direct_2 *) - ((char *)ep + ep->e2d_reclen); - ep->e2d_reclen = buf1 + blksize - (char *)ep; + ((char *)ep + le16toh(ep->e2d_reclen)); + ep->e2d_reclen = htole16(buf1 + blksize - (char *)ep); dp->i_flag |= IN_E3INDEX; /* * Initialize index root. */ - dotdot->e2d_reclen = blksize - EXT2_DIR_REC_LEN(1); + dotdot->e2d_reclen = htole16(blksize - EXT2_DIR_REC_LEN(1)); memset(&root->h_info, 0, sizeof(root->h_info)); root->h_info.h_hash_version = fs->e3fs_def_hash_version; root->h_info.h_info_len = sizeof(root->h_info); @@ -710,7 +726,8 @@ ext2_htree_create_index(struct vnode *vp, struct componentname *cnp, hash_version = root->h_info.h_hash_version; if (hash_version <= EXT2_HTREE_TEA) hash_version += m_fs->e2fs_uhash; - ext2_htree_split_dirblock(dp, buf1, buf2, blksize, fs->e3fs_hash_seed, + ext2_get_hash_seed(fs, hash_seed); + ext2_htree_split_dirblock(dp, buf1, buf2, blksize, hash_seed, hash_version, &split_hash, new_entry); ext2_htree_insert_entry(&info, split_hash, 2); @@ -771,6 +788,7 @@ ext2_htree_add_entry(struct vnode *dvp, struct ext2fs_direct_2 *entry, uint32_t dirhash, split_hash; uint32_t blksize, blknum; uint64_t cursize, dirsize; + uint32_t hash_seed[4]; uint8_t hash_version; char *newdirblock = NULL; char *newidxblock = NULL; @@ -804,7 +822,7 @@ ext2_htree_add_entry(struct vnode *dvp, struct ext2fs_direct_2 *entry, dst_node = (struct ext2fs_htree_node *)newidxblock; memset(&dst_node->h_fake_dirent, 0, sizeof(dst_node->h_fake_dirent)); - dst_node->h_fake_dirent.e2d_reclen = blksize; + dst_node->h_fake_dirent.e2d_reclen = htole16(blksize); cursize = roundup(ip->i_size, blksize); dirsize = cursize + blksize; @@ -899,8 +917,9 @@ ext2_htree_add_entry(struct vnode *dvp, struct ext2fs_direct_2 *entry, /* Split target directory block */ newdirblock = malloc(blksize, M_TEMP, M_WAITOK | M_ZERO); + ext2_get_hash_seed(fs, hash_seed); ext2_htree_split_dirblock(ip, (char *)bp->b_data, newdirblock, blksize, - fs->e3fs_hash_seed, hash_version, &split_hash, entry); + hash_seed, hash_version, &split_hash, entry); cursize = roundup(ip->i_size, blksize); dirsize = cursize + blksize; blknum = dirsize / blksize - 1; diff --git a/sys/fs/ext2fs/ext2_inode.c b/sys/fs/ext2fs/ext2_inode.c index d5e05cbe4747..f876f832bdca 100644 --- a/sys/fs/ext2fs/ext2_inode.c +++ b/sys/fs/ext2fs/ext2_inode.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -188,7 +189,7 @@ ext2_indirtrunc(struct inode *ip, daddr_t lbn, daddr_t dbn, */ for (i = NINDIR(fs) - 1, nlbn = lbn + 1 - i * factor; i > last; i--, nlbn += factor) { - nb = bap[i]; + nb = le32toh(bap[i]); if (nb == 0) continue; if (level > SINGLE) { @@ -206,7 +207,7 @@ ext2_indirtrunc(struct inode *ip, daddr_t lbn, daddr_t dbn, */ if (level > SINGLE && lastbn >= 0) { last = lastbn % factor; - nb = bap[i]; + nb = le32toh(bap[i]); if (nb != 0) { if ((error = ext2_indirtrunc(ip, nlbn, fsbtodb(fs, nb), last, level - 1, &blkcount)) != 0) diff --git a/sys/fs/ext2fs/ext2_inode_cnv.c b/sys/fs/ext2fs/ext2_inode_cnv.c index 05cdf27be493..7e8717e9b6a2 100644 --- a/sys/fs/ext2fs/ext2_inode_cnv.c +++ b/sys/fs/ext2fs/ext2_inode_cnv.c @@ -49,9 +49,6 @@ SDT_PROVIDER_DECLARE(ext2fs); */ 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) @@ -79,11 +76,14 @@ ext2_print_inode(struct inode *in) printf("Extents:\n"); ehp = (struct ext4_extent_header *)in->i_db; printf("Header (magic 0x%x entries %d max %d depth %d gen %d)\n", - ehp->eh_magic, ehp->eh_ecount, ehp->eh_max, ehp->eh_depth, - ehp->eh_gen); + le16toh(ehp->eh_magic), le16toh(ehp->eh_ecount), + le16toh(ehp->eh_max), le16toh(ehp->eh_depth), + le32toh(ehp->eh_gen)); ep = (struct ext4_extent *)(char *)(ehp + 1); - printf("Index (blk %d len %d start_lo %d start_hi %d)\n", ep->e_blk, - ep->e_len, ep->e_start_lo, ep->e_start_hi); + printf("Index (blk %d len %d start_lo %d start_hi %d)\n", + le32toh(ep->e_blk), + le16toh(ep->e_len), le32toh(ep->e_start_lo), + le16toh(ep->e_start_hi)); printf("\n"); } else { printf("BLOCKS:"); @@ -94,31 +94,38 @@ ext2_print_inode(struct inode *in) } #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 ei_flags_host; + uint16_t ei_extra_isize_le; + int i; if ((ip->i_number < EXT2_FIRST_INO(fs) && ip->i_number != EXT2_ROOTINO) || (ip->i_number < EXT2_ROOTINO) || - (ip->i_number > fs->e2fs->e2fs_icount)) { + (ip->i_number > le32toh(fs->e2fs->e2fs_icount))) { SDT_PROBE2(ext2fs, , trace, inode_cnv, 1, "bad inode number"); 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 */ + ei_extra_isize_le = 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 + ei_extra_isize_le > + EXT2_INODE_SIZE(fs) || (ei_extra_isize_le & 3)) { SDT_PROBE2(ext2fs, , trace, inode_cnv, 1, "bad extra inode size"); return (EINVAL); @@ -131,103 +138,124 @@ ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip) * 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 |= (uint64_t)le32toh(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_birthnsec = XTIME_TO_NSEC(ei->e2di_crtime_extra); + ip->i_atimensec = XTIME_TO_NSEC(le32toh(ei->e2di_atime_extra)); + ip->i_mtimensec = XTIME_TO_NSEC(le32toh(ei->e2di_mtime_extra)); + ip->i_ctimensec = XTIME_TO_NSEC(le32toh(ei->e2di_ctime_extra)); + ip->i_birthtime = le32toh(ei->e2di_crtime); + ip->i_birthnsec = XTIME_TO_NSEC(le32toh(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; + ei_flags_host = le32toh(ei->e2di_flags); + ip->i_flags |= (ei_flags_host & EXT2_APPEND) ? SF_APPEND : 0; + ip->i_flags |= (ei_flags_host & EXT2_IMMUTABLE) ? SF_IMMUTABLE : 0; + ip->i_flags |= (ei_flags_host & EXT2_NODUMP) ? UF_NODUMP : 0; + ip->i_flag |= (ei_flags_host & EXT3_INDEX) ? IN_E3INDEX : 0; + ip->i_flag |= (ei_flags_host & 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 (ei_flags_host & 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)); + if ((ip->i_flag & IN_E4EXTENTS)) { + memcpy(ip->i_data, ei->e2di_blocks, sizeof(ei->e2di_blocks)); + } else { + 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 = htole32(le16toh(ei->e2di_nlink) ? 0 : + le32toh(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_extra = NSEC_TO_XTIME(ip->i_birthnsec); + ei->e2di_ctime_extra = htole32(NSEC_TO_XTIME(ip->i_ctimensec)); + ei->e2di_mtime_extra = htole32(NSEC_TO_XTIME(ip->i_mtimensec)); + ei->e2di_atime_extra = htole32(NSEC_TO_XTIME(ip->i_atimensec)); + ei->e2di_crtime = htole32(ip->i_birthtime); + ei->e2di_crtime_extra = htole32(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; - ei->e2di_flags |= (ip->i_flags & UF_NODUMP) ? EXT2_NODUMP : 0; - ei->e2di_flags |= (ip->i_flag & IN_E3INDEX) ? EXT3_INDEX : 0; - ei->e2di_flags |= (ip->i_flag & IN_E4EXTENTS) ? EXT4_EXTENTS : 0; + ei->e2di_flags |= htole32((ip->i_flags & SF_APPEND) ? EXT2_APPEND : 0); + ei->e2di_flags |= htole32((ip->i_flags & SF_IMMUTABLE) ? EXT2_IMMUTABLE : 0); + ei->e2di_flags |= htole32((ip->i_flags & UF_NODUMP) ? EXT2_NODUMP : 0); + ei->e2di_flags |= htole32((ip->i_flag & IN_E3INDEX) ? EXT3_INDEX : 0); + ei->e2di_flags |= htole32((ip->i_flag & IN_E4EXTENTS) ? EXT4_EXTENTS : 0); if (ip->i_blocks > ~0U && !EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_HUGE_FILE)) { SDT_PROBE2(ext2fs, , trace, inode_cnv, 1, "i_blocks value is out of range"); return (EIO); } if (ip->i_blocks <= 0xffffffffffffULL) { - ei->e2di_nblock = ip->i_blocks & 0xffffffff; - ei->e2di_nblock_high = ip->i_blocks >> 32 & 0xffff; + ei->e2di_nblock = htole32(ip->i_blocks & 0xffffffff); + ei->e2di_nblock_high = htole16(ip->i_blocks >> 32 & 0xffff); } else { - ei->e2di_flags |= EXT4_HUGE_FILE; - ei->e2di_nblock = dbtofsb(fs, ip->i_blocks); - ei->e2di_nblock_high = dbtofsb(fs, ip->i_blocks) >> 32 & 0xffff; + ei->e2di_flags |= htole32(EXT4_HUGE_FILE); + ei->e2di_nblock = htole32(dbtofsb(fs, ip->i_blocks)); + ei->e2di_nblock_high = htole16(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; - 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); + + if ((ip->i_flag & IN_E4EXTENTS)) { + memcpy(ei->e2di_blocks, ip->i_data, sizeof(ei->e2di_blocks)); + } else { + 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); diff --git a/sys/fs/ext2fs/ext2_lookup.c b/sys/fs/ext2fs/ext2_lookup.c index 5669e40d0880..04ec059e85a4 100644 --- a/sys/fs/ext2fs/ext2_lookup.c +++ b/sys/fs/ext2fs/ext2_lookup.c @@ -203,8 +203,8 @@ ext2_readdir(struct vop_readdir_args *ap) dp = (struct ext2fs_direct_2 *)&bp->b_data[skipcnt]; edp = (struct ext2fs_direct_2 *)&bp->b_data[readcnt]; while (error == 0 && uio->uio_resid > 0 && dp < edp) { - if (dp->e2d_reclen <= offsetof(struct ext2fs_direct_2, - e2d_namlen) || (caddr_t)dp + dp->e2d_reclen > + if (le16toh(dp->e2d_reclen) <= offsetof(struct ext2fs_direct_2, + e2d_namlen) || (caddr_t)dp + le16toh(dp->e2d_reclen) > (caddr_t)edp) { error = EIO; break; @@ -228,17 +228,17 @@ ext2_readdir(struct vop_readdir_args *ap) dstdp.d_namlen = dp->e2d_namlen; dstdp.d_type = FTTODT(dp->e2d_type); if (offsetof(struct ext2fs_direct_2, e2d_namlen) + - dstdp.d_namlen > dp->e2d_reclen) { + dstdp.d_namlen > le16toh(dp->e2d_reclen)) { error = EIO; break; } - if (offset < startoffset || dp->e2d_ino == 0) + if (offset < startoffset || le32toh(dp->e2d_ino) == 0) goto nextentry; - dstdp.d_fileno = dp->e2d_ino; + dstdp.d_fileno = le32toh(dp->e2d_ino); dstdp.d_reclen = GENERIC_DIRSIZ(&dstdp); bcopy(dp->e2d_name, dstdp.d_name, dstdp.d_namlen); /* NOTE: d_off is the offset of the *next* entry. */ - dstdp.d_off = offset + dp->e2d_reclen; + dstdp.d_off = offset + le16toh(dp->e2d_reclen); dirent_terminate(&dstdp); if (dstdp.d_reclen > uio->uio_resid) { if (uio->uio_resid == startresid) @@ -254,14 +254,14 @@ ext2_readdir(struct vop_readdir_args *ap) if (cookies != NULL) { KASSERT(ncookies > 0, ("ext2_readdir: cookies buffer too small")); - *cookies = offset + dp->e2d_reclen; + *cookies = offset + le16toh(dp->e2d_reclen); cookies++; ncookies--; } nextentry: - offset += dp->e2d_reclen; + offset += le16toh(dp->e2d_reclen); dp = (struct ext2fs_direct_2 *)((caddr_t)dp + - dp->e2d_reclen); + le16toh(dp->e2d_reclen)); } bqrelse(bp); uio->uio_offset = offset; @@ -464,7 +464,7 @@ ext2_lookup_ino(struct vnode *vdp, struct vnode **vpp, struct componentname *cnp ep = (struct ext2fs_direct_2 *)((char *)bp->b_data + (entryoffsetinblock & bmask)); foundentry: - ino = ep->e2d_ino; + ino = le32toh(ep->e2d_ino); goto found; } } @@ -546,8 +546,8 @@ ext2_lookup_ino(struct vnode *vdp, struct vnode **vpp, struct componentname *cnp * Check that directory length properly reflects presence * of this entry. */ - if (entryoffsetinblock + EXT2_DIR_REC_LEN(ep->e2d_namlen) - > dp->i_size) { + if (entryoffsetinblock + EXT2_DIR_REC_LEN(ep->e2d_namlen) > + dp->i_size) { ext2_dirbad(dp, i_offset, "i_size too small"); dp->i_size = entryoffsetinblock + EXT2_DIR_REC_LEN(ep->e2d_namlen); dp->i_flag |= IN_CHANGE | IN_UPDATE; @@ -740,7 +740,7 @@ ext2_search_dirblock(struct inode *ip, void *data, int *foundp, * directory. Complete checks can be run by setting * "vfs.e2fs.dirchk" to be true. */ - if (ep->e2d_reclen == 0 || + if (le16toh(ep->e2d_reclen) == 0 || (dirchk && ext2_dirbadentry(vdp, ep, offset))) { int i; @@ -758,7 +758,7 @@ ext2_search_dirblock(struct inode *ip, void *data, int *foundp, * compaction is viable. */ if (ssp->slotstatus != FOUND) { - int size = ep->e2d_reclen; + int size = le16toh(ep->e2d_reclen); if (ep->e2d_ino != 0) size -= EXT2_DIR_REC_LEN(ep->e2d_namlen); @@ -768,7 +768,7 @@ ext2_search_dirblock(struct inode *ip, void *data, int *foundp, if (size >= ssp->slotneeded) { ssp->slotstatus = FOUND; ssp->slotoffset = *offp; - ssp->slotsize = ep->e2d_reclen; + ssp->slotsize = le16toh(ep->e2d_reclen); } else if (ssp->slotstatus == NONE) { ssp->slotfreespace += size; if (ssp->slotoffset == -1) @@ -776,7 +776,7 @@ ext2_search_dirblock(struct inode *ip, void *data, int *foundp, if (ssp->slotfreespace >= ssp->slotneeded) { ssp->slotstatus = COMPACT; ssp->slotsize = *offp + - ep->e2d_reclen - + le16toh(ep->e2d_reclen) - ssp->slotoffset; } } @@ -785,7 +785,7 @@ ext2_search_dirblock(struct inode *ip, void *data, int *foundp, /* * Check for a name match. */ - if (ep->e2d_ino) { + if (ep->e2d_ino != 0) { namlen = ep->e2d_namlen; if (namlen == namelen && !bcmp(name, ep->e2d_name, (unsigned)namlen)) { @@ -799,10 +799,10 @@ ext2_search_dirblock(struct inode *ip, void *data, int *foundp, } } *prevoffp = *offp; - *offp += ep->e2d_reclen; - offset += ep->e2d_reclen; + *offp += le16toh(ep->e2d_reclen); + offset += le16toh(ep->e2d_reclen); *entryoffsetinblockp = offset; - if (ep->e2d_ino) + if (ep->e2d_ino != 0) *endusefulp = *offp; /* * Get pointer to the next entry. @@ -847,13 +847,13 @@ ext2_dirbadentry(struct vnode *dp, struct ext2fs_direct_2 *de, char *error_msg = NULL; - if (de->e2d_reclen < EXT2_DIR_REC_LEN(1)) + if (le16toh(de->e2d_reclen) < EXT2_DIR_REC_LEN(1)) error_msg = "rec_len is smaller than minimal"; - else if (de->e2d_reclen % 4 != 0) + else if (le16toh(de->e2d_reclen) % 4 != 0) error_msg = "rec_len % 4 != 0"; - else if (de->e2d_reclen < EXT2_DIR_REC_LEN(de->e2d_namlen)) + else if (le16toh(de->e2d_reclen) < EXT2_DIR_REC_LEN(de->e2d_namlen)) error_msg = "reclen is too small for name_len"; - else if (entryoffsetinblock + de->e2d_reclen > DIRBLKSIZ) + else if (entryoffsetinblock + le16toh(de->e2d_reclen)> DIRBLKSIZ) error_msg = "directory entry across blocks"; /* else LATER if (de->inode > dir->i_sb->u.ext2_sb.s_es->s_inodes_count) @@ -863,9 +863,10 @@ ext2_dirbadentry(struct vnode *dp, struct ext2fs_direct_2 *de, if (error_msg != NULL) { SDT_PROBE5(ext2fs, , trace, ext2_dirbadentry_error, error_msg, entryoffsetinblock, - de->e2d_ino, de->e2d_reclen, de->e2d_namlen); + le32toh(de->e2d_ino), le16toh(de->e2d_reclen), + de->e2d_namlen); } - return error_msg == NULL ? 0 : 1; + return (error_msg == NULL ? 0 : 1); } /* @@ -890,7 +891,8 @@ ext2_add_first_entry(struct vnode *dvp, struct ext2fs_direct_2 *entry, if (EXT2_HAS_RO_COMPAT_FEATURE(dp->i_e2fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) { - entry->e2d_reclen = dirblksize - sizeof(struct ext2fs_direct_tail); + entry->e2d_reclen = htole16(dirblksize - + sizeof(struct ext2fs_direct_tail)); buf = malloc(dirblksize, M_TEMP, M_WAITOK); if (!buf) { error = ENOMEM; @@ -905,7 +907,7 @@ ext2_add_first_entry(struct vnode *dvp, struct ext2fs_direct_2 *entry, aiov.iov_len = auio.uio_resid; aiov.iov_base = (caddr_t)buf; } else { - entry->e2d_reclen = dirblksize; + entry->e2d_reclen = htole16(dirblksize); auio.uio_offset = dp->i_offset; auio.uio_resid = EXT2_DIR_REC_LEN(entry->e2d_namlen); aiov.iov_len = auio.uio_resid; @@ -952,13 +954,14 @@ ext2_direnter(struct inode *ip, struct vnode *dvp, struct componentname *cnp) panic("ext2_direnter: missing name"); #endif dp = VTOI(dvp); - newdir.e2d_ino = ip->i_number; - newdir.e2d_namlen = cnp->cn_namelen; + newdir.e2d_ino = htole32(ip->i_number); if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs, - EXT2F_INCOMPAT_FTYPE)) + EXT2F_INCOMPAT_FTYPE)) { + newdir.e2d_namlen = cnp->cn_namelen; newdir.e2d_type = DTTOFT(IFTODT(ip->i_mode)); - else - newdir.e2d_type = EXT2_FT_UNKNOWN; + } else + newdir.e2d_namlen = htole16(cnp->cn_namelen); + bcopy(cnp->cn_nameptr, newdir.e2d_name, (unsigned)cnp->cn_namelen + 1); if (ext2_htree_has_idx(dp)) { @@ -1048,20 +1051,20 @@ ext2_add_entry(struct vnode *dvp, struct ext2fs_direct_2 *entry) newentrysize = EXT2_DIR_REC_LEN(entry->e2d_namlen); ep = (struct ext2fs_direct_2 *)dirbuf; dsize = EXT2_DIR_REC_LEN(ep->e2d_namlen); - spacefree = ep->e2d_reclen - dsize; - for (loc = ep->e2d_reclen; loc < dp->i_count; ) { + spacefree = le16toh(ep->e2d_reclen) - dsize; + for (loc = le16toh(ep->e2d_reclen); loc < dp->i_count; ) { nep = (struct ext2fs_direct_2 *)(dirbuf + loc); - if (ep->e2d_ino) { + if (le32toh(ep->e2d_ino)) { /* trim the existing slot */ - ep->e2d_reclen = dsize; + ep->e2d_reclen = htole16(dsize); ep = (struct ext2fs_direct_2 *)((char *)ep + dsize); } else { /* overwrite; nothing there; header is ours */ spacefree += dsize; } dsize = EXT2_DIR_REC_LEN(nep->e2d_namlen); - spacefree += nep->e2d_reclen - dsize; - loc += nep->e2d_reclen; + spacefree += le16toh(nep->e2d_reclen) - dsize; + loc += le16toh(nep->e2d_reclen); bcopy((caddr_t)nep, (caddr_t)ep, dsize); } /* @@ -1071,12 +1074,12 @@ ext2_add_entry(struct vnode *dvp, struct ext2fs_direct_2 *entry) if (ep->e2d_ino == 0) { if (spacefree + dsize < newentrysize) panic("ext2_direnter: compact1"); - entry->e2d_reclen = spacefree + dsize; + entry->e2d_reclen = htole16(spacefree + dsize); } else { if (spacefree < newentrysize) panic("ext2_direnter: compact2"); - entry->e2d_reclen = spacefree; - ep->e2d_reclen = dsize; + entry->e2d_reclen = htole16(spacefree); + ep->e2d_reclen = htole16(dsize); ep = (struct ext2fs_direct_2 *)((char *)ep + dsize); } bcopy((caddr_t)entry, (caddr_t)ep, (u_int)newentrysize); @@ -1137,7 +1140,8 @@ ext2_dirremove(struct vnode *dvp, struct componentname *cnp) if (dp->i_count == 0) rep = ep; else - rep = (struct ext2fs_direct_2 *)((char *)ep + ep->e2d_reclen); + rep = (struct ext2fs_direct_2 *)((char *)ep + + le16toh(ep->e2d_reclen)); ep->e2d_reclen += rep->e2d_reclen; ext2_dirent_csum_set(dp, (struct ext2fs_direct_2 *)bp->b_data); if (DOINGASYNC(dvp) && dp->i_count != 0) @@ -1164,7 +1168,7 @@ ext2_dirrewrite(struct inode *dp, struct inode *ip, struct componentname *cnp) if ((error = ext2_blkatoff(vdp, (off_t)dp->i_offset, (char **)&ep, &bp)) != 0) return (error); - ep->e2d_ino = ip->i_number; + ep->e2d_ino = htole32(ip->i_number); if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs, EXT2F_INCOMPAT_FTYPE)) ep->e2d_type = DTTOFT(IFTODT(ip->i_mode)); @@ -1195,7 +1199,7 @@ ext2_dirempty(struct inode *ip, ino_t parentino, struct ucred *cred) ssize_t count; #define MINDIRSIZ (sizeof(struct dirtemplate) / 2) - for (off = 0; off < ip->i_size; off += dp->e2d_reclen) { + for (off = 0; off < ip->i_size; off += le16toh(dp->e2d_reclen)) { error = vn_rdwr(UIO_READ, ITOV(ip), (caddr_t)dp, MINDIRSIZ, off, UIO_SYSSPACE, IO_NODELOCKED | IO_NOMACCHECK, cred, NOCRED, &count, (struct thread *)0); @@ -1224,7 +1228,7 @@ ext2_dirempty(struct inode *ip, ino_t parentino, struct ucred *cred) */ if (namlen == 1) continue; - if (dp->e2d_name[1] == '.' && dp->e2d_ino == parentino) + if (dp->e2d_name[1] == '.' && le32toh(dp->e2d_ino) == parentino) continue; return (0); } @@ -1271,14 +1275,14 @@ ext2_checkpath(struct inode *source, struct inode *target, struct ucred *cred) error = ENOTDIR; break; } - if (dirbuf.dotdot_ino == source->i_number) { + if (le32toh(dirbuf.dotdot_ino) == source->i_number) { error = EINVAL; break; } - if (dirbuf.dotdot_ino == EXT2_ROOTINO) + if (le32toh(dirbuf.dotdot_ino) == EXT2_ROOTINO) break; vput(vp); - if ((error = VFS_VGET(vp->v_mount, dirbuf.dotdot_ino, + if ((error = VFS_VGET(vp->v_mount, le32toh(dirbuf.dotdot_ino), LK_EXCLUSIVE, &vp)) != 0) { vp = NULL; break; diff --git a/sys/fs/ext2fs/ext2_subr.c b/sys/fs/ext2fs/ext2_subr.c index cd2ea04fa8b7..004bd7a45211 100644 --- a/sys/fs/ext2fs/ext2_subr.c +++ b/sys/fs/ext2fs/ext2_subr.c @@ -114,7 +114,7 @@ ext2_clusteracct(struct m_ext2fs *fs, char *bbp, int cg, e4fs_daddr_t bno, int c bit = 1; loc = 0; - for (i = 0; i < fs->e2fs->e2fs_fpg; i++) { + for (i = 0; i < fs->e2fs_fpg; i++) { if ((bbp[loc] & bit) == 0) run++; else if (run != 0) { @@ -144,8 +144,8 @@ ext2_clusteracct(struct m_ext2fs *fs, char *bbp, int cg, e4fs_daddr_t bno, int c /* Find the size of the cluster going forward. */ start = bno + 1; end = start + fs->e2fs_contigsumsize; - if (end > fs->e2fs->e2fs_fpg) - end = fs->e2fs->e2fs_fpg; + if (end > fs->e2fs_fpg) + end = fs->e2fs_fpg; loc = start / NBBY; bit = 1 << (start % NBBY); for (i = start; i < end; i++) { diff --git a/sys/fs/ext2fs/ext2_vfsops.c b/sys/fs/ext2fs/ext2_vfsops.c index 7e03d77863ae..f40fb7202e45 100644 --- a/sys/fs/ext2fs/ext2_vfsops.c +++ b/sys/fs/ext2fs/ext2_vfsops.c @@ -169,7 +169,9 @@ ext2_mount(struct mount *mp) error = ext2_flushfiles(mp, flags, td); if (error == 0 && fs->e2fs_wasvalid && ext2_cgupdate(ump, MNT_WAIT) == 0) { - fs->e2fs->e2fs_state |= E2FS_ISCLEAN; + fs->e2fs->e2fs_state = + htole16((le16toh(fs->e2fs->e2fs_state) | + E2FS_ISCLEAN)); ext2_sbupdate(ump, MNT_WAIT); } fs->e2fs_ronly = 1; @@ -207,8 +209,8 @@ ext2_mount(struct mount *mp) if (error) return (error); - if ((fs->e2fs->e2fs_state & E2FS_ISCLEAN) == 0 || - (fs->e2fs->e2fs_state & E2FS_ERRORS)) { + if ((le16toh(fs->e2fs->e2fs_state) & E2FS_ISCLEAN) == 0 || + (le16toh(fs->e2fs->e2fs_state) & E2FS_ERRORS)) { if (mp->mnt_flag & MNT_FORCE) { printf( "WARNING: %s was not properly dismounted\n", fs->e2fs_fsmnt); @@ -219,7 +221,8 @@ ext2_mount(struct mount *mp) return (EPERM); } } - fs->e2fs->e2fs_state &= ~E2FS_ISCLEAN; + fs->e2fs->e2fs_state = + htole16(le16toh(fs->e2fs->e2fs_state) & ~E2FS_ISCLEAN); (void)ext2_cgupdate(ump, MNT_WAIT); fs->e2fs_ronly = 0; MNT_ILOCK(mp); @@ -297,13 +300,13 @@ ext2_check_sb_compat(struct ext2fs *es, struct cdev *dev, int ronly) { uint32_t i, mask; - if (es->e2fs_magic != E2FS_MAGIC) { + if (le16toh(es->e2fs_magic) != E2FS_MAGIC) { printf("ext2fs: %s: wrong magic number %#x (expected %#x)\n", - devtoname(dev), es->e2fs_magic, E2FS_MAGIC); + devtoname(dev), le16toh(es->e2fs_magic), E2FS_MAGIC); return (1); } - if (es->e2fs_rev > E2FS_REV0) { - mask = es->e2fs_features_incompat & ~(EXT2F_INCOMPAT_SUPP); + if (le32toh(es->e2fs_rev) > E2FS_REV0) { + mask = le32toh(es->e2fs_features_incompat) & ~(EXT2F_INCOMPAT_SUPP); if (mask) { printf("WARNING: mount of %s denied due to " "unsupported optional features:\n", devtoname(dev)); @@ -315,7 +318,7 @@ ext2_check_sb_compat(struct ext2fs *es, struct cdev *dev, int ronly) printf("\n"); return (1); } - mask = es->e2fs_features_rocompat & ~EXT2F_ROCOMPAT_SUPP; + mask = le32toh(es->e2fs_features_rocompat) & ~EXT2F_ROCOMPAT_SUPP; if (!ronly && mask) { printf("WARNING: R/W mount of %s denied due to " "unsupported optional features:\n", devtoname(dev)); @@ -344,7 +347,7 @@ ext2_cg_location(struct m_ext2fs *fs, int number) logical_sb = fs->e2fs_bsize > SBSIZE ? 0 : 1; if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_META_BG) || - number < fs->e2fs->e3fs_first_meta_bg) + number < le32toh(fs->e2fs->e3fs_first_meta_bg)) return (logical_sb + number + 1); if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT)) @@ -358,7 +361,7 @@ ext2_cg_location(struct m_ext2fs *fs, int number) has_super = 1; return (has_super + cg * (e4fs_daddr_t)EXT2_BLOCKS_PER_GROUP(fs) + - fs->e2fs->e2fs_first_dblock); + le32toh(fs->e2fs->e2fs_first_dblock)); } static int @@ -371,7 +374,7 @@ ext2_cg_validate(struct m_ext2fs *fs) struct ext2_gd *gd; unsigned int i, cg_count; - first_block = fs->e2fs->e2fs_first_dblock; + first_block = le32toh(fs->e2fs->e2fs_first_dblock); last_cg_block = ext2_cg_number_gdb(fs, 0); cg_count = fs->e2fs_gcount; @@ -387,7 +390,7 @@ ext2_cg_validate(struct m_ext2fs *fs) } if ((cg_count == fs->e2fs_gcount) && - !(gd->ext4bgd_flags & EXT2_BG_INODE_ZEROED)) + !(le16toh(gd->ext4bgd_flags) & EXT2_BG_INODE_ZEROED)) cg_count = i; b_bitmap = e2fs_gd_get_b_bitmap(gd); @@ -484,26 +487,26 @@ ext2_compute_sb_data(struct vnode *devvp, struct ext2fs *es, } /* Check for block size = 1K|2K|4K */ - if (es->e2fs_log_bsize > 2) { + if (le32toh(es->e2fs_log_bsize) > 2) { SDT_PROBE1(ext2fs, , vfsops, ext2_compute_sb_data_error, "bad block size"); return (EINVAL); } - fs->e2fs_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->e2fs_log_bsize; + fs->e2fs_bshift = EXT2_MIN_BLOCK_LOG_SIZE + le32toh(es->e2fs_log_bsize); fs->e2fs_bsize = 1U << fs->e2fs_bshift; - fs->e2fs_fsbtodb = es->e2fs_log_bsize + 1; + fs->e2fs_fsbtodb = le32toh(es->e2fs_log_bsize) + 1; fs->e2fs_qbmask = fs->e2fs_bsize - 1; /* Check for fragment size */ - if (es->e2fs_log_fsize > + if (le32toh(es->e2fs_log_fsize) > (EXT2_MAX_FRAG_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE)) { SDT_PROBE1(ext2fs, , vfsops, ext2_compute_sb_data_error, "invalid log cluster size"); return (EINVAL); } - fs->e2fs_fsize = EXT2_MIN_FRAG_SIZE << es->e2fs_log_fsize; + fs->e2fs_fsize = EXT2_MIN_FRAG_SIZE << le32toh(es->e2fs_log_fsize); if (fs->e2fs_fsize != fs->e2fs_bsize) { SDT_PROBE1(ext2fs, , vfsops, ext2_compute_sb_data_error, "fragment size != block size"); @@ -513,21 +516,21 @@ ext2_compute_sb_data(struct vnode *devvp, struct ext2fs *es, fs->e2fs_fpb = fs->e2fs_bsize / fs->e2fs_fsize; /* Check reserved gdt blocks for future filesystem expansion */ - if (es->e2fs_reserved_ngdb > (fs->e2fs_bsize / 4)) { + if (le16toh(es->e2fs_reserved_ngdb) > (fs->e2fs_bsize / 4)) { SDT_PROBE1(ext2fs, , vfsops, ext2_compute_sb_data_error, "number of reserved GDT blocks too large"); return (EINVAL); } - if (es->e2fs_rev == E2FS_REV0) { + if (le32toh(es->e2fs_rev) == E2FS_REV0) { fs->e2fs_isize = E2FS_REV0_INODE_SIZE; } else { - fs->e2fs_isize = es->e2fs_inode_size; + fs->e2fs_isize = le16toh(es->e2fs_inode_size); /* * Check first ino. */ - if (es->e2fs_first_ino < EXT2_FIRSTINO) { + if (le32toh(es->e2fs_first_ino) < EXT2_FIRSTINO) { SDT_PROBE1(ext2fs, , vfsops, ext2_compute_sb_data_error, "invalid first ino"); return (EINVAL); @@ -547,14 +550,14 @@ ext2_compute_sb_data(struct vnode *devvp, struct ext2fs *es, /* Check group descriptors */ if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT) && - es->e3fs_desc_size != E2FS_64BIT_GD_SIZE) { + le16toh(es->e3fs_desc_size) != E2FS_64BIT_GD_SIZE) { SDT_PROBE1(ext2fs, , vfsops, ext2_compute_sb_data_error, "unsupported 64bit descriptor size"); return (EINVAL); } - fs->e2fs_bpg = es->e2fs_bpg; - fs->e2fs_fpg = es->e2fs_fpg; + fs->e2fs_bpg = le32toh(es->e2fs_bpg); + fs->e2fs_fpg = le32toh(es->e2fs_fpg); if (fs->e2fs_bpg == 0 || fs->e2fs_fpg == 0) { SDT_PROBE1(ext2fs, , vfsops, ext2_compute_sb_data_error, "zero blocks/fragments per group"); @@ -579,7 +582,7 @@ ext2_compute_sb_data(struct vnode *devvp, struct ext2fs *es, return (EINVAL); } - fs->e2fs_ipg = es->e2fs_ipg; + fs->e2fs_ipg = le32toh(es->e2fs_ipg); if (fs->e2fs_ipg < fs->e2fs_ipb || fs->e2fs_ipg > fs->e2fs_bsize * 8) { SDT_PROBE1(ext2fs, , vfsops, ext2_compute_sb_data_error, "invalid inodes per group"); @@ -588,13 +591,13 @@ ext2_compute_sb_data(struct vnode *devvp, struct ext2fs *es, fs->e2fs_itpg = fs->e2fs_ipg / fs->e2fs_ipb; - fs->e2fs_bcount = es->e2fs_bcount; - fs->e2fs_rbcount = es->e2fs_rbcount; - fs->e2fs_fbcount = es->e2fs_fbcount; + fs->e2fs_bcount = le32toh(es->e2fs_bcount); + fs->e2fs_rbcount = le32toh(es->e2fs_rbcount); + fs->e2fs_fbcount = le32toh(es->e2fs_fbcount); if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT)) { - fs->e2fs_bcount |= (uint64_t)(es->e4fs_bcount_hi) << 32; - fs->e2fs_rbcount |= (uint64_t)(es->e4fs_rbcount_hi) << 32; - fs->e2fs_fbcount |= (uint64_t)(es->e4fs_fbcount_hi) << 32; + fs->e2fs_bcount |= (uint64_t)(le32toh(es->e4fs_bcount_hi)) << 32; + fs->e2fs_rbcount |= (uint64_t)(le32toh(es->e4fs_rbcount_hi)) << 32; + fs->e2fs_fbcount |= (uint64_t)(le32toh(es->e4fs_fbcount_hi)) << 32; } if (fs->e2fs_rbcount > fs->e2fs_bcount || fs->e2fs_fbcount > fs->e2fs_bcount) { @@ -602,14 +605,22 @@ ext2_compute_sb_data(struct vnode *devvp, struct ext2fs *es, "invalid block count"); return (EINVAL); } - if (es->e2fs_first_dblock >= fs->e2fs_bcount) { + + fs->e2fs_ficount = le32toh(es->e2fs_ficount); + if (fs->e2fs_ficount > le32toh(es->e2fs_icount)) { + SDT_PROBE1(ext2fs, , vfsops, ext2_compute_sb_data_error, + "invalid number of free inodes"); + return (EINVAL); + } + + if (le32toh(es->e2fs_first_dblock) >= fs->e2fs_bcount) { SDT_PROBE1(ext2fs, , vfsops, ext2_compute_sb_data_error, "first data block out of range"); return (EINVAL); } - fs->e2fs_gcount = howmany(fs->e2fs_bcount - es->e2fs_first_dblock, - EXT2_BLOCKS_PER_GROUP(fs)); + fs->e2fs_gcount = howmany(fs->e2fs_bcount - + le32toh(es->e2fs_first_dblock), EXT2_BLOCKS_PER_GROUP(fs)); if (fs->e2fs_gcount > ((uint64_t)1 << 32) - EXT2_DESCS_PER_BLOCK(fs)) { SDT_PROBE1(ext2fs, , vfsops, ext2_compute_sb_data_error, "groups count too large"); @@ -685,7 +696,7 @@ ext2_compute_sb_data(struct vnode *devvp, struct ext2fs *es, for (i = 0; i < fs->e2fs_gcount; i++) fs->e2fs_total_dir += e2fs_gd_get_ndirs(&fs->e2fs_gd[i]); - if (es->e2fs_rev == E2FS_REV0 || + if (le32toh(es->e2fs_rev) == E2FS_REV0 || !EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_LARGEFILE)) fs->e2fs_maxfilesize = 0x7fffffff; else { @@ -693,14 +704,14 @@ ext2_compute_sb_data(struct vnode *devvp, struct ext2fs *es, if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_HUGE_FILE)) fs->e2fs_maxfilesize = 0x7fffffffffffffff; } - if (es->e4fs_flags & E2FS_UNSIGNED_HASH) { + if (le32toh(es->e4fs_flags) & E2FS_UNSIGNED_HASH) { fs->e2fs_uhash = 3; - } else if ((es->e4fs_flags & E2FS_SIGNED_HASH) == 0) { + } else if ((le32toh(es->e4fs_flags) & E2FS_SIGNED_HASH) == 0) { #ifdef __CHAR_UNSIGNED__ - es->e4fs_flags |= E2FS_UNSIGNED_HASH; + es->e4fs_flags = htole32(le32toh(es->e4fs_flags) | E2FS_UNSIGNED_HASH); fs->e2fs_uhash = 3; #else - es->e4fs_flags |= E2FS_SIGNED_HASH; + es->e4fs_flags = htole32(le32toh(es->e4fs_flags) | E2FS_SIGNED_HASH); #endif } if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) @@ -879,8 +890,8 @@ ext2_mountfs(struct vnode *devvp, struct mount *mp) error = EINVAL; /* XXX needs translation */ goto out; } - if ((es->e2fs_state & E2FS_ISCLEAN) == 0 || - (es->e2fs_state & E2FS_ERRORS)) { + if ((le16toh(es->e2fs_state) & E2FS_ISCLEAN) == 0 || + (le16toh(es->e2fs_state) & E2FS_ERRORS)) { if (ronly || (mp->mnt_flag & MNT_FORCE)) { printf( "WARNING: Filesystem was not properly dismounted\n"); @@ -939,10 +950,11 @@ ext2_mountfs(struct vnode *devvp, struct mount *mp) * If the fs is not mounted read-only, make sure the super block is * always written back on a sync(). */ - fs->e2fs_wasvalid = fs->e2fs->e2fs_state & E2FS_ISCLEAN ? 1 : 0; + fs->e2fs_wasvalid = le16toh(fs->e2fs->e2fs_state) & E2FS_ISCLEAN ? 1 : 0; if (ronly == 0) { - fs->e2fs_fmod = 1; /* mark it modified */ - fs->e2fs->e2fs_state &= ~E2FS_ISCLEAN; /* set fs invalid */ + fs->e2fs_fmod = 1; /* mark it modified and set fs invalid */ + fs->e2fs->e2fs_state = + htole16(le16toh(fs->e2fs->e2fs_state) & ~E2FS_ISCLEAN); } mp->mnt_data = ump; mp->mnt_stat.f_fsid.val[0] = dev2udev(dev); @@ -962,7 +974,7 @@ ext2_mountfs(struct vnode *devvp, struct mount *mp) * ufs_bmap w/o changse! */ ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs); - ump->um_bptrtodb = fs->e2fs->e2fs_log_bsize + 1; + ump->um_bptrtodb = le32toh(fs->e2fs->e2fs_log_bsize) + 1; ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs); if (ronly == 0) ext2_sbupdate(ump, MNT_WAIT); @@ -1018,7 +1030,8 @@ ext2_unmount(struct mount *mp, int mntflags) ronly = fs->e2fs_ronly; if (ronly == 0 && ext2_cgupdate(ump, MNT_WAIT) == 0) { if (fs->e2fs_wasvalid) - fs->e2fs->e2fs_state |= E2FS_ISCLEAN; + fs->e2fs->e2fs_state = + htole16(le16toh(fs->e2fs->e2fs_state) | E2FS_ISCLEAN); ext2_sbupdate(ump, MNT_WAIT); } @@ -1068,7 +1081,7 @@ ext2_statfs(struct mount *mp, struct statfs *sbp) ump = VFSTOEXT2(mp); fs = ump->um_e2fs; - if (fs->e2fs->e2fs_magic != E2FS_MAGIC) + if (le16toh(fs->e2fs->e2fs_magic) != E2FS_MAGIC) panic("ext2_statfs"); /* @@ -1078,10 +1091,10 @@ ext2_statfs(struct mount *mp, struct statfs *sbp) 1 /* block bitmap */ + 1 /* inode bitmap */ + fs->e2fs_itpg; - overhead = fs->e2fs->e2fs_first_dblock + + overhead = le32toh(fs->e2fs->e2fs_first_dblock) + fs->e2fs_gcount * overhead_per_group; - if (fs->e2fs->e2fs_rev > E2FS_REV0 && - fs->e2fs->e2fs_features_rocompat & EXT2F_ROCOMPAT_SPARSESUPER) { + if (le32toh(fs->e2fs->e2fs_rev) > E2FS_REV0 && + le32toh(fs->e2fs->e2fs_features_rocompat) & EXT2F_ROCOMPAT_SPARSESUPER) { for (i = 0, ngroups = 0; i < fs->e2fs_gcount; i++) { if (ext2_cg_has_sb(fs, i)) ngroups++; @@ -1090,9 +1103,9 @@ ext2_statfs(struct mount *mp, struct statfs *sbp) ngroups = fs->e2fs_gcount; } ngdb = fs->e2fs_gdbcount; - if (fs->e2fs->e2fs_rev > E2FS_REV0 && - fs->e2fs->e2fs_features_compat & EXT2F_COMPAT_RESIZE) - ngdb += fs->e2fs->e2fs_reserved_ngdb; + if (le32toh(fs->e2fs->e2fs_rev) > E2FS_REV0 && + le32toh(fs->e2fs->e2fs_features_compat) & EXT2F_COMPAT_RESIZE) + ngdb += le16toh(fs->e2fs->e2fs_reserved_ngdb); overhead += ngroups * (1 /* superblock */ + ngdb); sbp->f_bsize = EXT2_FRAG_SIZE(fs); @@ -1100,8 +1113,8 @@ ext2_statfs(struct mount *mp, struct statfs *sbp) sbp->f_blocks = fs->e2fs_bcount - overhead; sbp->f_bfree = fs->e2fs_fbcount; sbp->f_bavail = sbp->f_bfree - fs->e2fs_rbcount; - sbp->f_files = fs->e2fs->e2fs_icount; - sbp->f_ffree = fs->e2fs->e2fs_ficount; + sbp->f_files = le32toh(fs->e2fs->e2fs_icount); + sbp->f_ffree = fs->e2fs_ficount; return (0); } @@ -1174,7 +1187,7 @@ ext2_sync(struct mount *mp, int waitfor) */ if (fs->e2fs_fmod != 0) { fs->e2fs_fmod = 0; - fs->e2fs->e2fs_wtime = time_second; + fs->e2fs->e2fs_wtime = htole32(time_second); if ((error = ext2_cgupdate(ump, waitfor)) != 0) allerror = error; } @@ -1317,7 +1330,7 @@ ext2_fhtovp(struct mount *mp, struct fid *fhp, int flags, struct vnode **vpp) ufhp = (struct ufid *)fhp; fs = VFSTOEXT2(mp)->um_e2fs; if (ufhp->ufid_ino < EXT2_ROOTINO || - ufhp->ufid_ino > fs->e2fs_gcount * fs->e2fs->e2fs_ipg) + ufhp->ufid_ino > fs->e2fs_gcount * fs->e2fs_ipg) return (ESTALE); error = VFS_VGET(mp, ufhp->ufid_ino, LK_EXCLUSIVE, &nvp); @@ -1348,15 +1361,17 @@ ext2_sbupdate(struct ext2mount *mp, int waitfor) struct buf *bp; int error = 0; - es->e2fs_bcount = fs->e2fs_bcount & 0xffffffff; - es->e2fs_rbcount = fs->e2fs_rbcount & 0xffffffff; - es->e2fs_fbcount = fs->e2fs_fbcount & 0xffffffff; + es->e2fs_bcount = htole32(fs->e2fs_bcount & 0xffffffff); + es->e2fs_rbcount = htole32(fs->e2fs_rbcount & 0xffffffff); + es->e2fs_fbcount = htole32(fs->e2fs_fbcount & 0xffffffff); if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT)) { - es->e4fs_bcount_hi = fs->e2fs_bcount >> 32; - es->e4fs_rbcount_hi = fs->e2fs_rbcount >> 32; - es->e4fs_fbcount_hi = fs->e2fs_fbcount >> 32; + es->e4fs_bcount_hi = htole32(fs->e2fs_bcount >> 32); + es->e4fs_rbcount_hi = htole32(fs->e2fs_rbcount >> 32); + es->e4fs_fbcount_hi = htole32(fs->e2fs_fbcount >> 32); } + es->e2fs_ficount = htole32(fs->e2fs_ficount); + if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) ext2_sb_csum_set(fs); diff --git a/sys/fs/ext2fs/ext2_vnops.c b/sys/fs/ext2fs/ext2_vnops.c index 99d2043f4987..5bea1a376a9b 100644 --- a/sys/fs/ext2fs/ext2_vnops.c +++ b/sys/fs/ext2fs/ext2_vnops.c @@ -209,12 +209,12 @@ VFS_VOP_VECTOR_REGISTER(ext2_fifoops); * endianness problems. */ static struct dirtemplate mastertemplate = { - 0, 12, 1, EXT2_FT_DIR, ".", - 0, DIRBLKSIZ - 12, 2, EXT2_FT_DIR, ".." + 0, htole16(12), 1, EXT2_FT_DIR, ".", + 0, htole16(DIRBLKSIZ - 12), 2, EXT2_FT_DIR, ".." }; static struct dirtemplate omastertemplate = { - 0, 12, 1, EXT2_FT_UNKNOWN, ".", - 0, DIRBLKSIZ - 12, 2, EXT2_FT_UNKNOWN, ".." + 0, htole16(12), 1, EXT2_FT_UNKNOWN, ".", + 0, htole16(DIRBLKSIZ - 12), 2, EXT2_FT_UNKNOWN, ".." }; static void @@ -1094,7 +1094,7 @@ ext2_rename(struct vop_rename_args *ap) ext2_dirbad(xp, (doff_t)12, "rename: mangled dir"); } else { - dirbuf->dotdot_ino = newparent; + dirbuf->dotdot_ino = htole32(newparent); /* * dirblock 0 could be htree root, * try both csum update functions. @@ -1380,15 +1380,15 @@ ext2_mkdir(struct vop_mkdir_args *ap) else dtp = &omastertemplate; dirtemplate = *dtp; - dirtemplate.dot_ino = ip->i_number; - dirtemplate.dotdot_ino = dp->i_number; + dirtemplate.dot_ino = htole32(ip->i_number); + dirtemplate.dotdot_ino = htole32(dp->i_number); /* * note that in ext2 DIRBLKSIZ == blocksize, not DEV_BSIZE so let's * just redefine it - for this function only */ #undef DIRBLKSIZ #define DIRBLKSIZ VTOI(dvp)->i_e2fs->e2fs_bsize - dirtemplate.dotdot_reclen = DIRBLKSIZ - 12; + dirtemplate.dotdot_reclen = htole16(DIRBLKSIZ - 12); buf = malloc(DIRBLKSIZ, M_TEMP, M_WAITOK | M_ZERO); if (!buf) { error = ENOMEM; @@ -1397,7 +1397,9 @@ ext2_mkdir(struct vop_mkdir_args *ap) goto bad; } if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) { - dirtemplate.dotdot_reclen -= sizeof(struct ext2fs_direct_tail); + dirtemplate.dotdot_reclen = + htole16(le16toh(dirtemplate.dotdot_reclen) - + sizeof(struct ext2fs_direct_tail)); ext2_init_dirent_tail(EXT2_DIRENT_TAIL(buf, DIRBLKSIZ)); } memcpy(buf, &dirtemplate, sizeof(dirtemplate)); diff --git a/sys/fs/ext2fs/ext2fs.h b/sys/fs/ext2fs/ext2fs.h index e757b456c006..81ff6838f16f 100644 --- a/sys/fs/ext2fs/ext2fs.h +++ b/sys/fs/ext2fs/ext2fs.h @@ -159,6 +159,7 @@ struct m_ext2fs { uint64_t e2fs_bcount; /* blocks count */ uint64_t e2fs_rbcount; /* reserved blocks count */ uint64_t e2fs_fbcount; /* free blocks count */ + uint32_t e2fs_ficount; /* free inodes count */ uint32_t e2fs_bsize; /* Block size */ uint32_t e2fs_bshift; /* calc of logical block no */ uint32_t e2fs_bpg; /* Number of blocks per group */ @@ -344,11 +345,11 @@ static const struct ext2_feature incompat[] = { * Feature set definitions */ #define EXT2_HAS_COMPAT_FEATURE(sb,mask) \ - ( EXT2_SB(sb)->e2fs->e2fs_features_compat & htole32(mask) ) + ( le32toh(EXT2_SB(sb)->e2fs->e2fs_features_compat) & mask) #define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask) \ - ( EXT2_SB(sb)->e2fs->e2fs_features_rocompat & htole32(mask) ) + ( le32toh(EXT2_SB(sb)->e2fs->e2fs_features_rocompat) & mask) #define EXT2_HAS_INCOMPAT_FEATURE(sb,mask) \ - ( EXT2_SB(sb)->e2fs->e2fs_features_incompat & htole32(mask) ) + ( le32toh(EXT2_SB(sb)->e2fs->e2fs_features_incompat) & mask) /* * File clean flags @@ -418,15 +419,14 @@ struct ext2_gd { * Macro-instructions used to manage group descriptors */ #define EXT2_BLOCKS_PER_GROUP(s) (EXT2_SB(s)->e2fs_bpg) -#define EXT2_DESCS_PER_BLOCK(s) (EXT2_HAS_INCOMPAT_FEATURE((s), \ - EXT2F_INCOMPAT_64BIT) ? ((s)->e2fs_bsize / sizeof(struct ext2_gd)) : \ - ((s)->e2fs_bsize / E2FS_REV0_GD_SIZE)) +#define EXT2_DESCS_PER_BLOCK(s) (EXT2_HAS_INCOMPAT_FEATURE((s), \ + EXT2F_INCOMPAT_64BIT) ? ((s)->e2fs_bsize / sizeof(struct ext2_gd)) : \ + ((s)->e2fs_bsize / E2FS_REV0_GD_SIZE)) /* * Macro-instructions used to manage inodes */ -#define EXT2_FIRST_INO(s) ((EXT2_SB(s)->e2fs->e2fs_rev == E2FS_REV0) ? \ - EXT2_FIRSTINO : \ - EXT2_SB(s)->e2fs->e2fs_first_ino) +#define EXT2_FIRST_INO(s) (le32toh((EXT2_SB(s)->e2fs->e2fs_rev) == \ + E2FS_REV0) ? EXT2_FIRSTINO : le32toh(EXT2_SB(s)->e2fs->e2fs_first_ino)) #endif /* !_FS_EXT2FS_EXT2FS_H_ */ diff --git a/sys/fs/ext2fs/fs.h b/sys/fs/ext2fs/fs.h index db696942bf29..e07b69b91bce 100644 --- a/sys/fs/ext2fs/fs.h +++ b/sys/fs/ext2fs/fs.h @@ -108,8 +108,8 @@ /* get block containing inode from its number x */ #define ino_to_fsba(fs, x) \ - (e2fs_gd_get_i_tables(&(fs)->e2fs_gd[ino_to_cg((fs), (x))]) + \ - (((x) - 1) % (fs)->e2fs->e2fs_ipg) / (fs)->e2fs_ipb) + (e2fs_gd_get_i_tables(&(fs)->e2fs_gd[ino_to_cg((fs), (x))]) + \ + (((x) - 1) % (fs)->e2fs_ipg) / (fs)->e2fs_ipb) /* get offset for inode in block */ #define ino_to_fsbo(fs, x) ((x-1) % (fs->e2fs_ipb)) @@ -118,10 +118,10 @@ * Give cylinder group number for a file system block. * Give cylinder group block number for a file system block. */ -#define dtog(fs, d) (((d) - fs->e2fs->e2fs_first_dblock) / \ - EXT2_BLOCKS_PER_GROUP(fs)) -#define dtogd(fs, d) (((d) - fs->e2fs->e2fs_first_dblock) % \ - EXT2_BLOCKS_PER_GROUP(fs)) +#define dtog(fs, d) (((d) - le32toh(fs->e2fs->e2fs_first_dblock)) / \ + EXT2_BLOCKS_PER_GROUP(fs)) +#define dtogd(fs, d) (((d) - le32toh(fs->e2fs->e2fs_first_dblock)) % \ + EXT2_BLOCKS_PER_GROUP(fs)) /* * The following macros optimize certain frequently calculated