}
/* calculate the first block number of the group */
-static __inline fsw_u32
+static __inline fsw_u64
fsw_ext4_group_first_block_no(struct ext4_super_block *sb, fsw_u32 group_no)
{
- return group_no * (fsw_u32)EXT4_BLOCKS_PER_GROUP(sb) +
+ return group_no * (fsw_u64)EXT4_BLOCKS_PER_GROUP(sb) +
sb->s_first_data_block;
}
fsw_status_t status;
void *buffer;
fsw_u32 blocksize;
- fsw_u32 groupcnt, groupno, gdesc_per_block, gdesc_bno, gdesc_index, metabg_of_gdesc;
+ fsw_u32 groupcnt, groupno, gdesc_per_block, gdesc_index, metabg_of_gdesc;
+ fsw_u64 gdesc_bno;
struct ext4_group_desc *gdesc;
int i;
struct fsw_string s;
if (vol->sb->s_rev_level == EXT4_DYNAMIC_REV &&
(vol->sb->s_feature_incompat & ~(EXT4_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_RECOVER |
EXT4_FEATURE_INCOMPAT_EXTENTS | EXT4_FEATURE_INCOMPAT_FLEX_BG |
- EXT4_FEATURE_INCOMPAT_META_BG)))
+ EXT4_FEATURE_INCOMPAT_64BIT | EXT4_FEATURE_INCOMPAT_META_BG)))
return FSW_UNSUPPORTED;
-
if (vol->sb->s_rev_level == EXT4_DYNAMIC_REV &&
(vol->sb->s_feature_incompat & EXT4_FEATURE_INCOMPAT_RECOVER))
{
gdesc_per_block = EXT4_DESC_PER_BLOCK(vol->sb);
// Read the group descriptors to get inode table offsets
- status = fsw_alloc(sizeof(fsw_u32) * groupcnt, &vol->inotab_bno);
+ status = fsw_alloc(sizeof(fsw_u64) * groupcnt, &vol->inotab_bno);
if (status)
return status;
// Get group descriptor table and block number of inode table...
gdesc = (struct ext4_group_desc *)((char *)buffer + gdesc_index * vol->sb->s_desc_size);
vol->inotab_bno[groupno] = gdesc->bg_inode_table_lo;
+ if (vol->sb->s_desc_size >= EXT4_MIN_DESC_SIZE_64BIT)
+ vol->inotab_bno[groupno] |= (fsw_u64)gdesc->bg_inode_table_hi << 32;
fsw_block_release(vol, gdesc_bno, buffer);
}
static fsw_status_t fsw_ext4_volume_stat(struct fsw_ext4_volume *vol, struct fsw_volume_stat *sb)
{
- sb->total_bytes = (fsw_u64)vol->sb->s_blocks_count_lo * vol->g.log_blocksize;
- sb->free_bytes = (fsw_u64)vol->sb->s_free_blocks_count_lo * vol->g.log_blocksize;
+ fsw_u64 count;
+
+ count = vol->sb->s_blocks_count_lo;
+ if (vol->sb->s_desc_size >= EXT4_MIN_DESC_SIZE_64BIT)
+ count |= (fsw_u64)vol->sb->s_blocks_count_hi << 32;
+ sb->total_bytes = count * vol->g.log_blocksize;
+
+ count = vol->sb->s_free_blocks_count_lo;
+ if (vol->sb->s_desc_size >= EXT4_MIN_DESC_SIZE_64BIT)
+ count |= (fsw_u64)vol->sb->s_free_blocks_count_hi << 32;
+ sb->free_bytes = count * vol->g.log_blocksize;
+
return FSW_SUCCESS;
}
static fsw_status_t fsw_ext4_dnode_fill(struct fsw_ext4_volume *vol, struct fsw_ext4_dnode *dno)
{
fsw_status_t status;
- fsw_u32 groupno, ino_in_group, ino_bno, ino_index;
+ fsw_u32 groupno, ino_in_group, ino_index;
+ fsw_u64 ino_bno;
fsw_u8 *buffer;
if (dno->raw)
struct fsw_dnode_stat *sb)
{
sb->used_bytes = dno->raw->i_blocks_lo * EXT4_BLOCK_SIZE(vol->sb); // very, very strange...
- sb->store_time_posix(sb, FSW_DNODE_STAT_CTIME, dno->raw->i_ctime);
- sb->store_time_posix(sb, FSW_DNODE_STAT_ATIME, dno->raw->i_atime);
- sb->store_time_posix(sb, FSW_DNODE_STAT_MTIME, dno->raw->i_mtime);
- sb->store_attr_posix(sb, dno->raw->i_mode);
+ fsw_store_time_posix(sb, FSW_DNODE_STAT_CTIME, dno->raw->i_ctime);
+ fsw_store_time_posix(sb, FSW_DNODE_STAT_ATIME, dno->raw->i_atime);
+ fsw_store_time_posix(sb, FSW_DNODE_STAT_MTIME, dno->raw->i_mtime);
+ fsw_store_attr_posix(sb, dno->raw->i_mode);
return FSW_SUCCESS;
}
struct fsw_extent *extent)
{
fsw_status_t status;
- fsw_u32 bno, release_bno, buf_offset, file_bcnt;
+ fsw_u32 bno, buf_offset;
int ext_cnt;
void *buffer;
// Is the requested block in this extent?
if(bno >= ext4_extent->ee_block && bno < ext4_extent->ee_block + ext4_extent->ee_len)
{
- extent->phys_start = ext4_extent->ee_start_lo + (bno - ext4_extent->ee_block);
+ extent->phys_start = ((fsw_u64)ext4_extent->ee_start_hi << 32) | ext4_extent->ee_start_lo;
+ extent->phys_start += (bno - ext4_extent->ee_block);
extent->log_count = ext4_extent->ee_len - (bno - ext4_extent->ee_block);
return FSW_SUCCESS;
}
if(bno >= ext4_extent_idx->ei_block)
{
// Follow extent tree...
- status = fsw_block_get(vol, ext4_extent_idx->ei_leaf_lo, 1, (void **)&buffer);
+ fsw_u64 phys_bno = ((fsw_u64)ext4_extent_idx->ei_leaf_hi << 32) | ext4_extent_idx->ei_leaf_lo;
+ status = fsw_block_get(vol, phys_bno, 1, (void **)&buffer);
if (status)
return status;
buf_offset = 0;