]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* grub-core/fs/bfs.c: Remove variable length arrays. Reduces afs.mod and
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 20 Oct 2013 11:11:40 +0000 (13:11 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 20 Oct 2013 11:11:40 +0000 (13:11 +0200)
bfs.mod size by 556 resp 740 bytes (288 resp 334 compressed).
* include/grub/types.h (grub_unaligned_uint64_t): New type.

ChangeLog
grub-core/fs/bfs.c
include/grub/types.h

index ef694e68756a7f76f89d66e06ebf94a81a158f52..916d43d8f4b30d7a07851fac57b65cecdb51f43b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index f2e39d3230a607fe7e177c4b1096851de4e648ab..36b01efc86cd07fc791e90c0312f0648453b366b 100644 (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--;
     }
 
-#ifdef MODE_AFS
-  if (!alen)
-    return - (int) (grub_int8_t) *b;
+  ac = alen ? *a : 0;
+  bc = blen ? *b : 0;
 
-  return (int) (grub_int8_t) *a - (int) (grub_int8_t) *b;
+#ifdef MODE_AFS
+  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
index 1620227cd20a5d37e0735075cd0de61765159e7a..02e1182f29accdd1fc8fb210ef9345cf39978137 100644 (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)