* 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:
parent
e89c2d48a9
commit
d28e1163c3
3 changed files with 240 additions and 244 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue