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
This commit is contained in:
Fedor Uporov 2020-05-17 14:52:54 +00:00
parent 4bd6d63dc5
commit cd3acfe7f3
16 changed files with 695 additions and 572 deletions

View File

@ -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);
}

View File

@ -40,6 +40,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/endian.h>
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/limits.h>
@ -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.

View File

@ -41,6 +41,7 @@
#include <sys/systm.h>
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/endian.h>
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/mount.h>
@ -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);

View File

@ -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]);
}

View File

@ -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);

View File

@ -36,6 +36,7 @@
#include <sys/vnode.h>
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/endian.h>
#include <sys/conf.h>
#include <sys/sdt.h>
#include <sys/stat.h>
@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -43,6 +43,7 @@
#include <sys/mount.h>
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/endian.h>
#include <sys/vnode.h>
#include <sys/malloc.h>
#include <sys/rwlock.h>
@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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++) {

View File

@ -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);

View File

@ -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));

View File

@ -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_ */

View File

@ -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