]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2010-09-09 Robert Millan <rmh@gnu.org>
authorRobert Millan <rmh@aybabtu.com>
Wed, 8 Sep 2010 23:12:10 +0000 (01:12 +0200)
committerRobert Millan <rmh@aybabtu.com>
Wed, 8 Sep 2010 23:12:10 +0000 (01:12 +0200)
Basic Btrfs support (detection and UUID).

* grub-core/fs/btrfs.c: New file.
* Makefile.util.def (library): Register btrfs.c.
* grub-core/Makefile.core.def: Likewise.

ChangeLog
Makefile.util.def
grub-core/Makefile.core.def
grub-core/fs/btrfs.c [new file with mode: 0644]

index ae534fa7f21703c9cccad1b980ed802fb23cdd84..0593c7731cd0a620097367c9921de6e9f1e7649d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2010-09-09  Robert Millan  <rmh@gnu.org>
+
+       Basic Btrfs support (detection and UUID).
+
+       * grub-core/fs/btrfs.c: New file.
+       * Makefile.util.def (library): Register btrfs.c.
+       * grub-core/Makefile.core.def: Likewise.
+
 2010-09-08  Robert Millan  <rmh@gnu.org>
 
        * util/grub-mkconfig_lib.in (is_path_readable_by_grub): Improve
index 05c4404a24514023ce6ce5ab0c5ab9d3b85ed91d..413c7eed86ba20feb5f45683a660808238bc7a73 100644 (file)
@@ -43,6 +43,7 @@ library = {
   common = grub-core/fs/afs.c;
   common = grub-core/fs/befs_be.c;
   common = grub-core/fs/befs.c;
+  common = grub-core/fs/btrfs.c;
   common = grub-core/fs/cpio.c;
   common = grub-core/fs/ext2.c;
   common = grub-core/fs/fat.c;
index 04525bbabf223831ff3e894df892fe923d75509c..000ccaa2aee322f11591656f1377b54127b6be26 100644 (file)
@@ -835,6 +835,11 @@ module = {
   common = fs/befs_be.c;
 };
 
+module = {
+  name = btrfs;
+  common = fs/btrfs.c;
+};
+
 module = {
   name = cpio;
   common = fs/cpio.c;
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
new file mode 100644 (file)
index 0000000..a50bae0
--- /dev/null
@@ -0,0 +1,132 @@
+/* btrfs.c - B-tree file system.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+
+#define BTRFS_SIGNATURE "_BHRfS_M"
+
+struct btrfs_superblock
+{ 
+  grub_uint8_t dummy1[32];
+  grub_uint16_t uuid[8];
+  grub_uint8_t dummy2[16];
+  grub_uint8_t signature[sizeof (BTRFS_SIGNATURE) - 1];
+} __attribute__ ((packed));
+
+struct grub_btrfs_data
+{
+  struct btrfs_superblock sblock;
+};
+
+static struct grub_btrfs_data *
+grub_btrfs_mount (grub_disk_t disk)
+{
+  struct grub_btrfs_data *data = grub_malloc (sizeof (*data));
+  if (! data)
+    return NULL;
+
+  if (grub_disk_read (disk, 128, 0, sizeof (data->sblock),
+                     &data->sblock) != GRUB_ERR_NONE)
+    goto fail;
+
+  if (grub_strncmp ((char *) data->sblock.signature, BTRFS_SIGNATURE, sizeof (BTRFS_SIGNATURE) - 1))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem");
+      goto fail;
+    }
+
+  return data;
+
+ fail:
+  grub_free (data);
+  return NULL;
+}
+
+static grub_err_t
+grub_btrfs_open (struct grub_file *file __attribute__ ((unused)),
+                const char *name __attribute__ ((unused)))
+{
+  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "only detection is supported for Btrfs");
+}
+
+static grub_err_t
+grub_btrfs_dir (grub_device_t device,
+                const char *path __attribute__ ((unused)),
+                int (*hook) (const char *filename,
+                             const struct grub_dirhook_info *info)
+                __attribute__ ((unused)))
+{
+  struct grub_btrfs_data *data = grub_btrfs_mount (device->disk);
+  if (grub_errno)
+    return grub_errno;
+
+  grub_free (data);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_btrfs_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_btrfs_data *data;
+
+  *uuid = NULL;
+
+  data = grub_btrfs_mount (device->disk);
+  if (! data)
+    return grub_errno;
+
+  *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
+                         grub_be_to_cpu16 (data->sblock.uuid[0]),
+                         grub_be_to_cpu16 (data->sblock.uuid[1]),
+                         grub_be_to_cpu16 (data->sblock.uuid[2]),
+                         grub_be_to_cpu16 (data->sblock.uuid[3]),
+                         grub_be_to_cpu16 (data->sblock.uuid[4]),
+                         grub_be_to_cpu16 (data->sblock.uuid[5]),
+                         grub_be_to_cpu16 (data->sblock.uuid[6]),
+                         grub_be_to_cpu16 (data->sblock.uuid[7]));
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static struct grub_fs grub_btrfs_fs =
+  {
+    .name = "btrfs",
+    .dir = grub_btrfs_dir,
+    .open = grub_btrfs_open,
+    .uuid = grub_btrfs_uuid,
+  };
+
+GRUB_MOD_INIT(btrfs)
+{
+  grub_fs_register (&grub_btrfs_fs);
+}
+
+GRUB_MOD_FINI(btrfs)
+{
+  grub_fs_unregister (&grub_btrfs_fs);
+}