2008-02-02 Bean <bean123ch@gmail.com>
* fs/ufs.c (INODE_BLKSZ): Fix incorrect value. (grub_ufs_get_file_block): Fix indirect block calculation problem. * fs/xfs.c (grub_xfs_sblock): New member log2_dirblk. (grub_xfs_btree_node): New structure. (grub_xfs_btree_root): New structure. (grub_xfs_inode): New members nblocks, extsize, nextents and btree. (GRUB_XFS_EXTENT_OFFSET): Use exts instead of inode->data.extents. (GRUB_XFS_EXTENT_BLOCK): Likewise. (GRUB_XFS_EXTENT_SIZE): Likewise. (grub_xfs_read_block): Support btree format type. (grub_xfs_iterate_dir): Use NESTED_FUNC_ATTR in call_hook. Use directory block as basic unit. * fs/fshelp.c (grub_fshelp_read_file): Bug fix for sparse block. * aclocal.m4 (grub_i386_CHECK_REGPARM_BUG): Define NESTED_FUNC_ATTR as __attribute__ ((__regparm__ (1))).
This commit is contained in:
parent
f95562bf52
commit
c004e1b477
6 changed files with 160 additions and 49 deletions
22
fs/ufs.c
22
fs/ufs.c
|
@ -52,7 +52,7 @@
|
|||
grub_le_to_cpu##bits2 (data->inode2.field))
|
||||
#define INODE_SIZE(data) INODE_ENDIAN (data,size,32,64)
|
||||
#define INODE_MODE(data) INODE_ENDIAN (data,mode,16,16)
|
||||
#define INODE_BLKSZ(data) (data->ufs_type == UFS1 ? 32 : 64)
|
||||
#define INODE_BLKSZ(data) (data->ufs_type == UFS1 ? 4 : 8)
|
||||
#define INODE_DIRBLOCKS(data,blk) INODE_ENDIAN \
|
||||
(data,blocks.dir_blocks[blk],32,64)
|
||||
#define INODE_INDIRBLOCKS(data,blk) INODE_ENDIAN \
|
||||
|
@ -205,35 +205,41 @@ grub_ufs_get_file_block (struct grub_ufs_data *data, unsigned int blk)
|
|||
{
|
||||
struct grub_ufs_sblock *sblock = &data->sblock;
|
||||
unsigned int indirsz;
|
||||
int log2_blksz;
|
||||
|
||||
/* Direct. */
|
||||
if (blk < GRUB_UFS_DIRBLKS)
|
||||
return INODE_DIRBLOCKS (data, blk);
|
||||
|
||||
log2_blksz = grub_le_to_cpu32 (data->sblock.log2_blksz);
|
||||
|
||||
blk -= GRUB_UFS_DIRBLKS;
|
||||
|
||||
indirsz = UFS_BLKSZ (sblock) / INODE_BLKSZ (data);
|
||||
/* Single indirect block. */
|
||||
if (blk < indirsz)
|
||||
{
|
||||
grub_uint32_t indir[UFS_BLKSZ (sblock)];
|
||||
grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 0),
|
||||
grub_uint32_t indir[UFS_BLKSZ (sblock) >> 2];
|
||||
grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 0) << log2_blksz,
|
||||
0, sizeof (indir), (char *) indir);
|
||||
return indir[blk];
|
||||
return (data->ufs_type == UFS1) ? indir[blk] : indir[blk << 1];
|
||||
}
|
||||
blk -= indirsz;
|
||||
|
||||
/* Double indirect block. */
|
||||
if (blk < UFS_BLKSZ (sblock) / indirsz)
|
||||
{
|
||||
grub_uint32_t indir[UFS_BLKSZ (sblock)];
|
||||
grub_uint32_t indir[UFS_BLKSZ (sblock) >> 2];
|
||||
|
||||
grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 1),
|
||||
grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 1) << log2_blksz,
|
||||
0, sizeof (indir), (char *) indir);
|
||||
grub_disk_read (data->disk, indir[blk / indirsz],
|
||||
grub_disk_read (data->disk,
|
||||
(data->ufs_type == UFS1) ?
|
||||
indir[blk / indirsz] : indir [(blk / indirsz) << 1],
|
||||
0, sizeof (indir), (char *) indir);
|
||||
|
||||
return indir[blk % indirsz];
|
||||
return (data->ufs_type == UFS1) ?
|
||||
indir[blk % indirsz] : indir[(blk % indirsz) << 1];
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue