]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Support BtrFS embedding.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 5 Nov 2011 13:47:25 +0000 (14:47 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 5 Nov 2011 13:47:25 +0000 (14:47 +0100)
* grub-core/fs/btrfs.c (grub_btrfs_embed) [GRUB_UTIL]: New function.
(grub_btrfs_fs) [GRUB_UTIL]: Set embed.
* include/grub/fs.h (grub_fs) [GRUB_UTIL]: New field embed.
* util/grub-setup.c (setup): Use fs embedding if available.
Add additional sanity check.

ChangeLog
grub-core/fs/btrfs.c
include/grub/fs.h
util/grub-setup.c

index 75cac6a4e420225c5028ad9bfcc48cdc53f276f8..8c125fa97d04eaf247ebdccd0659b2ed242efe20 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2011-11-05  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Support BtrFS embedding.
+
+       * grub-core/fs/btrfs.c (grub_btrfs_embed) [GRUB_UTIL]: New function.
+       (grub_btrfs_fs) [GRUB_UTIL]: Set embed.
+       * include/grub/fs.h (grub_fs) [GRUB_UTIL]: New field embed.
+       * util/grub-setup.c (setup): Use fs embedding if available.
+       Add additional sanity check.
+
 2011-11-05  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * util/grub-install.in: Fix condition for config_opt.
index 16e034661be6e77424c080a7e09ddf3a3fcc7026..3dc680034e7450e86e712b595ac456c4a6face7f 100644 (file)
@@ -1596,6 +1596,35 @@ grub_btrfs_label (grub_device_t device, char **label)
   return grub_errno;
 }
 
+#ifdef GRUB_UTIL
+static grub_err_t
+grub_btrfs_embed (grub_device_t device __attribute__ ((unused)),
+                 unsigned int *nsectors,
+                 grub_embed_type_t embed_type,
+                 grub_disk_addr_t **sectors)
+{
+  unsigned i;
+
+  if (embed_type != GRUB_EMBED_PCBIOS)
+    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                      "BtrFS curently supports only PC-BIOS embedding");
+
+  if (64 * 2 - 1 < *nsectors)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE,
+                      "Your core.img is unusually large.  "
+                      "It won't fit in the embedding area.");
+
+  *nsectors = 64 * 2 - 1;
+  *sectors = grub_malloc (*nsectors * sizeof (**sectors));
+  if (!*sectors)
+    return grub_errno;
+  for (i = 0; i < *nsectors; i++)
+    (*sectors)[i] = i + 1;
+
+  return GRUB_ERR_NONE;
+}
+#endif
+
 static struct grub_fs grub_btrfs_fs = {
   .name = "btrfs",
   .dir = grub_btrfs_dir,
@@ -1605,6 +1634,7 @@ static struct grub_fs grub_btrfs_fs = {
   .uuid = grub_btrfs_uuid,
   .label = grub_btrfs_label,
 #ifdef GRUB_UTIL
+  .embed = grub_btrfs_embed,
   .reserved_first_sector = 1,
 #endif
 };
index 2c39332a95d5d701307af9898d3f9d1f3d50eef3..dd274e1511580a3753d819458784ef8e3662ceaf 100644 (file)
 #include <grub/types.h>
 
 #include <grub/list.h>
+/* For embedding types.  */
+#ifdef GRUB_UTIL
+#include <grub/partition.h>
+#endif
 
 /* Forward declaration is required, because of mutual reference.  */
 struct grub_file;
@@ -74,6 +78,11 @@ struct grub_fs
   grub_err_t (*mtime) (grub_device_t device, grub_int32_t *timebuf);
 
 #ifdef GRUB_UTIL
+  /* Determine sectors available for embedding.  */
+  grub_err_t (*embed) (grub_device_t device, unsigned int *nsectors,
+                      grub_embed_type_t embed_type,
+                      grub_disk_addr_t **sectors);
+
   /* Whether this filesystem reserves first sector for DOS-style boot.  */
   int reserved_first_sector;
 #endif
index 99de26f76020b088f0acbf8ef252922098a9345a..d3f6fe8b87b26a6437647ac051a664adc80f99c2 100644 (file)
@@ -408,29 +408,44 @@ setup (const char *dir,
 
     free (tmp_img);
     
-    if (! dest_partmap)
+    if (! dest_partmap && ! fs)
       {
        grub_util_warn (_("Attempting to install GRUB to a partitionless disk or to a partition.  This is a BAD idea."));
        goto unable_to_embed;
       }
-    if (multiple_partmaps || fs)
+    if (multiple_partmaps || (dest_partmap && fs))
       {
        grub_util_warn (_("Attempting to install GRUB to a disk with multiple partition labels or both partition label and filesystem.  This is not supported yet."));
        goto unable_to_embed;
       }
 
-    if (!dest_partmap->embed)
+    if (dest_partmap && !dest_partmap->embed)
       {
        grub_util_warn ("Partition style '%s' doesn't support embeding",
                        dest_partmap->name);
        goto unable_to_embed;
       }
 
+    if (fs && !fs->embed)
+      {
+       grub_util_warn ("File system '%s' doesn't support embeding",
+                       fs->name);
+       goto unable_to_embed;
+      }
+
     nsec = core_sectors;
-    err = dest_partmap->embed (dest_dev->disk, &nsec,
-                              GRUB_EMBED_PCBIOS, &sectors);
-    if (nsec > 2 * core_sectors)
-      nsec = 2 * core_sectors;
+    if (dest_partmap)
+      err = dest_partmap->embed (dest_dev->disk, &nsec,
+                                GRUB_EMBED_PCBIOS, &sectors);
+    else
+      err = fs->embed (dest_dev, &nsec,
+                      GRUB_EMBED_PCBIOS, &sectors);
+    if (!err && nsec < core_sectors)
+      {
+       err = grub_error (GRUB_ERR_OUT_OF_RANGE,
+                         "Your embedding area is unusually small.  "
+                         "core.img won't fit in it.");
+      }
     
     if (err)
       {
@@ -439,6 +454,9 @@ setup (const char *dir,
        goto unable_to_embed;
       }
 
+    if (nsec > 2 * core_sectors)
+      nsec = 2 * core_sectors;
+
     /* Clean out the blocklists.  */
     block = first_block;
     while (block->len)