summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEtienne Brateau <etienne.brateau@gmail.com>2022-01-23 05:17:06 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2022-01-23 12:03:36 +0100
commit2e2c237ab90ade751753944f0ed1830b24478396 (patch)
tree5017ab9a57832b979405adacde7cea3c4f36c9d2
parent013bd5ad3fb25deabde0dfdddb2a4619db08dafc (diff)
ext2fs: Take cares of indiannes
In ext2 data are stored in little endian to ensure portability. So enforce little endian when manipulating these bytes. Message-Id: <20220123041715.19402-8-etienne.brateau@gmail.com>
-rw-r--r--ext2fs/balloc.c136
-rw-r--r--ext2fs/dir.c75
-rw-r--r--ext2fs/ext2_fs.h36
-rw-r--r--ext2fs/ext2fs.h9
-rw-r--r--ext2fs/getblk.c2
-rw-r--r--ext2fs/hyper.c42
-rw-r--r--ext2fs/ialloc.c75
-rw-r--r--ext2fs/inode.c140
-rw-r--r--ext2fs/xattr.c80
9 files changed, 311 insertions, 284 deletions
diff --git a/ext2fs/balloc.c b/ext2fs/balloc.c
index 8ebd11cd..337b583b 100644
--- a/ext2fs/balloc.c
+++ b/ext2fs/balloc.c
@@ -65,8 +65,8 @@ ext2_free_blocks (block_t block, unsigned long count)
pthread_spin_lock (&global_lock);
- if (block < sblock->s_first_data_block ||
- (block + count) > sblock->s_blocks_count)
+ if (block < le32toh (sblock->s_first_data_block) ||
+ (block + count) > le32toh (sblock->s_blocks_count))
{
ext2_error ("freeing blocks not in datazone - "
"block = %u, count = %lu", block, count);
@@ -80,24 +80,30 @@ ext2_free_blocks (block_t block, unsigned long count)
{
unsigned long int gcount = count;
- block_group = ((block - sblock->s_first_data_block)
- / sblock->s_blocks_per_group);
- bit = (block - sblock->s_first_data_block) % sblock->s_blocks_per_group;
- if (bit + count > sblock->s_blocks_per_group)
+ block_group = ((block - le32toh (sblock->s_first_data_block)) /
+ le32toh (sblock->s_blocks_per_group));
+ bit = (block - le32toh (sblock->s_first_data_block)) %
+ le32toh (sblock->s_blocks_per_group);
+
+ /*
+ * Check to see if we are freeing blocks accross a group
+ * boundary
+ */
+ if (bit + count > le32toh (sblock->s_blocks_per_group))
{
- unsigned long overflow = bit + count - sblock->s_blocks_per_group;
+ unsigned long overflow = bit + count - le32toh (sblock->s_blocks_per_group);
gcount -= overflow;
ext2_debug ("freeing blocks across group boundary - "
"block = %u, count = %lu",
block, count);
}
gdp = group_desc (block_group);
- bh = disk_cache_block_ref (gdp->bg_block_bitmap);
+ bh = disk_cache_block_ref (le32toh (gdp->bg_block_bitmap));
- if (in_range (gdp->bg_block_bitmap, block, gcount) ||
- in_range (gdp->bg_inode_bitmap, block, gcount) ||
- in_range (block, gdp->bg_inode_table, itb_per_group) ||
- in_range (block + gcount - 1, gdp->bg_inode_table, itb_per_group))
+ if (in_range (le32toh (gdp->bg_block_bitmap), block, gcount) ||
+ in_range (le32toh (gdp->bg_inode_bitmap), block, gcount) ||
+ in_range (block, le32toh (gdp->bg_inode_table), itb_per_group) ||
+ in_range (block + gcount - 1, le32toh (gdp->bg_inode_table), itb_per_group))
ext2_panic ("freeing blocks in system zones - "
"block = %u, count = %lu",
block, count);
@@ -108,8 +114,10 @@ ext2_free_blocks (block_t block, unsigned long count)
ext2_warning ("bit already cleared for block %lu", block + i);
else
{
- gdp->bg_free_blocks_count++;
- sblock->s_free_blocks_count++;
+ gdp->bg_free_blocks_count =
+ htole16 (le16toh (gdp->bg_free_blocks_count) + 1);
+ sblock->s_free_blocks_count =
+ htole32 (le32toh (sblock->s_free_blocks_count) + 1);
}
}
@@ -153,7 +161,7 @@ ext2_new_block (block_t goal,
pthread_spin_lock (&global_lock);
#ifdef XXX /* Auth check to use reserved blocks */
- if (sblock->s_free_blocks_count <= sblock->s_r_blocks_count &&
+ if (le32toh (sblock->s_free_blocks_count) <= le32toh (sblock->s_r_blocks_count) &&
(!fsuser () && (sb->u.ext2_sb.s_resuid != current->fsuid) &&
(sb->u.ext2_sb.s_resgid == 0 ||
!in_group_p (sb->u.ext2_sb.s_resgid))))
@@ -170,18 +178,21 @@ repeat:
/*
* First, test whether the goal block is free.
*/
- if (goal < sblock->s_first_data_block || goal >= sblock->s_blocks_count)
- goal = sblock->s_first_data_block;
- i = (goal - sblock->s_first_data_block) / sblock->s_blocks_per_group;
+ if (goal < le32toh (sblock->s_first_data_block)
+ || goal >= le32toh (sblock->s_blocks_count))
+ goal = le32toh (sblock->s_first_data_block);
+ i = (goal - le32toh (sblock->s_first_data_block)) /
+ le32toh (sblock->s_blocks_per_group);
gdp = group_desc (i);
- if (gdp->bg_free_blocks_count > 0)
+ if (le16toh (gdp->bg_free_blocks_count) > 0)
{
- j = ((goal - sblock->s_first_data_block) % sblock->s_blocks_per_group);
+ j = ((goal - le32toh (sblock->s_first_data_block))
+ % le32toh (sblock->s_blocks_per_group));
#ifdef EXT2FS_DEBUG
if (j)
goal_attempts++;
#endif
- bh = disk_cache_block_ref (gdp->bg_block_bitmap);
+ bh = disk_cache_block_ref (le32toh (gdp->bg_block_bitmap));
ext2_debug ("goal is at %d:%d", i, j);
@@ -204,7 +215,8 @@ repeat:
else
lmap = ((((unsigned long *) bh)[j >> 5]) >>
((j & 31) + 1));
- if (j < sblock->s_blocks_per_group - 32)
+
+ if (j < le32toh (sblock->s_blocks_per_group) - 32)
lmap |= (((unsigned long *) bh)[(j >> 5) + 1]) <<
(31 - (j & 31));
else
@@ -212,7 +224,7 @@ repeat:
if (lmap != 0xffffffffl)
{
k = ffz (lmap) + 1;
- if ((j + k) < sblock->s_blocks_per_group)
+ if ((j + k) < le32toh (sblock->s_blocks_per_group))
{
j += k;
goto got_block;
@@ -232,17 +244,17 @@ repeat:
* cyclicly search through the rest of the groups.
*/
p = bh + (j >> 3);
- r = memscan (p, 0, (sblock->s_blocks_per_group - j + 7) >> 3);
+ r = memscan (p, 0, (le32toh (sblock->s_blocks_per_group) - j + 7) >> 3);
k = (r - bh) << 3;
- if (k < sblock->s_blocks_per_group)
+ if (k < le32toh (sblock->s_blocks_per_group))
{
j = k;
goto search_back;
}
k = find_next_zero_bit ((unsigned long *) bh,
- sblock->s_blocks_per_group,
+ le32toh (sblock->s_blocks_per_group),
j);
- if (k < sblock->s_blocks_per_group)
+ if (k < le32toh (sblock->s_blocks_per_group))
{
j = k;
goto got_block;
@@ -264,7 +276,7 @@ repeat:
if (i >= groups_count)
i = 0;
gdp = group_desc (i);
- if (gdp->bg_free_blocks_count > 0)
+ if (le16toh (gdp->bg_free_blocks_count) > 0)
break;
}
if (k >= groups_count)
@@ -273,15 +285,15 @@ repeat:
return 0;
}
assert_backtrace (bh == NULL);
- bh = disk_cache_block_ref (gdp->bg_block_bitmap);
- r = memscan (bh, 0, sblock->s_blocks_per_group >> 3);
+ bh = disk_cache_block_ref (le32toh (gdp->bg_block_bitmap));
+ r = memscan (bh, 0, le32toh (sblock->s_blocks_per_group) >> 3);
j = (r - bh) << 3;
- if (j < sblock->s_blocks_per_group)
+ if (j < le32toh (sblock->s_blocks_per_group))
goto search_back;
else
j = find_first_zero_bit ((unsigned long *) bh,
- sblock->s_blocks_per_group);
- if (j >= sblock->s_blocks_per_group)
+ le32toh (sblock->s_blocks_per_group));
+ if (j >= le32toh (sblock->s_blocks_per_group))
{
disk_cache_block_deref (bh);
bh = NULL;
@@ -302,13 +314,14 @@ search_back:
got_block:
assert_backtrace (bh != NULL);
- ext2_debug ("using block group %d (%d)", i, gdp->bg_free_blocks_count);
+ ext2_debug ("using block group %d (%d)", i, le16toh (gdp->bg_free_blocks_count));
- tmp = j + i * sblock->s_blocks_per_group + sblock->s_first_data_block;
+ tmp = j + i * le32toh (sblock->s_blocks_per_group) +
+ le32toh (sblock->s_first_data_block);
- if (tmp == gdp->bg_block_bitmap ||
- tmp == gdp->bg_inode_bitmap ||
- in_range (tmp, gdp->bg_inode_table, itb_per_group))
+ if (tmp == le32toh (gdp->bg_block_bitmap) ||
+ tmp == le32toh (gdp->bg_inode_bitmap) ||
+ in_range (tmp, le32toh (gdp->bg_inode_table), itb_per_group))
ext2_panic ("allocating block in system zone; block = %u", tmp);
if (set_bit (j, bh))
@@ -340,7 +353,7 @@ got_block:
*prealloc_count = 0;
*prealloc_block = tmp + 1;
for (k = 1;
- k < prealloc_goal && (j + k) < sblock->s_blocks_per_group; k++)
+ k < prealloc_goal && (j + k) < le32toh (sblock->s_blocks_per_group); k++)
{
if (set_bit (j + k, bh))
break;
@@ -354,8 +367,10 @@ got_block:
pthread_spin_unlock (&modified_global_blocks_lock);
}
}
- gdp->bg_free_blocks_count -= *prealloc_count;
- sblock->s_free_blocks_count -= *prealloc_count;
+ gdp->bg_free_blocks_count = htole16 (le16toh (gdp->bg_free_blocks_count) -
+ *prealloc_count);
+ sblock->s_free_blocks_count = htole32 (le32toh (sblock->s_free_blocks_count) -
+ *prealloc_count);
ext2_debug ("preallocated a further %u bits", *prealloc_count);
}
#endif
@@ -365,7 +380,7 @@ got_block:
record_global_poke (bh);
bh = NULL;
- if (j >= sblock->s_blocks_count)
+ if (j >= le32toh (sblock->s_blocks_count))
{
ext2_error ("block >= blocks count - block_group = %d, block=%d", i, j);
j = 0;
@@ -375,11 +390,11 @@ got_block:
ext2_debug ("allocating block %d; goal hits %d of %d",
j, goal_hits, goal_attempts);
- gdp->bg_free_blocks_count--;
+ gdp->bg_free_blocks_count = htole16 (le16toh (gdp->bg_free_blocks_count) - 1);
disk_cache_block_ref_ptr (gdp);
record_global_poke (gdp);
- sblock->s_free_blocks_count--;
+ sblock->s_free_blocks_count = htole32 (le32toh (sblock->s_free_blocks_count) - 1);
sblock_dirty = 1;
sync_out:
@@ -407,28 +422,29 @@ ext2_count_free_blocks ()
{
void *bh;
gdp = group_desc (i);
- desc_count += gdp->bg_free_blocks_count;
- bh = disk_cache_block_ref (gdp->bg_block_bitmap);
+ desc_count += le16toh (gdp->bg_free_blocks_count);
+ bh = disk_cache_block_ref (le32toh (gdp->bg_block_bitmap));
x = count_free (bh, block_size);
disk_cache_block_deref (bh);
printf ("group %d: stored = %d, counted = %lu",
- i, gdp->bg_free_blocks_count, x);
+ i, le16toh (gdp->bg_free_blocks_count), x);
bitmap_count += x;
}
printf ("ext2_count_free_blocks: stored = %u, computed = %lu, %lu",
- sblock->s_free_blocks_count, desc_count, bitmap_count);
+ le32toh (sblock->s_free_blocks_count),
+ desc_count, bitmap_count);
pthread_spin_unlock (&global_lock);
return bitmap_count;
#else
- return sblock->s_free_blocks_count;
+ return le32toh (sblock->s_free_blocks_count);
#endif
}
static inline int
block_in_use (block_t block, unsigned char *map)
{
- return test_bit ((block - sblock->s_first_data_block) %
- sblock->s_blocks_per_group, map);
+ return test_bit ((block - le32toh (sblock->s_first_data_block)) %
+ le32toh (sblock->s_blocks_per_group), map);
}
void
@@ -470,8 +486,8 @@ ext2_check_blocks_bitmap ()
}
gdp = group_desc (i);
- desc_count += gdp->bg_free_blocks_count;
- bh = disk_cache_block_ref (gdp->bg_block_bitmap);
+ desc_count += le16toh (gdp->bg_free_blocks_count);
+ bh = disk_cache_block_ref (le32toh (gdp->bg_block_bitmap));
if (!EXT2_HAS_RO_COMPAT_FEATURE (sblock,
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
@@ -486,27 +502,27 @@ ext2_check_blocks_bitmap ()
j, i);
}
- if (!block_in_use (gdp->bg_block_bitmap, bh))
+ if (!block_in_use (le32toh (gdp->bg_block_bitmap), bh))
ext2_error ("block bitmap for group %d is marked free", i);
- if (!block_in_use (gdp->bg_inode_bitmap, bh))
+ if (!block_in_use (le32toh (gdp->bg_inode_bitmap), bh))
ext2_error ("inode bitmap for group %d is marked free", i);
for (j = 0; j < itb_per_group; j++)
- if (!block_in_use (gdp->bg_inode_table + j, bh))
+ if (!block_in_use (le32toh (gdp->bg_inode_table) + j, bh))
ext2_error ("block #%d of the inode table in group %d is marked free", j, i);
x = count_free (bh, block_size);
disk_cache_block_deref (bh);
- if (gdp->bg_free_blocks_count != x)
+ if (le16toh (gdp->bg_free_blocks_count) != x)
ext2_error ("wrong free blocks count for group %d,"
" stored = %d, counted = %lu",
- i, gdp->bg_free_blocks_count, x);
+ i, le16toh (gdp->bg_free_blocks_count), x);
bitmap_count += x;
}
- if (sblock->s_free_blocks_count != bitmap_count)
+ if (le32toh (sblock->s_free_blocks_count) != bitmap_count)
ext2_error ("wrong free blocks count in super block,"
" stored = %lu, counted = %lu",
- (unsigned long) sblock->s_free_blocks_count, bitmap_count);
+ (unsigned long) le32toh (sblock->s_free_blocks_count), bitmap_count);
pthread_spin_unlock (&global_lock);
}
diff --git a/ext2fs/dir.c b/ext2fs/dir.c
index bcf90469..c7c3018b 100644
--- a/ext2fs/dir.c
+++ b/ext2fs/dir.c
@@ -404,15 +404,15 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx,
for (currentoff = blockaddr, prevoff = 0;
currentoff < blockaddr + DIRBLKSIZ;
- prevoff = currentoff, currentoff += entry->rec_len)
+ prevoff = currentoff, currentoff += le16toh (entry->rec_len))
{
entry = (struct ext2_dir_entry_2 *)currentoff;
- if (!entry->rec_len
- || entry->rec_len % EXT2_DIR_PAD
+ if (!le16toh (entry->rec_len)
+ || le16toh (entry->rec_len) % EXT2_DIR_PAD
|| entry->name_len > EXT2_NAME_LEN
- || currentoff + entry->rec_len > blockaddr + DIRBLKSIZ
- || EXT2_DIR_REC_LEN (entry->name_len) > entry->rec_len
+ || currentoff + le16toh (entry->rec_len) > blockaddr + DIRBLKSIZ
+ || EXT2_DIR_REC_LEN (entry->name_len) > le16toh (entry->rec_len)
|| memchr (entry->name, '\0', entry->name_len))
{
ext2_warning ("bad directory entry: inode: %Ld offset: %lu",
@@ -426,10 +426,10 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx,
size_t thisfree;
/* Count how much free space this entry has in it. */
- if (entry->inode == 0)
- thisfree = entry->rec_len;
+ if (le32toh (entry->inode) == 0)
+ thisfree = le16toh (entry->rec_len);
else
- thisfree = entry->rec_len - EXT2_DIR_REC_LEN (entry->name_len);
+ thisfree = le16toh (entry->rec_len) - EXT2_DIR_REC_LEN (entry->name_len);
/* If this isn't at the front of the block, then it will
have to be copied if we do a compression; count the
@@ -445,7 +445,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx,
if (thisfree >= needed)
{
ds->type = CREATE;
- ds->stat = entry->inode == 0 ? TAKE : SHRINK;
+ ds->stat = le32toh (entry->inode) == 0 ? TAKE : SHRINK;
ds->entry = entry;
ds->idx = idx;
looking = countcopies = 0;
@@ -458,12 +458,12 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx,
}
}
- if (entry->inode)
+ if (le32toh (entry->inode))
nentries++;
if (entry->name_len == namelen
&& entry->name[0] == name[0]
- && entry->inode
+ && le32toh (entry->inode)
&& !bcmp (entry->name, name, namelen))
break;
}
@@ -514,7 +514,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx,
ds->preventry = (struct ext2_dir_entry_2 *) prevoff;
}
- *inum = entry->inode;
+ *inum = le32toh (entry->inode);
return 0;
}
@@ -551,7 +551,8 @@ diskfs_direnter_hard (struct node *dp, const char *name, struct node *np,
{
case TAKE:
/* We are supposed to consume this slot. */
- assert_backtrace (ds->entry->inode == 0 && ds->entry->rec_len >= needed);
+ assert_backtrace (le32toh (ds->entry->inode) == 0
+ && le16toh (ds->entry->rec_len) >= needed);
new = ds->entry;
break;
@@ -560,12 +561,12 @@ diskfs_direnter_hard (struct node *dp, const char *name, struct node *np,
/* We are supposed to take the extra space at the end
of this slot. */
oldneeded = EXT2_DIR_REC_LEN (ds->entry->name_len);
- assert_backtrace (ds->entry->rec_len - oldneeded >= needed);
+ assert_backtrace (le16toh (ds->entry->rec_len) - oldneeded >= needed);
new = (struct ext2_dir_entry_2 *) ((vm_address_t) ds->entry + oldneeded);
- new->rec_len = ds->entry->rec_len - oldneeded;
- ds->entry->rec_len = oldneeded;
+ new->rec_len = htole16 (le16toh (ds->entry->rec_len) - oldneeded);
+ ds->entry->rec_len = htole16 (oldneeded);
break;
case COMPRESS:
@@ -579,16 +580,16 @@ diskfs_direnter_hard (struct node *dp, const char *name, struct node *np,
{
struct ext2_dir_entry_2 *from = (struct ext2_dir_entry_2 *)fromoff;
struct ext2_dir_entry_2 *to = (struct ext2_dir_entry_2 *) tooff;
- size_t fromreclen = from->rec_len;
+ size_t fromreclen = le16toh (from->rec_len);
- if (from->inode != 0)
+ if (le32toh (from->inode) != 0)
{
assert_backtrace (fromoff >= tooff);
memmove (to, from, fromreclen);
- to->rec_len = EXT2_DIR_REC_LEN (to->name_len);
+ to->rec_len = htole16 (EXT2_DIR_REC_LEN (to->name_len));
- tooff += to->rec_len;
+ tooff += le16toh (to->rec_len);
}
fromoff += fromreclen;
}
@@ -597,7 +598,7 @@ diskfs_direnter_hard (struct node *dp, const char *name, struct node *np,
assert_backtrace (totfreed >= needed);
new = (struct ext2_dir_entry_2 *) tooff;
- new->rec_len = totfreed;
+ new->rec_len = htole16 (totfreed);
break;
case EXTEND:
@@ -634,7 +635,7 @@ diskfs_direnter_hard (struct node *dp, const char *name, struct node *np,
dp->dn_stat.st_size = oldsize + DIRBLKSIZ;
dp->dn_set_ctime = 1;
- new->rec_len = DIRBLKSIZ;
+ new->rec_len = htole16 (DIRBLKSIZ);
break;
default:
@@ -645,7 +646,7 @@ diskfs_direnter_hard (struct node *dp, const char *name, struct node *np,
/* NEW points to the directory entry being written, and its
rec_len field is already filled in. Now fill in the rest. */
- new->inode = np->cache_id;
+ new->inode = htole32 (np->cache_id);
#if 0
/* XXX We cannot enable this code because file types can change
(and conceivably quite often) with translator settings.
@@ -722,12 +723,12 @@ diskfs_dirremove_hard (struct node *dp, struct dirstat *ds)
assert_backtrace (!diskfs_readonly);
if (ds->preventry == 0)
- ds->entry->inode = 0;
+ ds->entry->inode = htole32 (0);
else
{
assert_backtrace ((vm_address_t) ds->entry - (vm_address_t) ds->preventry
- == ds->preventry->rec_len);
- ds->preventry->rec_len += ds->entry->rec_len;
+ == le16toh (ds->preventry->rec_len));
+ ds->preventry->rec_len = htole16( le16toh (ds->preventry->rec_len) + ds->entry->rec_len);
}
dp->dn_set_mtime = 1;
@@ -761,7 +762,7 @@ diskfs_dirrewrite_hard (struct node *dp, struct node *np, struct dirstat *ds)
assert_backtrace (!diskfs_readonly);
- ds->entry->inode = np->cache_id;
+ ds->entry->inode = htole32 (np->cache_id);
dp->dn_set_mtime = 1;
diskfs_node_disknode (dp)->info.i_flags &= ~EXT2_BTREE_FL;
@@ -796,11 +797,11 @@ diskfs_dirempty (struct node *dp, struct protid *cred)
for (curoff = buf;
!hit && curoff < buf + dp->dn_stat.st_size;
- curoff += entry->rec_len)
+ curoff += le16toh (entry->rec_len))
{
entry = (struct ext2_dir_entry_2 *) curoff;
- if (entry->inode != 0
+ if (le32toh (entry->inode) != 0
&& (entry->name_len > 2
|| entry->name[0] != '.'
|| (entry->name[1] != '.'
@@ -853,10 +854,10 @@ count_dirents (struct node *dp, block_t nb, char *buf)
for (offinblk = buf;
offinblk < buf + DIRBLKSIZ;
- offinblk += entry->rec_len)
+ offinblk += le16toh (entry->rec_len))
{
entry = (struct ext2_dir_entry_2 *) offinblk;
- if (entry->inode)
+ if (le32toh (entry->inode))
count++;
}
@@ -982,7 +983,7 @@ diskfs_get_directs (struct node *dp,
}
for (i = 0, bufp = buf;
i < entry - curentry && bufp - buf < DIRBLKSIZ;
- bufp += ((struct ext2_dir_entry_2 *)bufp)->rec_len, i++)
+ bufp += le16toh (((struct ext2_dir_entry_2 *)bufp)->rec_len), i++)
;
/* Make sure we didn't run off the end. */
assert_backtrace (bufp - buf < DIRBLKSIZ);
@@ -1009,7 +1010,7 @@ diskfs_get_directs (struct node *dp,
entryp = (struct ext2_dir_entry_2 *)bufp;
- if (entryp->inode)
+ if (le32toh (entryp->inode))
{
int rec_len;
int name_len = entryp->name_len;
@@ -1033,7 +1034,7 @@ diskfs_get_directs (struct node *dp,
if (datap + rec_len > *data + allocsize)
break;
- userp->d_fileno = entryp->inode;
+ userp->d_fileno = le32toh (entryp->inode);
userp->d_reclen = rec_len;
userp->d_namlen = name_len;
@@ -1066,7 +1067,7 @@ diskfs_get_directs (struct node *dp,
i++;
}
- if (entryp->rec_len == 0)
+ if (le16toh (entryp->rec_len) == 0)
{
ext2_warning ("zero length directory entry: inode: %Ld offset: %zd",
dp->cache_id,
@@ -1074,7 +1075,7 @@ diskfs_get_directs (struct node *dp,
return EIO;
}
- bufp += entryp->rec_len;
+ bufp += le16toh (entryp->rec_len);
if (bufp - buf == DIRBLKSIZ)
{
blkno++;
@@ -1084,7 +1085,7 @@ diskfs_get_directs (struct node *dp,
{
ext2_warning ("directory entry too long: inode: %Ld offset: %zd",
dp->cache_id,
- blkno * DIRBLKSIZ + bufp - buf - entryp->rec_len);
+ blkno * DIRBLKSIZ + bufp - buf - le16toh (entryp->rec_len));
return EIO;
}
}
diff --git a/ext2fs/ext2_fs.h b/ext2fs/ext2_fs.h
index f05abb04..daa49543 100644
--- a/ext2fs/ext2_fs.h
+++ b/ext2fs/ext2_fs.h
@@ -83,12 +83,12 @@
#define EXT2_ACLE_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
#define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10)
-#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
- EXT2_GOOD_OLD_INODE_SIZE : \
- (s)->s_inode_size)
-#define EXT2_FIRST_INO(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
- EXT2_GOOD_OLD_FIRST_INO : \
- (s)->s_first_ino)
+#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == htole32(EXT2_GOOD_OLD_REV)) ? \
+ EXT2_GOOD_OLD_INODE_SIZE : \
+ le16toh ((s)->s_inode_size))
+#define EXT2_FIRST_INO(s) (((s)->s_rev_level == htole32(EXT2_GOOD_OLD_REV)) ? \
+ EXT2_GOOD_OLD_FIRST_INO : \
+ (le32toh ((s)->s_first_ino)))
/*
* Macro-instructions used to manage fragments
@@ -96,7 +96,7 @@
#define EXT2_MIN_FRAG_SIZE 1024
#define EXT2_MAX_FRAG_SIZE 4096
#define EXT2_MIN_FRAG_LOG_SIZE 10
-#define EXT2_FRAG_SIZE(s) (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
+#define EXT2_FRAG_SIZE(s) (EXT2_MIN_FRAG_SIZE << le32toh((s)->s_log_frag_size))
#define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))
/*
@@ -139,9 +139,9 @@ struct ext2_group_desc
/*
* Macro-instructions used to manage group descriptors
*/
-#define EXT2_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group)
+#define EXT2_BLOCKS_PER_GROUP(s) (le32toh ((s)->s_blocks_per_group))
#define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group))
-#define EXT2_INODES_PER_GROUP(s) ((s)->s_inodes_per_group)
+#define EXT2_INODES_PER_GROUP(s) (le32toh ((s)->s_inodes_per_group))
/*
* Constants relative to the data blocks
@@ -435,23 +435,23 @@ struct ext2_super_block {
*/
#define EXT2_HAS_COMPAT_FEATURE(sb,mask) \
- ( (sb)->s_feature_compat & (mask) )
+ ( (sb)->s_feature_compat & htole32 (mask) )
#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask) \
- ( (sb)->s_feature_ro_compat & (mask) )
+ ( (sb)->s_feature_ro_compat & htole32 (mask) )
#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask) \
- ( (sb)->s_feature_incompat & (mask) )
+ ( (sb)->s_feature_incompat & htole32 (mask) )
#define EXT2_SET_COMPAT_FEATURE(sb,mask) \
- (sb)->s_feature_compat |= (mask)
+ (sb)->s_feature_compat |= htole32 (mask)
#define EXT2_SET_RO_COMPAT_FEATURE(sb,mask) \
- (sb)->s_feature_ro_compat |= (mask)
+ (sb)->s_feature_ro_compat |= htole32 (mask)
#define EXT2_SET_INCOMPAT_FEATURE(sb,mask) \
- (sb)->s_feature_incompat |= (mask)
+ (sb)->s_feature_incompat |= htole32 (mask)
#define EXT2_CLEAR_COMPAT_FEATURE(sb,mask) \
- (sb)->s_feature_compat &= ~(mask)
+ (sb)->s_feature_compat &= ~htole32 (mask)
#define EXT2_CLEAR_RO_COMPAT_FEATURE(sb,mask) \
- (sb)->s_feature_ro_compat &= ~(mask)
+ (sb)->s_feature_ro_compat &= ~htole32 (mask)
#define EXT2_CLEAR_INCOMPAT_FEATURE(sb,mask) \
- (sb)->s_feature_incompat &= ~(mask)
+ (sb)->s_feature_incompat &= ~htole32 (mask)
#define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001
#define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002
diff --git a/ext2fs/ext2fs.h b/ext2fs/ext2fs.h
index 003e2753..88c9fe81 100644
--- a/ext2fs/ext2fs.h
+++ b/ext2fs/ext2fs.h
@@ -32,6 +32,7 @@
#include <assert-backtrace.h>
#include <pthread.h>
#include <sys/mman.h>
+#include <endian.h>
/* Types used by the ext2 header files. */
typedef u_int32_t __u32;
@@ -293,7 +294,7 @@ extern unsigned int block_size;
extern unsigned int log2_block_size;
/* The number of bits to scale min-blocks to get filesystem blocks. */
-#define BLOCKSIZE_SCALE (sblock->s_log_block_size)
+#define BLOCKSIZE_SCALE (le32toh (sblock->s_log_block_size))
/* log2 of the number of device blocks in a filesystem block. */
extern unsigned log2_dev_blocks_per_fs_block;
@@ -404,7 +405,7 @@ bptr_offs (void *ptr)
#define group_desc(num) (&group_desc_image[num])
extern struct ext2_group_desc *group_desc_image;
-#define inode_group_num(inum) (((inum) - 1) / sblock->s_inodes_per_group)
+#define inode_group_num(inum) (((inum) - 1) / le32toh (sblock->s_inodes_per_group))
/* Forward declarations for the following functions that are usually
inlined. In case inlining is disabled, or inlining is not
@@ -418,11 +419,11 @@ extern void _dino_deref (struct ext2_inode *inode);
EXT2FS_EI struct ext2_inode *
dino_ref (ino_t inum)
{
- unsigned long inodes_per_group = sblock->s_inodes_per_group;
+ unsigned long inodes_per_group = le32toh (sblock->s_inodes_per_group);
unsigned long bg_num = (inum - 1) / inodes_per_group;
unsigned long group_inum = (inum - 1) % inodes_per_group;
struct ext2_group_desc *bg = group_desc (bg_num);
- block_t block = bg->bg_inode_table + (group_inum / inodes_per_block);
+ block_t block = le32toh (bg->bg_inode_table) + (group_inum / inodes_per_block);
struct ext2_inode *inode = disk_cache_block_ref (block);
inode += group_inum % inodes_per_block;
ext2_debug ("(%llu) = %p", inum, inode);
diff --git a/ext2fs/getblk.c b/ext2fs/getblk.c
index 43daf6c9..00a35135 100644
--- a/ext2fs/getblk.c
+++ b/ext2fs/getblk.c
@@ -152,7 +152,7 @@ inode_getblk (struct node *node, int nr, int create, int zero,
goal =
(diskfs_node_disknode (node)->info.i_block_group
* EXT2_BLOCKS_PER_GROUP (sblock))
- + sblock->s_first_data_block;
+ + le32toh (sblock->s_first_data_block);
}
*result = ext2_alloc_block (node, goal, zero);
diff --git a/ext2fs/hyper.c b/ext2fs/hyper.c
index 0bcf0c72..04da86a7 100644
--- a/ext2fs/hyper.c
+++ b/ext2fs/hyper.c
@@ -42,7 +42,7 @@ allocate_mod_map (void)
global blocks are actually modified so the pager can write only them. */
{
/* One bit per filesystem block. */
- mod_map_size = sblock->s_blocks_count >> 3;
+ mod_map_size = le32toh (sblock->s_blocks_count) >> 3;
modified_global_blocks = mmap (0, mod_map_size, PROT_READ|PROT_WRITE,
MAP_ANON, 0, 0);
assert_backtrace (modified_global_blocks != (void *) -1);
@@ -70,15 +70,15 @@ get_hypermetadata (void)
if (err || read != SBLOCK_SIZE)
ext2_panic ("Cannot read hypermetadata");
- if (sblock->s_magic != EXT2_SUPER_MAGIC
+ if (sblock->s_magic != htole16 (EXT2_SUPER_MAGIC)
#ifdef EXT2FS_PRE_02B_COMPAT
- && sblock->s_magic != EXT2_PRE_02B_MAGIC
+ && sblock->s_magic != htole16 (EXT2_PRE_02B_MAGIC)
#endif
)
ext2_panic ("bad magic number %#x (should be %#x)",
- sblock->s_magic, EXT2_SUPER_MAGIC);
+ le16toh (sblock->s_magic), EXT2_SUPER_MAGIC);
- log2_block_size = EXT2_MIN_BLOCK_LOG_SIZE + sblock->s_log_block_size;
+ log2_block_size = EXT2_MIN_BLOCK_LOG_SIZE + le32toh(sblock->s_log_block_size);
block_size = 1 << log2_block_size;
if (block_size > EXT2_MAX_BLOCK_SIZE)
@@ -98,10 +98,10 @@ get_hypermetadata (void)
ext2_panic ("block size %d isn't a power-of-two multiple of 512!",
block_size);
- if ((store->size >> log2_block_size) < sblock->s_blocks_count)
+ if ((store->size >> log2_block_size) < le32toh (sblock->s_blocks_count))
ext2_panic ("disk size (%qd bytes) too small; superblock says we need %qd",
(long long int) store->size,
- (long long int) sblock->s_blocks_count << log2_block_size);
+ (long long int) le32toh (sblock->s_blocks_count) << log2_block_size);
if (log2_dev_blocks_per_fs_block != 0
&& (store->size & ((1 << log2_dev_blocks_per_fs_block) - 1)) != 0)
ext2_warning ("%Ld (%zd byte) device blocks "
@@ -112,12 +112,12 @@ get_hypermetadata (void)
/* Set these handy variables. */
inodes_per_block = block_size / EXT2_INODE_SIZE (sblock);
- frag_size = EXT2_MIN_FRAG_SIZE << sblock->s_log_frag_size;
+ frag_size = EXT2_MIN_FRAG_SIZE << le32toh (sblock->s_log_frag_size);
if (frag_size == 0)
ext2_panic ("frag size is zero!");
frags_per_block = block_size / frag_size;
- if (sblock->s_rev_level > EXT2_GOOD_OLD_REV)
+ if (le32toh (sblock->s_rev_level) > EXT2_GOOD_OLD_REV)
{
features = EXT2_HAS_INCOMPAT_FEATURE(sblock, EXT2_FEATURE_INCOMPAT_UNSUPPORTED);
if (features)
@@ -132,21 +132,21 @@ get_hypermetadata (void)
features);
diskfs_readonly = 1;
}
- if (sblock->s_inode_size != EXT2_GOOD_OLD_INODE_SIZE)
- ext2_panic ("inode size %d isn't supported", sblock->s_inode_size);
+ if (le16toh (sblock->s_inode_size) != EXT2_GOOD_OLD_INODE_SIZE)
+ ext2_panic ("inode size %d isn't supported", le16toh (sblock->s_inode_size));
}
groups_count =
- ((sblock->s_blocks_count - sblock->s_first_data_block +
- sblock->s_blocks_per_group - 1)
- / sblock->s_blocks_per_group);
+ ((le32toh (sblock->s_blocks_count) - le32toh (sblock->s_first_data_block) +
+ le32toh (sblock->s_blocks_per_group) - 1)
+ / le32toh (sblock->s_blocks_per_group));
- itb_per_group = sblock->s_inodes_per_group / inodes_per_block;
+ itb_per_group = le32toh (sblock->s_inodes_per_group) / inodes_per_block;
desc_per_block = block_size / sizeof (struct ext2_group_desc);
addr_per_block = block_size / sizeof (block_t);
db_per_group = (groups_count + desc_per_block - 1) / desc_per_block;
- ext2fs_clean = sblock->s_state & EXT2_VALID_FS;
+ ext2fs_clean = sblock->s_state & htole16 (EXT2_VALID_FS);
if (! ext2fs_clean)
{
ext2_warning ("FILESYSTEM NOT UNMOUNTED CLEANLY; PLEASE fsck");
@@ -183,16 +183,16 @@ map_hypermetadata (void)
error_t
diskfs_set_hypermetadata (int wait, int clean)
{
- if (clean && ext2fs_clean && !(sblock->s_state & EXT2_VALID_FS))
+ if (clean && ext2fs_clean && !(sblock->s_state & htole16 (EXT2_VALID_FS)))
/* The filesystem is clean, so we need to set the clean flag. */
{
- sblock->s_state |= EXT2_VALID_FS;
+ sblock->s_state |= htole16 (EXT2_VALID_FS);
sblock_dirty = 1;
}
- else if (!clean && (sblock->s_state & EXT2_VALID_FS))
+ else if (!clean && (sblock->s_state & htole16 (EXT2_VALID_FS)))
/* The filesystem just became dirty, so clear the clean flag. */
{
- sblock->s_state &= ~EXT2_VALID_FS;
+ sblock->s_state &= htole16 (~EXT2_VALID_FS);
sblock_dirty = 1;
wait = 1;
}
@@ -221,6 +221,6 @@ diskfs_readonly_changed (int readonly)
mprotect (disk_cache, disk_cache_size,
PROT_READ | (readonly ? 0 : PROT_WRITE));
- if (!readonly && !(sblock->s_state & EXT2_VALID_FS))
+ if (!readonly && !(sblock->s_state & htole16 (EXT2_VALID_FS)))
ext2_warning ("UNCLEANED FILESYSTEM NOW WRITABLE");
}
diff --git a/ext2fs/ialloc.c b/ext2fs/ialloc.c
index 49122319..9ab631db 100644
--- a/ext2fs/ialloc.c
+++ b/ext2fs/ialloc.c
@@ -66,18 +66,18 @@ diskfs_free_node (struct node *np, mode_t old_mode)
pthread_spin_lock (&global_lock);
- if (inum < EXT2_FIRST_INO (sblock) || inum > sblock->s_inodes_count)
+ if (inum < EXT2_FIRST_INO (sblock) || inum > le32toh (sblock->s_inodes_count))
{
ext2_error ("reserved inode or nonexistent inode: %Ld", inum);
pthread_spin_unlock (&global_lock);
return;
}
- block_group = (inum - 1) / sblock->s_inodes_per_group;
- bit = (inum - 1) % sblock->s_inodes_per_group;
+ block_group = (inum - 1) / le32toh (sblock->s_inodes_per_group);
+ bit = (inum - 1) % le32toh (sblock->s_inodes_per_group);
gdp = group_desc (block_group);
- bh = disk_cache_block_ref (gdp->bg_inode_bitmap);
+ bh = disk_cache_block_ref (le32toh (gdp->bg_inode_bitmap));
if (!clear_bit (bit, bh))
ext2_warning ("bit already cleared for inode %Ld", inum);
@@ -86,13 +86,13 @@ diskfs_free_node (struct node *np, mode_t old_mode)
disk_cache_block_ref_ptr (bh);
record_global_poke (bh);
- gdp->bg_free_inodes_count++;
+ gdp->bg_free_inodes_count = htole16 (le16toh (gdp->bg_free_inodes_count) + 1);
if (S_ISDIR (old_mode))
- gdp->bg_used_dirs_count--;
+ gdp->bg_used_dirs_count = htole16 (le16toh (gdp->bg_used_dirs_count) - 1);
disk_cache_block_ref_ptr (gdp);
record_global_poke (gdp);
- sblock->s_free_inodes_count++;
+ sblock->s_free_inodes_count = htole32 (le32toh (sblock->s_free_inodes_count) + 1);
}
disk_cache_block_deref (bh);
@@ -131,14 +131,14 @@ repeat:
if (S_ISDIR (mode))
{
- avefreei = sblock->s_free_inodes_count / groups_count;
+ avefreei = le32toh (sblock->s_free_inodes_count) / groups_count;
/* I am not yet convinced that this next bit is necessary.
i = inode_group_num(dir_inum);
for (j = 0; j < groups_count; j++)
{
tmp = group_desc (i);
- if ((tmp->bg_used_dirs_count << 8) < tmp->bg_free_inodes_count)
+ if ((le16toh (tmp->bg_used_dirs_count) << 8) < le16toh (tmp->bg_free_inodes_count))
{
gdp = tmp;
break;
@@ -153,11 +153,12 @@ repeat:
for (j = 0; j < groups_count; j++)
{
tmp = group_desc (j);
- if (tmp->bg_free_inodes_count
- && tmp->bg_free_inodes_count >= avefreei)
+ if (le16toh (tmp->bg_free_inodes_count)
+ && le16toh (tmp->bg_free_inodes_count) >= avefreei)
{
if (!gdp ||
- (tmp->bg_free_blocks_count > gdp->bg_free_blocks_count))
+ (le16toh (tmp->bg_free_blocks_count) >
+ le16toh (gdp->bg_free_blocks_count)))
{
i = j;
gdp = tmp;
@@ -173,7 +174,7 @@ repeat:
*/
i = inode_group_num(dir_inum);
tmp = group_desc (i);
- if (tmp->bg_free_inodes_count)
+ if (le16toh (tmp->bg_free_inodes_count))
gdp = tmp;
else
{
@@ -187,7 +188,7 @@ repeat:
if (i >= groups_count)
i -= groups_count;
tmp = group_desc (i);
- if (tmp->bg_free_inodes_count)
+ if (le16toh (tmp->bg_free_inodes_count))
{
gdp = tmp;
break;
@@ -205,7 +206,7 @@ repeat:
if (++i >= groups_count)
i = 0;
tmp = group_desc (i);
- if (tmp->bg_free_inodes_count)
+ if (le16toh (tmp->bg_free_inodes_count))
{
gdp = tmp;
break;
@@ -220,10 +221,10 @@ repeat:
return 0;
}
- bh = disk_cache_block_ref (gdp->bg_inode_bitmap);
+ bh = disk_cache_block_ref (le32toh (gdp->bg_inode_bitmap));
if ((inum =
- find_first_zero_bit ((unsigned long *) bh, sblock->s_inodes_per_group))
- < sblock->s_inodes_per_group)
+ find_first_zero_bit ((unsigned long *) bh, le32toh (sblock->s_inodes_per_group)))
+ < le32toh (sblock->s_inodes_per_group))
{
if (set_bit (inum, bh))
{
@@ -239,7 +240,7 @@ repeat:
{
disk_cache_block_deref (bh);
bh = NULL;
- if (gdp->bg_free_inodes_count != 0)
+ if (le16toh (gdp->bg_free_inodes_count) != 0)
{
ext2_error ("free inodes count corrupted in group %d", i);
inum = 0;
@@ -248,8 +249,8 @@ repeat:
goto repeat;
}
- inum += i * sblock->s_inodes_per_group + 1;
- if (inum < EXT2_FIRST_INO (sblock) || inum > sblock->s_inodes_count)
+ inum += i * le32toh (sblock->s_inodes_per_group) + 1;
+ if (inum < EXT2_FIRST_INO (sblock) || inum > le32toh (sblock->s_inodes_count))
{
ext2_error ("reserved inode or inode > inodes count - "
"block_group = %d,inode=%llu", i, inum);
@@ -257,13 +258,13 @@ repeat:
goto sync_out;
}
- gdp->bg_free_inodes_count--;
+ gdp->bg_free_inodes_count = htole16 (le16toh (gdp->bg_free_inodes_count) - 1);
if (S_ISDIR (mode))
- gdp->bg_used_dirs_count++;
+ gdp->bg_used_dirs_count = htole16 (le16toh (gdp->bg_used_dirs_count) + 1);
disk_cache_block_ref_ptr (gdp);
record_global_poke (gdp);
- sblock->s_free_inodes_count--;
+ sblock->s_free_inodes_count = htole32( le32toh(sblock->s_free_inodes_count) - 1);
sblock_dirty = 1;
sync_out:
@@ -381,20 +382,20 @@ ext2_count_free_inodes ()
{
void *bh;
gdp = group_desc (i);
- desc_count += gdp->bg_free_inodes_count;
- bh = disk_cache_block_ref (gdp->bg_inode_bitmap);
- x = count_free (bh, sblock->s_inodes_per_group / 8);
+ desc_count += le16toh (gdp->bg_free_inodes_count);
+ bh = disk_cache_block_ref (le32toh (gdp->bg_inode_bitmap));
+ x = count_free (bh, le32toh (sblock->s_inodes_per_group) / 8);
disk_cache_block_deref (bh);
ext2_debug ("group %d: stored = %d, counted = %lu",
- i, gdp->bg_free_inodes_count, x);
+ i, le16toh (gdp->bg_free_inodes_count), x);
bitmap_count += x;
}
ext2_debug ("stored = %u, computed = %lu, %lu",
- sblock->s_free_inodes_count, desc_count, bitmap_count);
+ le32toh (sblock->s_free_inodes_count), desc_count, bitmap_count);
pthread_spin_unlock (&global_lock);
return desc_count;
#else
- return sblock->s_free_inodes_count;
+ return le32toh (sblock->s_free_inodes_count);
#endif
}
@@ -416,20 +417,20 @@ ext2_check_inodes_bitmap ()
{
void *bh;
gdp = group_desc (i);
- desc_count += gdp->bg_free_inodes_count;
- bh = disk_cache_block_ref (gdp->bg_inode_bitmap);
- x = count_free (bh, sblock->s_inodes_per_group / 8);
+ desc_count += le16toh (gdp->bg_free_inodes_count);
+ bh = disk_cache_block_ref (le32toh (gdp->bg_inode_bitmap));
+ x = count_free (bh, le32toh (sblock->s_inodes_per_group) / 8);
disk_cache_block_deref (bh);
- if (gdp->bg_free_inodes_count != x)
+ if (le16toh (gdp->bg_free_inodes_count) != x)
ext2_error ("wrong free inodes count in group %d, "
"stored = %d, counted = %lu",
- i, gdp->bg_free_inodes_count, x);
+ i, le16toh (gdp->bg_free_inodes_count), x);
bitmap_count += x;
}
- if (sblock->s_free_inodes_count != bitmap_count)
+ if (le32toh (sblock->s_free_inodes_count) != bitmap_count)
ext2_error ("wrong free inodes count in super block, "
"stored = %lu, counted = %lu",
- (unsigned long) sblock->s_free_inodes_count, bitmap_count);
+ (unsigned long) le32toh (sblock->s_free_inodes_count), bitmap_count);
pthread_spin_unlock (&global_lock);
}
diff --git a/ext2fs/inode.c b/ext2fs/inode.c
index 3bfbdfdb..30219c71 100644
--- a/ext2fs/inode.c
+++ b/ext2fs/inode.c
@@ -130,45 +130,45 @@ diskfs_user_read_node (struct node *np, struct lookup_context *ctx)
st->st_ino = np->cache_id;
st->st_blksize = vm_page_size * 2;
- st->st_nlink = di->i_links_count;
- st->st_size = di->i_size;
- st->st_gen = di->i_generation;
+ st->st_nlink = le16toh (di->i_links_count);
+ st->st_size = le32toh (di->i_size);
+ st->st_gen = le32toh (di->i_generation);
- st->st_atim.tv_sec = di->i_atime;
+ st->st_atim.tv_sec = le32toh (di->i_atime);
#ifdef not_yet
/* ``struct ext2_inode'' doesn't do better than sec. precision yet. */
#else
st->st_atim.tv_nsec = 0;
#endif
- st->st_mtim.tv_sec = di->i_mtime;
+ st->st_mtim.tv_sec = le32toh (di->i_mtime);
#ifdef not_yet
/* ``struct ext2_inode'' doesn't do better than sec. precision yet. */
#else
st->st_mtim.tv_nsec = 0;
#endif
- st->st_ctim.tv_sec = di->i_ctime;
+ st->st_ctim.tv_sec = le32toh (di->i_ctime);
#ifdef not_yet
/* ``struct ext2_inode'' doesn't do better than sec. precision yet. */
#else
st->st_ctim.tv_nsec = 0;
#endif
- st->st_blocks = di->i_blocks;
+ st->st_blocks = le32toh (di->i_blocks);
st->st_flags = 0;
- if (di->i_flags & EXT2_APPEND_FL)
+ if (di->i_flags & htole32 (EXT2_APPEND_FL))
st->st_flags |= UF_APPEND;
- if (di->i_flags & EXT2_NODUMP_FL)
+ if (di->i_flags & htole32 (EXT2_NODUMP_FL))
st->st_flags |= UF_NODUMP;
- if (di->i_flags & EXT2_IMMUTABLE_FL)
+ if (di->i_flags & htole32 (EXT2_IMMUTABLE_FL))
st->st_flags |= UF_IMMUTABLE;
- if (sblock->s_creator_os == EXT2_OS_HURD)
+ if (sblock->s_creator_os == htole32 (EXT2_OS_HURD))
{
- st->st_mode = di->i_mode | (di->i_mode_high << 16);
+ st->st_mode = le16toh (di->i_mode) | (le16toh (di->i_mode_high) << 16);
st->st_mode &= ~S_ITRANS;
- if (di->i_translator)
+ if (le32toh (di->i_translator))
st->st_mode |= S_IPTRANS;
else
{
@@ -178,41 +178,41 @@ diskfs_user_read_node (struct node *np, struct lookup_context *ctx)
st->st_mode |= S_IPTRANS;
}
- st->st_uid = di->i_uid | (di->i_uid_high << 16);
- st->st_gid = di->i_gid | (di->i_gid_high << 16);
+ st->st_uid = le16toh (di->i_uid) | (le16toh (di->i_uid_high) << 16);
+ st->st_gid = le16toh (di->i_gid) | (le16toh (di->i_gid_high) << 16);
- st->st_author = di->i_author;
+ st->st_author = le32toh (di->i_author);
if (st->st_author == -1)
st->st_author = st->st_uid;
}
else
{
- st->st_mode = di->i_mode & ~S_ITRANS;
- st->st_uid = di->i_uid;
- st->st_gid = di->i_gid;
+ st->st_mode = le16toh (di->i_mode) & ~S_ITRANS;
+ st->st_uid = le16toh (di->i_uid);
+ st->st_gid = le16toh (di->i_gid);
st->st_author = st->st_uid;
np->author_tracks_uid = 1;
}
/* Setup the ext2fs auxiliary inode info. */
- info->i_dtime = di->i_dtime;
- info->i_flags = di->i_flags;
- info->i_faddr = di->i_faddr;
+ info->i_dtime = le32toh (di->i_dtime);
+ info->i_flags = le32toh (di->i_flags);
+ info->i_faddr = le32toh (di->i_faddr);
info->i_frag_no = di->i_frag;
info->i_frag_size = di->i_fsize;
info->i_osync = 0;
- info->i_file_acl = di->i_file_acl;
+ info->i_file_acl = le32toh (di->i_file_acl);
if (S_ISDIR (st->st_mode))
- info->i_dir_acl = di->i_dir_acl;
+ info->i_dir_acl = le32toh (di->i_dir_acl);
else
{
info->i_dir_acl = 0;
if (sizeof (off_t) >= 8)
/* 64bit file size */
- st->st_size += ((off_t) di->i_size_high) << 32;
+ st->st_size += ((off_t) le32toh (di->i_size_high)) << 32;
else
{
- if (di->i_size_high) /* XXX */
+ if (le32toh (di->i_size_high)) /* XXX */
{
dino_deref (di);
ext2_warning ("cannot handle large file inode %Ld", np->cache_id);
@@ -230,14 +230,18 @@ diskfs_user_read_node (struct node *np, struct lookup_context *ctx)
dn->last_page_partially_writable = 0;
if (S_ISCHR (st->st_mode) || S_ISBLK (st->st_mode))
- st->st_rdev = di->i_block[0];
+ st->st_rdev = le32toh (di->i_block[0]);
else
{
+ /*
+ * NOTE! The in-memory inode i_data array is in little-endian order
+ * even on big-endian machines: we do NOT byteswap the block numbers!
+ */
memcpy (info->i_data, di->i_block,
EXT2_N_BLOCKS * sizeof info->i_data[0]);
st->st_rdev = 0;
}
- dn->info_i_translator = di->i_translator;
+ dn->info_i_translator = le32toh (di->i_translator);
dino_deref (di);
diskfs_end_catch_exception ();
@@ -280,7 +284,7 @@ diskfs_user_read_node (struct node *np, struct lookup_context *ctx)
static inline error_t
check_high_bits (struct node *np, long l)
{
- if (sblock->s_creator_os == EXT2_OS_HURD)
+ if (sblock->s_creator_os == htole32 (EXT2_OS_HURD))
return 0;
/* Linux 2.3.42 has a mount-time option (not a bit stored on disk)
@@ -325,7 +329,7 @@ diskfs_validate_mode_change (struct node *np, mode_t mode)
error_t
diskfs_validate_author_change (struct node *np, uid_t author)
{
- if (sblock->s_creator_os == EXT2_OS_HURD)
+ if (sblock->s_creator_os == htole32 (EXT2_OS_HURD))
return 0;
else
/* For non-hurd filesystems, the author & owner are the same. */
@@ -372,7 +376,7 @@ write_node (struct node *np)
di = dino_ref (np->cache_id);
- di->i_generation = st->st_gen;
+ di->i_generation = htole32 (st->st_gen);
/* We happen to know that the stat mode bits are the same
as the ext2fs mode bits. */
@@ -380,17 +384,17 @@ write_node (struct node *np)
/* Only the low 16 bits of these fields are standard across all ext2
implementations. */
- di->i_mode = st->st_mode & 0xFFFF & ~S_ITRANS;
- di->i_uid = st->st_uid & 0xFFFF;
- di->i_gid = st->st_gid & 0xFFFF;
+ di->i_mode = htole16 (st->st_mode & 0xFFFF & ~S_ITRANS);
+ di->i_uid = htole16 (st->st_uid & 0xFFFF);
+ di->i_gid = htole16 (st->st_gid & 0xFFFF);
- if (sblock->s_creator_os == EXT2_OS_HURD)
+ if (sblock->s_creator_os == htole32 (EXT2_OS_HURD))
/* If this is a hurd-compatible filesystem, write the high bits too. */
{
- di->i_mode_high = (st->st_mode >> 16) & 0xffff & ~S_ITRANS;
- di->i_uid_high = st->st_uid >> 16;
- di->i_gid_high = st->st_gid >> 16;
- di->i_author = st->st_author;
+ di->i_mode_high = htole16 ((st->st_mode >> 16) & 0xffff & ~S_ITRANS);
+ di->i_uid_high = htole16 (st->st_uid >> 16);
+ di->i_gid_high = htole16 (st->st_gid >> 16);
+ di->i_author = htole32 (st->st_author);
}
else
/* No hurd extensions should be turned on. */
@@ -401,20 +405,20 @@ write_node (struct node *np)
assert_backtrace (np->author_tracks_uid && st->st_author == st->st_uid);
}
- di->i_links_count = st->st_nlink;
+ di->i_links_count = htole16 (st->st_nlink);
- di->i_atime = st->st_atim.tv_sec;
+ di->i_atime = htole32(st->st_atim.tv_sec);
#ifdef not_yet
/* ``struct ext2_inode'' doesn't do better than sec. precision yet. */
- di->i_atime.tv_nsec = st->st_atim.tv_nsec;
+ di->i_atime.tv_nsec = htole32 (st->st_atim.tv_nsec);
#endif
- di->i_mtime = st->st_mtim.tv_sec;
+ di->i_mtime = htole32 (st->st_mtim.tv_sec);
#ifdef not_yet
- di->i_mtime.tv_nsec = st->st_mtim.tv_nsec;
+ di->i_mtime.tv_nsec = htole32 (st->st_mtim.tv_nsec);
#endif
- di->i_ctime = st->st_ctim.tv_sec;
+ di->i_ctime = htole32 (st->st_ctim.tv_sec);
#ifdef not_yet
- di->i_ctime.tv_nsec = st->st_ctim.tv_nsec;
+ di->i_ctime.tv_nsec = htole32 (st->st_ctim.tv_nsec);
#endif
/* Convert generic flags in ST->st_flags to ext2-specific flags in DI
@@ -429,25 +433,25 @@ write_node (struct node *np)
info->i_flags |= EXT2_NODUMP_FL;
if (st->st_flags & UF_IMMUTABLE)
info->i_flags |= EXT2_IMMUTABLE_FL;
- di->i_flags = info->i_flags;
+ di->i_flags = htole32 (info->i_flags);
if (st->st_mode == 0)
/* Set dtime non-zero to indicate a deleted file.
We don't clear i_size, i_blocks, and i_translator in this case,
to give "undeletion" utilities a chance. */
- di->i_dtime = di->i_mtime;
+ di->i_dtime = htole32 (di->i_mtime);
else
{
- di->i_dtime = 0;
- di->i_size = st->st_size;
+ di->i_dtime = htole32 (0);
+ di->i_size = htole32 (st->st_size);
if (sizeof (off_t) >= 8 && !S_ISDIR (st->st_mode))
/* 64bit file size */
- di->i_size_high = st->st_size >> 32;
- di->i_blocks = st->st_blocks;
+ di->i_size_high = htole32 (st->st_size >> 32);
+ di->i_blocks = htole32 (st->st_blocks);
}
if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
- di->i_block[0] = st->st_rdev;
+ di->i_block[0] = htole32 (st->st_rdev);
else
memcpy (di->i_block, diskfs_node_disknode (np)->info.i_data,
EXT2_N_BLOCKS * sizeof di->i_block[0]);
@@ -529,13 +533,13 @@ diskfs_set_statfs (struct statfs *st)
{
st->f_type = FSTYPE_EXT2FS;
st->f_bsize = block_size;
- st->f_blocks = sblock->s_blocks_count;
- st->f_bfree = sblock->s_free_blocks_count;
- st->f_bavail = st->f_bfree - sblock->s_r_blocks_count;
- if (st->f_bfree < sblock->s_r_blocks_count)
+ st->f_blocks = le32toh (sblock->s_blocks_count);
+ st->f_bfree = le32toh (sblock->s_free_blocks_count);
+ st->f_bavail = st->f_bfree - le32toh (sblock->s_r_blocks_count);
+ if (st->f_bfree < le32toh (sblock->s_r_blocks_count))
st->f_bavail = 0;
- st->f_files = sblock->s_inodes_count;
- st->f_ffree = sblock->s_free_inodes_count;
+ st->f_files = le32toh (sblock->s_inodes_count);
+ st->f_ffree = le32toh (sblock->s_free_inodes_count);
st->f_fsid = getpid ();
st->f_namelen = 0;
st->f_favail = st->f_ffree;
@@ -553,7 +557,7 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen,
assert_backtrace (!diskfs_readonly);
- if (sblock->s_creator_os != EXT2_OS_HURD)
+ if (sblock->s_creator_os != htole32 (EXT2_OS_HURD))
return EOPNOTSUPP;
err = diskfs_catch_exception ();
@@ -569,7 +573,7 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen,
struct ext2_inode *di;
di = dino_ref (np->cache_id);
- blkno = di->i_translator;
+ blkno = le32toh (di->i_translator);
/* If a legacy translator record found, clear it */
if (blkno)
@@ -577,7 +581,7 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen,
ext2_debug ("Old translator record found, clear it");
/* Clear block for translator going away. */
- di->i_translator = 0;
+ di->i_translator = htole32 (0);
diskfs_node_disknode (np)->info_i_translator = 0;
record_global_poke (di);
ext2_free_blocks (blkno, 1);
@@ -628,7 +632,7 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen,
return ENAMETOOLONG;
di = dino_ref (np->cache_id);
- blkno = di->i_translator;
+ blkno = le32toh (di->i_translator);
if (namelen && !blkno)
{
@@ -648,7 +652,7 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen,
blkno =
ext2_new_block ((diskfs_node_disknode (np)->info.i_block_group
* EXT2_BLOCKS_PER_GROUP (sblock))
- + sblock->s_first_data_block,
+ + le32toh (sblock->s_first_data_block),
0, 0, 0);
if (blkno == 0)
{
@@ -664,7 +668,7 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen,
np->dn_stat.st_mode = newmode;
}
- di->i_translator = blkno;
+ di->i_translator = htole32 (blkno);
diskfs_node_disknode (np)->info_i_translator = blkno;
record_global_poke (di);
@@ -674,7 +678,7 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen,
else if (!namelen && blkno)
{
/* Clear block for translator going away. */
- di->i_translator = 0;
+ di->i_translator = htole32 (0);
diskfs_node_disknode (np)->info_i_translator = 0;
record_global_poke (di);
ext2_free_blocks (blkno, 1);
@@ -719,7 +723,7 @@ diskfs_get_translator (struct node *np, char **namep, unsigned *namelen)
void *transloc;
struct ext2_inode *di;
- if (sblock->s_creator_os != EXT2_OS_HURD)
+ if (sblock->s_creator_os != htole32 (EXT2_OS_HURD))
return EOPNOTSUPP;
err = diskfs_catch_exception ();
@@ -727,7 +731,7 @@ diskfs_get_translator (struct node *np, char **namep, unsigned *namelen)
return err;
di = dino_ref (np->cache_id);
- blkno = di->i_translator;
+ blkno = le32toh (di->i_translator);
dino_deref (di);
/* If an old translator record found, read it firstly */
diff --git a/ext2fs/xattr.c b/ext2fs/xattr.c
index ff84a3b9..ab6f5600 100644
--- a/ext2fs/xattr.c
+++ b/ext2fs/xattr.c
@@ -91,17 +91,17 @@ xattr_entry_hash (struct ext2_xattr_header *header,
if (entry->e_value_block == 0 && entry->e_value_size != 0)
{
- __u32 *value = (__u32 *) ((char *) header + entry->e_value_offs);
- for (n = (entry->e_value_size + EXT2_XATTR_ROUND) >>
+ __u32 *value = (__u32 *) ((char *) header + le16toh (entry->e_value_offs));
+ for (n = (le32toh (entry->e_value_size) + EXT2_XATTR_ROUND) >>
EXT2_XATTR_PAD_BITS; n; n--)
{
hash = (hash << VALUE_HASH_SHIFT)
^ (hash >> (8 * sizeof (hash) - VALUE_HASH_SHIFT))
- ^ *value++;
+ ^ le32toh(*value++);
}
}
- entry->e_hash = hash;
+ entry->e_hash = htole32 (hash);
}
@@ -127,7 +127,7 @@ xattr_entry_rehash (struct ext2_xattr_header *header,
position = EXT2_XATTR_ENTRY_FIRST (header);
while (!EXT2_XATTR_ENTRY_LAST (position))
{
- if (position->e_hash == 0)
+ if (le32toh (position->e_hash) == 0)
{
/* Block is not shared if an entry's hash value == 0 */
hash = 0;
@@ -136,12 +136,12 @@ xattr_entry_rehash (struct ext2_xattr_header *header,
hash = (hash << BLOCK_HASH_SHIFT)
^ (hash >> (8 * sizeof (hash) - BLOCK_HASH_SHIFT))
- ^ position->e_hash;
+ ^ le32toh (position->e_hash);
position = EXT2_XATTR_ENTRY_NEXT (position);
}
- header->h_hash = hash;
+ header->h_hash = htole32 (hash);
}
@@ -237,14 +237,14 @@ xattr_entry_get (void *block, struct ext2_xattr_entry *entry,
if (value)
{
- if (*len < entry->e_value_size)
+ if (*len < le32toh (entry->e_value_size))
{
return ERANGE;
}
- memcpy (value, block + entry->e_value_offs, entry->e_value_size);
+ memcpy (value, block + le16toh (entry->e_value_offs), le32toh (entry->e_value_size));
}
- *len = entry->e_value_size;
+ *len = le32toh (entry->e_value_size);
return 0;
}
@@ -295,13 +295,13 @@ xattr_entry_create (struct ext2_xattr_header *header,
position->e_name_len = name_len;
position->e_name_index = index;
- position->e_value_offs = end + rest - value_size;
+ position->e_value_offs = htole16 (end + rest - value_size);
position->e_value_block = 0;
- position->e_value_size = len;
+ position->e_value_size = htole32 (len);
strncpy (position->e_name, name, name_len);
- memcpy ((char *) header + position->e_value_offs, value, len);
- memset ((char *) header + position->e_value_offs + len, 0,
+ memcpy ((char *) header + le16toh (position->e_value_offs), value, len);
+ memset ((char *) header + le16toh (position->e_value_offs) + len, 0,
value_size - len);
return 0;
@@ -325,9 +325,9 @@ xattr_entry_remove (struct ext2_xattr_header *header,
struct ext2_xattr_entry *entry;
/* Remove the value */
- size = EXT2_XATTR_ALIGN (position->e_value_size);
+ size = EXT2_XATTR_ALIGN (le32toh (position->e_value_size));
start = EXT2_XATTR_ENTRY_OFFSET (header, last) + rest;
- end = position->e_value_offs;
+ end = le16toh (position->e_value_offs);
memmove ((char *) header + start + size, (char *) header + start,
end - start);
@@ -337,8 +337,8 @@ xattr_entry_remove (struct ext2_xattr_header *header,
entry = EXT2_XATTR_ENTRY_FIRST (header);
while (!EXT2_XATTR_ENTRY_LAST (entry))
{
- if (entry->e_value_offs < end)
- entry->e_value_offs += size;
+ if (le16toh (entry->e_value_offs) < end)
+ entry->e_value_offs = htole16 (le16toh (entry->e_value_offs) + size);
entry = EXT2_XATTR_ENTRY_NEXT (entry);
}
@@ -372,7 +372,7 @@ xattr_entry_replace (struct ext2_xattr_header *header,
size_t old_size;
size_t new_size;
- old_size = EXT2_XATTR_ALIGN (position->e_value_size);
+ old_size = EXT2_XATTR_ALIGN (le32toh (position->e_value_size));
new_size = EXT2_XATTR_ALIGN (len);
if (rest < 4 || new_size - old_size > rest - 4)
@@ -385,7 +385,7 @@ xattr_entry_replace (struct ext2_xattr_header *header,
struct ext2_xattr_entry *entry;
start = EXT2_XATTR_ENTRY_OFFSET (header, last) + rest;
- end = position->e_value_offs;
+ end = le16toh (position->e_value_offs);
/* Remove the old value */
memmove ((char *) header + start + old_size, (char *) header + start,
@@ -395,19 +395,19 @@ xattr_entry_replace (struct ext2_xattr_header *header,
entry = EXT2_XATTR_ENTRY_FIRST (header);
while (!EXT2_XATTR_ENTRY_LAST (entry))
{
- if (entry->e_value_offs < end)
- entry->e_value_offs += old_size;
+ if (le16toh (entry->e_value_offs) < end)
+ entry->e_value_offs = htole16 ( le16toh (entry->e_value_offs) + old_size);
entry = EXT2_XATTR_ENTRY_NEXT (entry);
}
- position->e_value_offs = start - (new_size - old_size);
+ position->e_value_offs = htole16 (start - (new_size - old_size));
}
- position->e_value_size = len;
+ position->e_value_size = htole32 (len);
/* Write the new value */
- memcpy ((char *) header + position->e_value_offs, value, len);
- memset ((char *) header + position->e_value_offs + len, 0, new_size - len);
+ memcpy ((char *) header + le16toh (position->e_value_offs), value, len);
+ memset ((char *) header + le16toh (position->e_value_offs) + len, 0, new_size - len);
return 0;
@@ -450,14 +450,15 @@ ext2_free_xattr_block (struct node *np)
block = disk_cache_block_ref (blkno);
header = EXT2_XATTR_HEADER (block);
- if (header->h_magic != EXT2_XATTR_BLOCK_MAGIC || header->h_blocks != 1)
+ if (header->h_magic != htole32 (EXT2_XATTR_BLOCK_MAGIC)
+ || header->h_blocks != htole32 (1))
{
ext2_warning ("Invalid extended attribute block.");
err = EIO;
goto cleanup;
}
- if (header->h_refcount == 1)
+ if (le32toh (header->h_refcount) == 1)
{
ext2_debug("free block %d", blkno);
@@ -470,9 +471,9 @@ ext2_free_xattr_block (struct node *np)
}
else
{
- ext2_debug("h_refcount: %d", header->h_refcount);
+ ext2_debug("h_refcount: %d", le32toh (header->h_refcount));
- header->h_refcount--;
+ header->h_refcount = htole32 (le32toh (header->h_refcount) - 1);
record_global_poke (block);
}
@@ -535,7 +536,8 @@ ext2_list_xattr (struct node *np, char *buffer, size_t *len)
block = disk_cache_block_ref (blkno);
header = EXT2_XATTR_HEADER (block);
- if (header->h_magic != EXT2_XATTR_BLOCK_MAGIC || header->h_blocks != 1)
+ if (header->h_magic != htole32 (EXT2_XATTR_BLOCK_MAGIC)
+ || header->h_blocks != htole32 (1))
{
ext2_warning ("Invalid extended attribute block.");
err = EIO;
@@ -609,7 +611,8 @@ ext2_get_xattr (struct node *np, const char *name, char *value, size_t *len)
dino_deref (ei);
header = EXT2_XATTR_HEADER (block);
- if (header->h_magic != EXT2_XATTR_BLOCK_MAGIC || header->h_blocks != 1)
+ if (header->h_magic != htole32 (EXT2_XATTR_BLOCK_MAGIC)
+ || header->h_blocks != htole32 (1))
{
ext2_warning ("Invalid extended attribute block.");
err = EIO;
@@ -699,7 +702,7 @@ ext2_set_xattr (struct node *np, const char *name, const char *value,
assert_backtrace (!diskfs_readonly);
- goal = sblock->s_first_data_block + np->dn->info.i_block_group *
+ goal = le32toh (sblock->s_first_data_block) + np->dn->info.i_block_group *
EXT2_BLOCKS_PER_GROUP (sblock);
blkno = ext2_new_block (goal, 0, 0, 0);
@@ -713,15 +716,16 @@ ext2_set_xattr (struct node *np, const char *name, const char *value,
memset (block, 0, block_size);
header = EXT2_XATTR_HEADER (block);
- header->h_magic = EXT2_XATTR_BLOCK_MAGIC;
- header->h_blocks = 1;
- header->h_refcount = 1;
+ header->h_magic = htole32 (EXT2_XATTR_BLOCK_MAGIC);
+ header->h_blocks = htole32 (1);
+ header->h_refcount = htole32 (1);
}
else
{
block = disk_cache_block_ref (blkno);
header = EXT2_XATTR_HEADER (block);
- if (header->h_magic != EXT2_XATTR_BLOCK_MAGIC || header->h_blocks != 1)
+ if (header->h_magic != htole32 (EXT2_XATTR_BLOCK_MAGIC)
+ || header->h_blocks != htole32 (1))
{
ext2_warning ("Invalid extended attribute block.");
err = EIO;
@@ -761,7 +765,7 @@ ext2_set_xattr (struct node *np, const char *name, const char *value,
break;
}
- rest -= EXT2_XATTR_ALIGN (entry->e_value_size);
+ rest -= EXT2_XATTR_ALIGN (le32toh (entry->e_value_size));
entry = EXT2_XATTR_ENTRY_NEXT (entry);
}