+2009-07-31 Bean <bean123ch@gmail.com>
+
+ * fs/xfs.c (grub_xfs_sblock): Change unused5 field to log2_sect and
+ log2_inode.
+ (grub_fshelp_node): Move inode field to the end.
+ (grub_xfs_data): Remove inode field.
+ (grub_xfs_inode_block): Calculate inode size using sblock.
+ (grub_xfs_inode_offset): Likewise.
+ (grub_xfs_read_inode): Calculate inode size using sblock.
+ (grub_xfs_read_block): Replace XFS_INODE_EXTENTS with nrec.
+ (grub_xfs_iterate_dir): Calculate inode size using sblock.
+ (grub_xfs_mount): Use grub_zalloc instead of grub_malloc. Realloc data
+ to match inode size.
+ (grub_xfs_dir): goto mount_fail when mount fails, as data->diropen is
+ not accessible when data is null.
+ (grub_xfs_open): Likewise.
+
2009-07-31 Bean <bean123ch@gmail.com>
* disk/lvm.c (grub_lvm_scan_device): Ignore extra copy of metadata.
grub_uint8_t unused4[20];
grub_uint8_t label[12];
grub_uint8_t log2_bsize;
- grub_uint8_t unused5[2];
+ grub_uint8_t log2_sect;
+ grub_uint8_t log2_inode;
grub_uint8_t log2_inop;
grub_uint8_t log2_agblk;
grub_uint8_t unused6[67];
struct grub_fshelp_node
{
struct grub_xfs_data *data;
- struct grub_xfs_inode inode;
grub_uint64_t ino;
int inode_read;
+ struct grub_xfs_inode inode;
};
struct grub_xfs_data
{
struct grub_xfs_sblock sblock;
- struct grub_xfs_inode *inode;
grub_disk_t disk;
int pos;
int bsize;
int agsize;
struct grub_fshelp_node diropen;
-
};
static grub_dl_t my_mod;
long long ag = GRUB_XFS_INO_AG (data, ino);
long long block;
- block = (inoinag >> 4) + ag * data->agsize;
+ block = (inoinag >> data->sblock.log2_inop) + ag * data->agsize;
block <<= (data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS);
return block;
}
grub_uint64_t ino)
{
int inoag = GRUB_XFS_INO_INOINAG (data, ino);
- return (inoag & ((1 << 4) - 1)) << 8;
+ return ((inoag & ((1 << data->sblock.log2_inop) - 1)) <<
+ data->sblock.log2_inode);
}
/* Read the inode. */
if (grub_disk_read (data->disk, block, offset,
- sizeof (struct grub_xfs_inode), inode))
+ 1 << data->sblock.log2_inode, inode))
return grub_errno;
if (grub_strncmp ((char *) inode->magic, "IN", 2))
}
if (grub_disk_read (node->data->disk,
- grub_be_to_cpu64 (keys[i - 1 + XFS_INODE_EXTENTS])
+ grub_be_to_cpu64 (keys[i - 1 + nrec])
<< (node->data->sblock.log2_bsize
- GRUB_DISK_SECTOR_BITS),
0, node->data->sblock.bsize, leaf))
{
struct grub_fshelp_node *fdiro;
- fdiro = grub_malloc (sizeof (struct grub_fshelp_node));
+ fdiro = grub_malloc (sizeof (struct grub_fshelp_node)
+ - sizeof (struct grub_xfs_inode)
+ + (1 << diro->data->sblock.log2_inode));
if (!fdiro)
return 0;
{
struct grub_xfs_data *data = 0;
- data = grub_malloc (sizeof (struct grub_xfs_data));
+ data = grub_zalloc (sizeof (struct grub_xfs_data));
if (!data)
return 0;
goto fail;
}
+ data = grub_realloc (data,
+ sizeof (struct grub_xfs_data)
+ - sizeof (struct grub_xfs_inode)
+ + (1 << data->sblock.log2_inode));
+
+ if (! data)
+ goto fail;
+
data->diropen.data = data;
data->diropen.ino = data->sblock.rootino;
data->diropen.inode_read = 1;
data->agsize = grub_be_to_cpu32 (data->sblock.agsize);
data->disk = disk;
- data->inode = &data->diropen.inode;
data->pos = 0;
- grub_xfs_read_inode (data, data->diropen.ino, data->inode);
+ grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode);
return data;
fail:
data = grub_xfs_mount (device->disk);
if (!data)
- goto fail;
+ goto mount_fail;
grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_xfs_iterate_dir,
grub_xfs_read_symlink, GRUB_FSHELP_DIR);
grub_free (fdiro);
grub_free (data);
+ mount_fail:
+
grub_dl_unref (my_mod);
return grub_errno;
-
- return 0;
}
data = grub_xfs_mount (file->device->disk);
if (!data)
- goto fail;
+ goto mount_fail;
grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_xfs_iterate_dir,
grub_xfs_read_symlink, GRUB_FSHELP_REG);
goto fail;
}
- grub_memcpy (data->inode,
- &fdiro->inode,
- sizeof (struct grub_xfs_inode));
- grub_free (fdiro);
+ if (fdiro != &data->diropen)
+ grub_memcpy (&data->diropen, fdiro,
+ sizeof (struct grub_fshelp_node)
+ - sizeof (struct grub_xfs_inode)
+ + (1 << data->sblock.log2_inode));
- file->size = grub_be_to_cpu64 (data->inode->size);
+ file->size = grub_be_to_cpu64 (data->diropen.inode.size);
file->data = data;
file->offset = 0;
grub_free (fdiro);
grub_free (data);
+ mount_fail:
grub_dl_unref (my_mod);
return grub_errno;