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:
parent
4bd6d63dc5
commit
cd3acfe7f3
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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]);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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++) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user