* grub-core/fs/bfs.c: Remove variable length arrays. Reduces afs.mod and

bfs.mod size by 556 resp 740 bytes (288 resp 334 compressed).
	* include/grub/types.h (grub_unaligned_uint64_t): New type.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2013-10-20 13:11:40 +02:00
parent e89c2d48a9
commit d28e1163c3
3 changed files with 240 additions and 244 deletions

View file

@ -1,3 +1,9 @@
2013-10-20 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/fs/bfs.c: Remove variable length arrays. Reduces afs.mod and
bfs.mod size by 556 resp 740 bytes (288 resp 334 compressed).
* include/grub/types.h (grub_unaligned_uint64_t): New type.
2013-10-19 Vladimir Serbinenko <phcoder@gmail.com>
Lift 255x255 erminal sie restriction to 65535x65535. Also change from

View file

@ -170,7 +170,7 @@ struct grub_bfs_btree_node
struct grub_bfs_data
{
struct grub_bfs_superblock sb;
struct grub_bfs_inode ino[0];
struct grub_bfs_inode ino;
};
/* Context for grub_bfs_dir. */
@ -419,6 +419,63 @@ read_bfs_file (grub_disk_t disk,
}
}
static grub_err_t
read_b_node (grub_disk_t disk,
const struct grub_bfs_superblock *sb,
const struct grub_bfs_inode *ino,
grub_uint64_t node_off,
struct grub_bfs_btree_node **node,
char **key_data, grub_uint16_t **keylen_idx,
grub_unaligned_uint64_t **key_values)
{
void *ret;
struct grub_bfs_btree_node node_head;
grub_size_t total_size;
grub_err_t err;
*node = NULL;
*key_data = NULL;
*keylen_idx = NULL;
*key_values = NULL;
err = read_bfs_file (disk, sb, ino, node_off, &node_head, sizeof (node_head),
0, 0);
if (err)
return err;
total_size = ALIGN_UP (sizeof (node_head) +
grub_bfs_to_cpu_treehead
(node_head.total_key_len),
BTREE_ALIGN) +
grub_bfs_to_cpu_treehead (node_head.count_keys) *
sizeof (grub_uint16_t)
+ grub_bfs_to_cpu_treehead (node_head.count_keys) *
sizeof (grub_uint64_t);
ret = grub_malloc (total_size);
if (!ret)
return grub_errno;
err = read_bfs_file (disk, sb, ino, node_off, ret, total_size, 0, 0);
if (err)
{
grub_free (ret);
return err;
}
*node = ret;
*key_data = (char *) ret + sizeof (node_head);
*keylen_idx = (grub_uint16_t *) ret
+ ALIGN_UP (sizeof (node_head) +
grub_bfs_to_cpu_treehead (node_head.total_key_len),
BTREE_ALIGN) / 2;
*key_values = (grub_unaligned_uint64_t *)
(*keylen_idx +
grub_bfs_to_cpu_treehead (node_head.count_keys));
return GRUB_ERR_NONE;
}
static int
iterate_in_b_tree (grub_disk_t disk,
const struct grub_bfs_superblock *sb,
@ -462,70 +519,52 @@ iterate_in_b_tree (grub_disk_t disk,
while (1)
{
struct grub_bfs_btree_node node;
err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node),
0, 0);
struct grub_bfs_btree_node *node;
char *key_data;
grub_uint16_t *keylen_idx;
grub_unaligned_uint64_t *key_values;
unsigned i;
grub_uint16_t start = 0, end = 0;
err = read_b_node (disk, sb, ino,
node_off,
&node,
&key_data,
&keylen_idx,
&key_values);
if (err)
return 0;
{
char key_data[grub_bfs_to_cpu_treehead (node.total_key_len) + 1];
grub_uint16_t keylen_idx[grub_bfs_to_cpu_treehead (node.count_keys)];
grub_uint64_t key_values[grub_bfs_to_cpu_treehead (node.count_keys)];
unsigned i;
grub_uint16_t start = 0, end = 0;
err =
read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data,
grub_bfs_to_cpu_treehead (node.total_key_len), 0, 0);
if (err)
return 0;
key_data[grub_bfs_to_cpu_treehead (node.total_key_len)] = 0;
err = read_bfs_file (disk, sb, ino, node_off
+ ALIGN_UP (sizeof (node) +
grub_bfs_to_cpu_treehead
(node.total_key_len), BTREE_ALIGN),
keylen_idx,
grub_bfs_to_cpu_treehead (node.count_keys) *
sizeof (grub_uint16_t), 0, 0);
if (err)
return 0;
err = read_bfs_file (disk, sb, ino, node_off
+ ALIGN_UP (sizeof (node) +
grub_bfs_to_cpu_treehead
(node.total_key_len),
BTREE_ALIGN) +
grub_bfs_to_cpu_treehead (node.count_keys) *
sizeof (grub_uint16_t), key_values,
grub_bfs_to_cpu_treehead (node.count_keys) *
sizeof (grub_uint64_t), 0, 0);
if (err)
return 0;
for (i = 0; i < grub_bfs_to_cpu_treehead (node.count_keys); i++)
{
char c;
start = end;
end = grub_bfs_to_cpu16 (keylen_idx[i]);
if (grub_bfs_to_cpu_treehead (node.total_key_len) <= end)
end = grub_bfs_to_cpu_treehead (node.total_key_len);
c = key_data[end];
key_data[end] = 0;
if (hook (key_data + start, grub_bfs_to_cpu64 (key_values[i]),
ctx))
for (i = 0; i < grub_bfs_to_cpu_treehead (node->count_keys); i++)
{
char c;
start = end;
end = grub_bfs_to_cpu16 (keylen_idx[i]);
if (grub_bfs_to_cpu_treehead (node->total_key_len) <= end)
end = grub_bfs_to_cpu_treehead (node->total_key_len);
c = key_data[end];
key_data[end] = 0;
if (hook (key_data + start, grub_bfs_to_cpu64 (key_values[i].val),
ctx))
{
grub_free (node);
return 1;
}
key_data[end] = c;
}
node_off = grub_bfs_to_cpu64 (node.right);
node_off = grub_bfs_to_cpu64 (node->right);
grub_free (node);
if (node_off == POINTER_INVALID)
return 0;
}
}
}
static int
bfs_strcmp (const char *a, const char *b, grub_size_t alen)
bfs_strcmp (const char *a, const char *b, grub_size_t alen, grub_size_t blen)
{
while (*b && alen)
char ac, bc;
while (blen && alen)
{
if (*a != *b)
break;
@ -533,18 +572,16 @@ bfs_strcmp (const char *a, const char *b, grub_size_t alen)
a++;
b++;
alen--;
blen--;
}
ac = alen ? *a : 0;
bc = blen ? *b : 0;
#ifdef MODE_AFS
if (!alen)
return - (int) (grub_int8_t) *b;
return (int) (grub_int8_t) *a - (int) (grub_int8_t) *b;
return (int) (grub_int8_t) ac - (int) (grub_int8_t) bc;
#else
if (!alen)
return - (int) (grub_uint8_t) *b;
return (int) (grub_uint8_t) *a - (int) (grub_uint8_t) *b;
return (int) (grub_uint8_t) ac - (int) (grub_uint8_t) bc;
#endif
}
@ -552,6 +589,7 @@ static grub_err_t
find_in_b_tree (grub_disk_t disk,
const struct grub_bfs_superblock *sb,
const struct grub_bfs_inode *ino, const char *name,
grub_size_t name_len,
grub_uint64_t * res)
{
struct grub_bfs_btree_header head;
@ -567,131 +605,113 @@ find_in_b_tree (grub_disk_t disk,
level = grub_bfs_to_cpu32 (head.level) - 1;
while (1)
{
struct grub_bfs_btree_node node;
err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node),
0, 0);
struct grub_bfs_btree_node *node;
char *key_data;
grub_uint16_t *keylen_idx;
grub_unaligned_uint64_t *key_values;
int lg, j;
unsigned i;
err = read_b_node (disk, sb, ino, node_off, &node, &key_data, &keylen_idx, &key_values);
if (err)
return err;
if (node.count_keys == 0)
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"),
name);
{
char key_data[grub_bfs_to_cpu_treehead (node.total_key_len) + 1];
grub_uint16_t keylen_idx[grub_bfs_to_cpu_treehead (node.count_keys)];
grub_uint64_t key_values[grub_bfs_to_cpu_treehead (node.count_keys)];
unsigned i;
err =
read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data,
grub_bfs_to_cpu_treehead (node.total_key_len), 0, 0);
if (err)
return err;
key_data[grub_bfs_to_cpu_treehead (node.total_key_len)] = 0;
err = read_bfs_file (disk, sb, ino, node_off
+
ALIGN_UP (sizeof (node) +
grub_bfs_to_cpu_treehead (node.
total_key_len),
BTREE_ALIGN), keylen_idx,
grub_bfs_to_cpu_treehead (node.count_keys) *
sizeof (grub_uint16_t), 0, 0);
if (err)
return err;
err = read_bfs_file (disk, sb, ino, node_off
+ ALIGN_UP (sizeof (node) +
grub_bfs_to_cpu_treehead
(node.total_key_len),
BTREE_ALIGN) +
grub_bfs_to_cpu_treehead (node.count_keys) *
sizeof (grub_uint16_t), key_values,
grub_bfs_to_cpu_treehead (node.count_keys) *
sizeof (grub_uint64_t), 0, 0);
if (err)
return err;
int lg, j;
if (node->count_keys == 0)
{
grub_free (node);
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"),
name);
}
for (lg = 0; grub_bfs_to_cpu_treehead (node.count_keys) >> lg; lg++);
for (lg = 0; grub_bfs_to_cpu_treehead (node->count_keys) >> lg; lg++);
i = 0;
i = 0;
for (j = lg - 1; j >= 0; j--)
{
int cmp;
grub_uint16_t start = 0, end = 0;
if ((i | (1 << j)) >= grub_bfs_to_cpu_treehead (node.count_keys))
continue;
start = grub_bfs_to_cpu16 (keylen_idx[(i | (1 << j)) - 1]);
end = grub_bfs_to_cpu16 (keylen_idx[(i | (1 << j))]);
if (grub_bfs_to_cpu_treehead (node.total_key_len) <= end)
end = grub_bfs_to_cpu_treehead (node.total_key_len);
cmp = bfs_strcmp (key_data + start, name, end - start);
if (cmp == 0 && level == 0)
{
*res = grub_bfs_to_cpu64 (key_values[i | (1 << j)]);
return GRUB_ERR_NONE;
}
for (j = lg - 1; j >= 0; j--)
{
int cmp;
grub_uint16_t start = 0, end = 0;
if ((i | (1 << j)) >= grub_bfs_to_cpu_treehead (node->count_keys))
continue;
start = grub_bfs_to_cpu16 (keylen_idx[(i | (1 << j)) - 1]);
end = grub_bfs_to_cpu16 (keylen_idx[(i | (1 << j))]);
if (grub_bfs_to_cpu_treehead (node->total_key_len) <= end)
end = grub_bfs_to_cpu_treehead (node->total_key_len);
cmp = bfs_strcmp (key_data + start, name, end - start, name_len);
if (cmp == 0 && level == 0)
{
*res = grub_bfs_to_cpu64 (key_values[i | (1 << j)].val);
grub_free (node);
return GRUB_ERR_NONE;
}
#ifdef MODE_AFS
if (cmp <= 0)
if (cmp <= 0)
#else
if (cmp < 0)
if (cmp < 0)
#endif
i |= (1 << j);
}
if (i == 0)
{
grub_uint16_t end = 0;
int cmp;
end = grub_bfs_to_cpu16 (keylen_idx[0]);
if (grub_bfs_to_cpu_treehead (node.total_key_len) <= end)
end = grub_bfs_to_cpu_treehead (node.total_key_len);
cmp = bfs_strcmp (key_data, name, end);
if (cmp == 0 && level == 0)
{
*res = grub_bfs_to_cpu64 (key_values[0]);
return GRUB_ERR_NONE;
}
i |= (1 << j);
}
if (i == 0)
{
grub_uint16_t end = 0;
int cmp;
end = grub_bfs_to_cpu16 (keylen_idx[0]);
if (grub_bfs_to_cpu_treehead (node->total_key_len) <= end)
end = grub_bfs_to_cpu_treehead (node->total_key_len);
cmp = bfs_strcmp (key_data, name, end, name_len);
if (cmp == 0 && level == 0)
{
*res = grub_bfs_to_cpu64 (key_values[0].val);
grub_free (node);
return GRUB_ERR_NONE;
}
#ifdef MODE_AFS
if (cmp > 0 && level != 0)
if (cmp > 0 && level != 0)
#else
if (cmp >= 0 && level != 0)
#endif
{
node_off = grub_bfs_to_cpu64 (key_values[0]);
node_off = grub_bfs_to_cpu64 (key_values[0].val);
level--;
grub_free (node);
continue;
}
else if (level != 0
&& grub_bfs_to_cpu_treehead (node.count_keys) >= 2)
&& grub_bfs_to_cpu_treehead (node->count_keys) >= 2)
{
node_off = grub_bfs_to_cpu64 (key_values[1]);
node_off = grub_bfs_to_cpu64 (key_values[1].val);
level--;
grub_free (node);
continue;
}
}
else if (level != 0
&& i + 1 < grub_bfs_to_cpu_treehead (node.count_keys))
&& i + 1 < grub_bfs_to_cpu_treehead (node->count_keys))
{
node_off = grub_bfs_to_cpu64 (key_values[i + 1]);
node_off = grub_bfs_to_cpu64 (key_values[i + 1].val);
level--;
grub_free (node);
continue;
}
if (node.overflow != POINTER_INVALID)
if (node->overflow != POINTER_INVALID)
{
node_off = grub_bfs_to_cpu64 (node.overflow);
node_off = grub_bfs_to_cpu64 (node->overflow);
/* This level-- isn't specified but is needed. */
level--;
grub_free (node);
continue;
}
grub_free (node);
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"),
name);
}
}
}
static grub_err_t
hop_level (grub_disk_t disk,
const struct grub_bfs_superblock *sb,
struct grub_bfs_inode *ino, const char *name)
struct grub_bfs_inode *ino, const char *name,
const char *name_end)
{
grub_err_t err;
grub_uint64_t res = 0;
@ -699,38 +719,35 @@ hop_level (grub_disk_t disk,
if (((grub_bfs_to_cpu32 (ino->mode) & ATTR_TYPE) != ATTR_DIR))
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
err = find_in_b_tree (disk, sb, ino, name, &res);
err = find_in_b_tree (disk, sb, ino, name, name_end - name, &res);
if (err)
return err;
return grub_disk_read (disk, res
<< (grub_bfs_to_cpu32 (sb->log2_bsize)
- GRUB_DISK_SECTOR_BITS), 0,
grub_bfs_to_cpu32 (sb->bsize), (char *) ino);
sizeof (*ino), (char *) ino);
}
static grub_err_t
find_file (const char *path, grub_disk_t disk,
const struct grub_bfs_superblock *sb, struct grub_bfs_inode *ino)
{
char *ptr, *ptr2;
const char *ptr, *next = path;
char *alloc = NULL;
char *wptr;
grub_err_t err;
union
{
struct grub_bfs_inode ino;
grub_uint8_t raw[grub_bfs_to_cpu32 (sb->bsize)];
} old_ino;
struct grub_bfs_inode old_ino;
unsigned symlinks_max = 32;
err = read_extent (disk, sb, &sb->root_dir, 0, 0, ino,
grub_bfs_to_cpu32 (sb->bsize));
sizeof (*ino));
if (err)
return err;
ptr = (char *) path;
while (1)
{
ptr = next;
while (*ptr == '/')
ptr++;
if (*ptr == 0)
@ -738,17 +755,9 @@ find_file (const char *path, grub_disk_t disk,
grub_free (alloc);
return GRUB_ERR_NONE;
}
ptr2 = grub_strchr (ptr, '/');
grub_memcpy (&old_ino, ino, grub_bfs_to_cpu32 (sb->bsize));
if (ptr2)
{
char component[ptr2 - ptr + 1];
grub_memcpy (component, ptr, ptr2 - ptr);
component[ptr2 - ptr] = 0;
err = hop_level (disk, sb, ino, component);
}
else
err = hop_level (disk, sb, ino, ptr);
for (next = ptr; *next && *next != '/'; next++);
grub_memcpy (&old_ino, ino, sizeof (old_ino));
err = hop_level (disk, sb, ino, ptr, next);
if (err)
return err;
@ -767,7 +776,7 @@ find_file (const char *path, grub_disk_t disk,
#endif
{
grub_size_t symsize = grub_bfs_to_cpu64 (ino->size);
alloc = grub_malloc ((ptr2 ? grub_strlen (ptr2) : 0)
alloc = grub_malloc (grub_strlen (next)
+ symsize + 1);
if (!alloc)
{
@ -786,7 +795,7 @@ find_file (const char *path, grub_disk_t disk,
#ifndef MODE_AFS
else
{
alloc = grub_malloc ((ptr2 ? grub_strlen (ptr2) : 0)
alloc = grub_malloc (grub_strlen (next)
+ sizeof (ino->inplace_link) + 1);
if (!alloc)
{
@ -802,7 +811,7 @@ find_file (const char *path, grub_disk_t disk,
if (alloc[0] == '/')
{
err = read_extent (disk, sb, &sb->root_dir, 0, 0, ino,
grub_bfs_to_cpu32 (sb->bsize));
sizeof (*ino));
if (err)
{
grub_free (alloc);
@ -810,21 +819,14 @@ find_file (const char *path, grub_disk_t disk,
}
}
else
grub_memcpy (ino, &old_ino, grub_bfs_to_cpu32 (sb->bsize));
ptr = alloc + grub_strlen (alloc);
if (ptr2)
ptr = grub_stpcpy (ptr, ptr2);
*ptr = 0;
ptr = ptr2 = alloc;
grub_memcpy (ino, &old_ino, sizeof (old_ino));
wptr = alloc + grub_strlen (alloc);
if (next)
wptr = grub_stpcpy (wptr, next);
*wptr = 0;
next = alloc;
continue;
}
if (!ptr2)
{
grub_free (alloc);
return GRUB_ERR_NONE;
}
ptr = ptr2 + 1;
}
}
@ -866,17 +868,13 @@ grub_bfs_dir_iter (const char *name, grub_uint64_t value,
struct grub_bfs_dir_ctx *ctx)
{
grub_err_t err2;
union
{
struct grub_bfs_inode ino;
grub_uint8_t raw[grub_bfs_to_cpu32 (ctx->sb.bsize)];
} ino;
struct grub_bfs_inode ino;
struct grub_dirhook_info info;
err2 = grub_disk_read (ctx->device->disk, value
<< (grub_bfs_to_cpu32 (ctx->sb.log2_bsize)
- GRUB_DISK_SECTOR_BITS), 0,
grub_bfs_to_cpu32 (ctx->sb.bsize), (char *) ino.raw);
sizeof (ino), (char *) &ino);
if (err2)
{
grub_print_error ();
@ -886,11 +884,11 @@ grub_bfs_dir_iter (const char *name, grub_uint64_t value,
info.mtimeset = 1;
#ifdef MODE_AFS
info.mtime =
grub_divmod64 (grub_bfs_to_cpu64 (ino.ino.mtime), 1000000, 0);
grub_divmod64 (grub_bfs_to_cpu64 (ino.mtime), 1000000, 0);
#else
info.mtime = grub_bfs_to_cpu64 (ino.ino.mtime) >> 16;
info.mtime = grub_bfs_to_cpu64 (ino.mtime) >> 16;
#endif
info.dir = ((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) == ATTR_DIR);
info.dir = ((grub_bfs_to_cpu32 (ino.mode) & ATTR_TYPE) == ATTR_DIR);
return ctx->hook (name, &info, ctx->hook_data);
}
@ -910,17 +908,13 @@ grub_bfs_dir (grub_device_t device, const char *path,
return err;
{
union
{
struct grub_bfs_inode ino;
grub_uint8_t raw[grub_bfs_to_cpu32 (ctx.sb.bsize)];
} ino;
err = find_file (path, device->disk, &ctx.sb, &ino.ino);
struct grub_bfs_inode ino;
err = find_file (path, device->disk, &ctx.sb, &ino);
if (err)
return err;
if (((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) != ATTR_DIR))
if (((grub_bfs_to_cpu32 (ino.mode) & ATTR_TYPE) != ATTR_DIR))
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
iterate_in_b_tree (device->disk, &ctx.sb, &ino.ino, grub_bfs_dir_iter,
iterate_in_b_tree (device->disk, &ctx.sb, &ino, grub_bfs_dir_iter,
&ctx);
}
@ -938,26 +932,21 @@ grub_bfs_open (struct grub_file *file, const char *name)
return err;
{
union
{
struct grub_bfs_inode ino;
grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)];
} ino;
struct grub_bfs_inode ino;
struct grub_bfs_data *data;
err = find_file (name, file->device->disk, &sb, &ino.ino);
err = find_file (name, file->device->disk, &sb, &ino);
if (err)
return err;
if (((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) != ATTR_REG))
if (((grub_bfs_to_cpu32 (ino.mode) & ATTR_TYPE) != ATTR_REG))
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file"));
data = grub_zalloc (sizeof (struct grub_bfs_data)
+ grub_bfs_to_cpu32 (sb.bsize));
data = grub_zalloc (sizeof (struct grub_bfs_data));
if (!data)
return grub_errno;
data->sb = sb;
grub_memcpy (&data->ino, &ino, grub_bfs_to_cpu32 (sb.bsize));
grub_memcpy (&data->ino, &ino, sizeof (data->ino));
file->data = data;
file->size = grub_bfs_to_cpu64 (ino.ino.size);
file->size = grub_bfs_to_cpu64 (ino.size);
}
return GRUB_ERR_NONE;
@ -978,7 +967,7 @@ grub_bfs_read (grub_file_t file, char *buf, grub_size_t len)
struct grub_bfs_data *data = file->data;
err = read_bfs_file (file->device->disk, &data->sb,
data->ino, file->offset, buf, len,
&data->ino, file->offset, buf, len,
file->read_hook, file->read_hook_data);
if (err)
return -1;
@ -1005,7 +994,7 @@ grub_bfs_label (grub_device_t device, char **label)
static grub_ssize_t
read_bfs_attr (grub_disk_t disk,
const struct grub_bfs_superblock *sb,
const struct grub_bfs_inode *ino,
struct grub_bfs_inode *ino,
const char *name, void *buf, grub_size_t len)
{
grub_uint8_t *ptr = (grub_uint8_t *) ino->small_data;
@ -1036,32 +1025,27 @@ read_bfs_attr (grub_disk_t disk,
if (ino->attr.len != 0)
{
union
{
struct grub_bfs_inode ino;
grub_uint8_t raw[grub_bfs_to_cpu32 (sb->bsize)];
} ino2;
grub_size_t read;
grub_err_t err;
grub_uint64_t res;
err = read_extent (disk, sb, &ino->attr, 0, 0, ino2.raw,
err = read_extent (disk, sb, &ino->attr, 0, 0, ino,
grub_bfs_to_cpu32 (sb->bsize));
if (err)
return -1;
err = find_in_b_tree (disk, sb, &ino2.ino, name, &res);
err = find_in_b_tree (disk, sb, ino, name, grub_strlen (name), &res);
if (err)
return -1;
grub_disk_read (disk, res
<< (grub_bfs_to_cpu32 (sb->log2_bsize)
- GRUB_DISK_SECTOR_BITS), 0,
grub_bfs_to_cpu32 (sb->bsize), (char *) &ino2);
read = grub_bfs_to_cpu64 (ino2.ino.size);
grub_bfs_to_cpu32 (sb->bsize), (char *) ino);
read = grub_bfs_to_cpu64 (ino->size);
if (read > len)
read = len;
err = read_bfs_file (disk, sb, &ino2.ino, 0, buf, read, 0, 0);
err = read_bfs_file (disk, sb, ino, 0, buf, read, 0, 0);
if (err)
return -1;
return read;
@ -1074,6 +1058,8 @@ grub_bfs_uuid (grub_device_t device, char **uuid)
{
struct grub_bfs_superblock sb;
grub_err_t err;
struct grub_bfs_inode *ino;
grub_uint64_t vid;
*uuid = 0;
@ -1081,23 +1067,24 @@ grub_bfs_uuid (grub_device_t device, char **uuid)
if (err)
return err;
{
union
{
struct grub_bfs_inode ino;
grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)];
} ino;
grub_uint64_t vid;
ino = grub_malloc (grub_bfs_to_cpu32 (sb.bsize));
if (!ino)
return grub_errno;
err = read_extent (device->disk, &sb, &sb.root_dir, 0, 0,
&ino, grub_bfs_to_cpu32 (sb.bsize));
if (err)
err = read_extent (device->disk, &sb, &sb.root_dir, 0, 0,
ino, grub_bfs_to_cpu32 (sb.bsize));
if (err)
{
grub_free (ino);
return err;
if (read_bfs_attr (device->disk, &sb, &ino.ino, "be:volume_id",
&vid, sizeof (vid)) == sizeof (vid))
*uuid =
grub_xasprintf ("%016" PRIxGRUB_UINT64_T, grub_bfs_to_cpu64 (vid));
}
}
if (read_bfs_attr (device->disk, &sb, ino, "be:volume_id",
&vid, sizeof (vid)) == sizeof (vid))
*uuid =
grub_xasprintf ("%016" PRIxGRUB_UINT64_T, grub_bfs_to_cpu64 (vid));
grub_free (ino);
return GRUB_ERR_NONE;
}
#endif

View file

@ -291,15 +291,18 @@ static inline void grub_set_unaligned32 (void *ptr, grub_uint32_t val)
dd->d = val;
}
struct grub_unaligned_uint64
{
grub_uint64_t val;
} __attribute__ ((packed));
typedef struct grub_unaligned_uint64 grub_unaligned_uint64_t;
static inline grub_uint64_t grub_get_unaligned64 (const void *ptr)
{
struct grub_unaligned_uint64_t
{
grub_uint64_t d;
} __attribute__ ((packed));
const struct grub_unaligned_uint64_t *dd
= (const struct grub_unaligned_uint64_t *)ptr;
return dd->d;
const struct grub_unaligned_uint64 *dd
= (const struct grub_unaligned_uint64 *) ptr;
return dd->val;
}
static inline void grub_set_unaligned64 (void *ptr, grub_uint64_t val)