2009-04-10 Vladimir Serbinenko <phcoder@gmail.com>
UFS improvements * fs/ufs.c (INODE_NBLOCKS): new definition (struct grub_ufs_dirent): added fields for non-BSD dirents (grub_ufs_get_file_block): fixed double indirect handling (grub_ufs_lookup_symlink): use more robust way to determine whether symlink is inline (grub_ufs_find_file): support for non-BSD dirents (grub_ufs_dir): support for non-BSD dirents
This commit is contained in:
parent
e7e6862a4c
commit
6df8cc7614
2 changed files with 42 additions and 13 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2009-04-10 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
UFS improvements
|
||||||
|
|
||||||
|
* fs/ufs.c (INODE_NBLOCKS): new definition
|
||||||
|
(struct grub_ufs_dirent): added fields for non-BSD dirents
|
||||||
|
(grub_ufs_get_file_block): fixed double indirect handling
|
||||||
|
(grub_ufs_lookup_symlink): use more robust way to determine whether
|
||||||
|
symlink is inline
|
||||||
|
(grub_ufs_find_file): support for non-BSD dirents
|
||||||
|
(grub_ufs_dir): support for non-BSD dirents
|
||||||
|
|
||||||
2009-04-10 Bean <bean123ch@gnail.com>
|
2009-04-10 Bean <bean123ch@gnail.com>
|
||||||
|
|
||||||
* include/grub/efi/api.h (grub_efi_configuration_table): Add packed
|
* include/grub/efi/api.h (grub_efi_configuration_table): Add packed
|
||||||
|
|
43
fs/ufs.c
43
fs/ufs.c
|
@ -54,6 +54,8 @@
|
||||||
grub_le_to_cpu##bits1 (data->inode.field) : \
|
grub_le_to_cpu##bits1 (data->inode.field) : \
|
||||||
grub_le_to_cpu##bits2 (data->inode2.field))
|
grub_le_to_cpu##bits2 (data->inode2.field))
|
||||||
#define INODE_SIZE(data) INODE_ENDIAN (data,size,32,64)
|
#define INODE_SIZE(data) INODE_ENDIAN (data,size,32,64)
|
||||||
|
#define INODE_NBLOCKS(data) INODE_ENDIAN (data,nblocks,32,64)
|
||||||
|
|
||||||
#define INODE_MODE(data) INODE_ENDIAN (data,mode,16,16)
|
#define INODE_MODE(data) INODE_ENDIAN (data,mode,16,16)
|
||||||
#define INODE_BLKSZ(data) (data->ufs_type == UFS1 ? 4 : 8)
|
#define INODE_BLKSZ(data) (data->ufs_type == UFS1 ? 4 : 8)
|
||||||
#define INODE_DIRBLOCKS(data,blk) INODE_ENDIAN \
|
#define INODE_DIRBLOCKS(data,blk) INODE_ENDIAN \
|
||||||
|
@ -174,8 +176,15 @@ struct grub_ufs_dirent
|
||||||
{
|
{
|
||||||
grub_uint32_t ino;
|
grub_uint32_t ino;
|
||||||
grub_uint16_t direntlen;
|
grub_uint16_t direntlen;
|
||||||
grub_uint8_t filetype;
|
union
|
||||||
grub_uint8_t namelen;
|
{
|
||||||
|
grub_uint16_t namelen;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
grub_uint8_t filetype_bsd;
|
||||||
|
grub_uint8_t namelen_bsd;
|
||||||
|
};
|
||||||
|
};
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
/* Information about a "mounted" ufs filesystem. */
|
/* Information about a "mounted" ufs filesystem. */
|
||||||
|
@ -234,15 +243,16 @@ grub_ufs_get_file_block (struct grub_ufs_data *data, unsigned int blk)
|
||||||
blk -= indirsz;
|
blk -= indirsz;
|
||||||
|
|
||||||
/* Double indirect block. */
|
/* Double indirect block. */
|
||||||
if (blk < UFS_BLKSZ (sblock) / indirsz)
|
if (blk < indirsz * indirsz)
|
||||||
{
|
{
|
||||||
grub_uint32_t indir[UFS_BLKSZ (sblock) >> 2];
|
grub_uint32_t indir[UFS_BLKSZ (sblock) >> 2];
|
||||||
|
|
||||||
grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 1) << log2_blksz,
|
grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 1) << log2_blksz,
|
||||||
0, sizeof (indir), (char *) indir);
|
0, sizeof (indir), (char *) indir);
|
||||||
grub_disk_read (data->disk,
|
grub_disk_read (data->disk,
|
||||||
(data->ufs_type == UFS1) ?
|
((data->ufs_type == UFS1) ?
|
||||||
indir[blk / indirsz] : indir [(blk / indirsz) << 1],
|
indir[blk / indirsz] : indir [(blk / indirsz) << 1])
|
||||||
|
<< log2_blksz,
|
||||||
0, sizeof (indir), (char *) indir);
|
0, sizeof (indir), (char *) indir);
|
||||||
|
|
||||||
return (data->ufs_type == UFS1) ?
|
return (data->ufs_type == UFS1) ?
|
||||||
|
@ -387,8 +397,7 @@ grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino)
|
||||||
if (++data->linknest > GRUB_UFS_MAX_SYMLNK_CNT)
|
if (++data->linknest > GRUB_UFS_MAX_SYMLNK_CNT)
|
||||||
return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
|
return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
|
||||||
|
|
||||||
if (INODE_SIZE (data) < (GRUB_UFS_DIRBLKS + GRUB_UFS_INDIRBLKS
|
if (INODE_NBLOCKS (data) == 0)
|
||||||
* INODE_BLKSZ (data)))
|
|
||||||
grub_strcpy (symlink, (char *) INODE (data, symlink));
|
grub_strcpy (symlink, (char *) INODE (data, symlink));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -447,6 +456,7 @@ grub_ufs_find_file (struct grub_ufs_data *data, const char *path)
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
struct grub_ufs_dirent dirent;
|
struct grub_ufs_dirent dirent;
|
||||||
|
int namelen;
|
||||||
|
|
||||||
if (grub_strlen (name) == 0)
|
if (grub_strlen (name) == 0)
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
@ -455,14 +465,17 @@ grub_ufs_find_file (struct grub_ufs_data *data, const char *path)
|
||||||
(char *) &dirent) < 0)
|
(char *) &dirent) < 0)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
|
namelen = (data->ufs_type == UFS2)
|
||||||
|
? dirent.namelen_bsd : grub_le_to_cpu16 (dirent.namelen);
|
||||||
|
|
||||||
{
|
{
|
||||||
char filename[dirent.namelen + 1];
|
char filename[namelen + 1];
|
||||||
|
|
||||||
if (grub_ufs_read_file (data, 0, pos + sizeof (dirent),
|
if (grub_ufs_read_file (data, 0, pos + sizeof (dirent),
|
||||||
dirent.namelen, filename) < 0)
|
namelen, filename) < 0)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
filename[dirent.namelen] = '\0';
|
filename[namelen] = '\0';
|
||||||
|
|
||||||
if (!grub_strcmp (name, filename))
|
if (!grub_strcmp (name, filename))
|
||||||
{
|
{
|
||||||
|
@ -595,21 +608,25 @@ grub_ufs_dir (grub_device_t device, const char *path,
|
||||||
while (pos < INODE_SIZE (data))
|
while (pos < INODE_SIZE (data))
|
||||||
{
|
{
|
||||||
struct grub_ufs_dirent dirent;
|
struct grub_ufs_dirent dirent;
|
||||||
|
int namelen;
|
||||||
|
|
||||||
if (grub_ufs_read_file (data, 0, pos, sizeof (dirent),
|
if (grub_ufs_read_file (data, 0, pos, sizeof (dirent),
|
||||||
(char *) &dirent) < 0)
|
(char *) &dirent) < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
namelen = (data->ufs_type == UFS2)
|
||||||
|
? dirent.namelen_bsd : grub_le_to_cpu16 (dirent.namelen);
|
||||||
|
|
||||||
{
|
{
|
||||||
char filename[dirent.namelen + 1];
|
char filename[namelen + 1];
|
||||||
struct grub_dirhook_info info;
|
struct grub_dirhook_info info;
|
||||||
grub_memset (&info, 0, sizeof (info));
|
grub_memset (&info, 0, sizeof (info));
|
||||||
|
|
||||||
if (grub_ufs_read_file (data, 0, pos + sizeof (dirent),
|
if (grub_ufs_read_file (data, 0, pos + sizeof (dirent),
|
||||||
dirent.namelen, filename) < 0)
|
namelen, filename) < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
filename[dirent.namelen] = '\0';
|
filename[namelen] = '\0';
|
||||||
if (data->ufs_type == UFS1)
|
if (data->ufs_type == UFS1)
|
||||||
{
|
{
|
||||||
struct grub_ufs_inode inode;
|
struct grub_ufs_inode inode;
|
||||||
|
|
Loading…
Reference in a new issue