grub_uint64_t nblocks;
grub_uint32_t extsize;
grub_uint32_t nextents;
- grub_uint8_t unused3[20];
+ grub_uint16_t unused3;
+ grub_uint8_t fork_offset;
+ grub_uint8_t unused4[17];
union
{
char raw[156];
grub_disk_t disk;
int pos;
int bsize;
- int agsize;
+ grub_uint32_t agsize;
struct grub_fshelp_node diropen;
};
#define FILETYPE_INO_DIRECTORY 0040000
#define FILETYPE_INO_SYMLINK 0120000
-#define GRUB_XFS_INO_AGBITS(data) \
- ((data)->sblock.log2_agblk + (data)->sblock.log2_inop)
-#define GRUB_XFS_INO_INOINAG(data, ino) \
- (grub_be_to_cpu64 (ino) & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1))
-#define GRUB_XFS_INO_AG(data,ino) \
- (grub_be_to_cpu64 (ino) >> GRUB_XFS_INO_AGBITS (data))
-
-#define GRUB_XFS_FSB_TO_BLOCK(data, fsb) \
- (((fsb) >> (data)->sblock.log2_agblk) * (data)->agsize \
- + ((fsb) & ((1LL << (data)->sblock.log2_agblk) - 1)))
-
-#define GRUB_XFS_EXTENT_OFFSET(exts,ex) \
- ((grub_be_to_cpu32 (exts[ex][0]) & ~(1 << 31)) << 23 \
- | grub_be_to_cpu32 (exts[ex][1]) >> 9)
-
-#define GRUB_XFS_EXTENT_BLOCK(exts,ex) \
- ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex][1]) \
- & (0x1ff)) << 43 \
- | (grub_uint64_t) grub_be_to_cpu32 (exts[ex][2]) << 11 \
- | grub_be_to_cpu32 (exts[ex][3]) >> 21)
-
-#define GRUB_XFS_EXTENT_SIZE(exts,ex) \
- (grub_be_to_cpu32 (exts[ex][3]) & ((1 << 20) - 1))
-
-#define GRUB_XFS_ROUND_TO_DIRENT(pos) ((((pos) + 8 - 1) / 8) * 8)
-#define GRUB_XFS_NEXT_DIRENT(pos,len) \
- (pos) + GRUB_XFS_ROUND_TO_DIRENT (8 + 1 + len + 2)
+static inline int
+GRUB_XFS_INO_AGBITS(struct grub_xfs_data *data)
+{
+ return ((data)->sblock.log2_agblk + (data)->sblock.log2_inop);
+}
+
+static inline grub_uint64_t
+GRUB_XFS_INO_INOINAG (struct grub_xfs_data *data,
+ grub_uint64_t ino)
+{
+ return (grub_be_to_cpu64 (ino) & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1));
+}
+
+static inline grub_uint64_t
+GRUB_XFS_INO_AG (struct grub_xfs_data *data,
+ grub_uint64_t ino)
+{
+ return (grub_be_to_cpu64 (ino) >> GRUB_XFS_INO_AGBITS (data));
+}
+
+static inline grub_disk_addr_t
+GRUB_XFS_FSB_TO_BLOCK (struct grub_xfs_data *data, grub_disk_addr_t fsb)
+{
+ return ((fsb >> data->sblock.log2_agblk) * data->agsize
+ + (fsb & ((1LL << data->sblock.log2_agblk) - 1)));
+}
+
+static inline grub_uint64_t
+GRUB_XFS_EXTENT_OFFSET (grub_xfs_extent *exts, int ex)
+{
+ return ((grub_be_to_cpu32 (exts[ex][0]) & ~(1 << 31)) << 23
+ | grub_be_to_cpu32 (exts[ex][1]) >> 9);
+}
+
+static inline grub_uint64_t
+GRUB_XFS_EXTENT_BLOCK (grub_xfs_extent *exts, int ex)
+{
+ return ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex][1])
+ & (0x1ff)) << 43
+ | (grub_uint64_t) grub_be_to_cpu32 (exts[ex][2]) << 11
+ | grub_be_to_cpu32 (exts[ex][3]) >> 21);
+}
+
+static inline grub_uint64_t
+GRUB_XFS_EXTENT_SIZE (grub_xfs_extent *exts, int ex)
+{
+ return (grub_be_to_cpu32 (exts[ex][3]) & ((1 << 20) - 1));
+}
+
+static inline int
+GRUB_XFS_ROUND_TO_DIRENT (int pos)
+{
+ return ((((pos) + 8 - 1) / 8) * 8);
+}
+
+static inline int
+GRUB_XFS_NEXT_DIRENT (int pos, int len)
+{
+ return (pos) + GRUB_XFS_ROUND_TO_DIRENT (8 + 1 + len + 2);
+}
+
\f
static inline grub_uint64_t
grub_xfs_inode_block (struct grub_xfs_data *data,
if (node->inode.format == XFS_INODE_FORMAT_BTREE)
{
grub_uint64_t *keys;
+ int recoffset;
- leaf = grub_malloc (node->data->sblock.bsize);
+ leaf = grub_malloc (node->data->bsize);
if (leaf == 0)
return 0;
nrec = grub_be_to_cpu16 (node->inode.data.btree.numrecs);
keys = &node->inode.data.btree.keys[0];
+ if (node->inode.fork_offset)
+ recoffset = (node->inode.fork_offset
+ - ((char *) &node->inode.data.btree.keys - (char *) &node->inode))
+ / (2 * sizeof (grub_uint64_t));
+ else
+ recoffset = ((1 << node->data->sblock.log2_inode)
+ - ((char *) &node->inode.data.btree.keys
+ - (char *) &node->inode))
+ / (2 * sizeof (grub_uint64_t));
do
{
int i;
grub_free (leaf);
return 0;
}
-
if (grub_disk_read (node->data->disk,
- grub_be_to_cpu64 (keys[i - 1 + nrec])
- << (node->data->sblock.log2_bsize
- - GRUB_DISK_SECTOR_BITS),
- 0, node->data->sblock.bsize, leaf))
+ GRUB_XFS_FSB_TO_BLOCK (node->data, grub_be_to_cpu64 (keys[i - 1 + recoffset])) << (node->data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS),
+ 0, node->data->bsize, leaf))
return 0;
if (grub_strncmp ((char *) leaf->magic, "BMAP", 4))
nrec = grub_be_to_cpu16 (leaf->numrecs);
keys = &leaf->keys[0];
- } while (leaf->level);
+ recoffset = ((node->data->bsize - ((char *) &leaf->keys
+ - (char *) leaf))
+ / (2 * sizeof (grub_uint64_t)));
+ }
+ while (leaf->level);
exts = (grub_xfs_extent *) keys;
}
else if (node->inode.format == XFS_INODE_FORMAT_EXT)
grub_xfs_read_file (grub_fshelp_node_t node,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
unsigned offset, unsigned length),
- int pos, grub_size_t len, char *buf)
+ grub_off_t pos, grub_size_t len, char *buf)
{
return grub_fshelp_read_file (node->data->disk, node, read_hook,
pos, len, buf, grub_xfs_read_block,