]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: Add bcache support
authorRolf Fokkens <rolf@rolffokkens.nl>
Fri, 6 Sep 2013 10:58:45 +0000 (12:58 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 11 Sep 2013 15:12:24 +0000 (17:12 +0200)
From https://bugzilla.redhat.com/show_bug.cgi?id=1001120#c11

[kzak@redhat.com: - move crc64 code to lib/ by separate patch,
                  - use BLKID_USAGE_OTHER rather than _RAID]

Signed-off-by: Karel Zak <kzak@redhat.com>
libblkid/src/Makemodule.am
libblkid/src/superblocks/bcache.c [new file with mode: 0644]
libblkid/src/superblocks/superblocks.c
libblkid/src/superblocks/superblocks.h

index 15639768a98e3fd41e343d592792eead7d520067..ac88b782a90d71fd7e1985085d6b743ca3a8065c 100644 (file)
@@ -46,6 +46,7 @@ libblkid_la_SOURCES = \
        libblkid/src/partitions/unixware.c \
        \
        libblkid/src/superblocks/adaptec_raid.c \
+       libblkid/src/superblocks/bcache.c \
        libblkid/src/superblocks/befs.c \
        libblkid/src/superblocks/bfs.c \
        libblkid/src/superblocks/btrfs.c \
diff --git a/libblkid/src/superblocks/bcache.c b/libblkid/src/superblocks/bcache.c
new file mode 100644 (file)
index 0000000..303f7ee
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2013 Rolf Fokkens <rolf@fokkens.nl>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ *
+ * Based on code fragments from bcache-tools by Kent Overstreet:
+ * http://evilpiepirate.org/git/bcache-tools.git
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include "superblocks.h"
+#include "crc64.h"
+
+#define SB_LABEL_SIZE      32
+#define SB_JOURNAL_BUCKETS 256U
+
+#define node(i, j)         ((i)->d + (j))
+#define end(i)             node(i, (i)->keys)
+
+static const char bcache_magic[] = {
+       0xc6, 0x85, 0x73, 0xf6, 0x4e, 0x1a, 0x45, 0xca,
+       0x82, 0x65, 0xf5, 0x7f, 0x48, 0xba, 0x6d, 0x81
+};
+
+struct bcache_super_block {
+       uint64_t                csum;
+       uint64_t                offset; /* sector where this sb was written */
+       uint64_t                version;
+
+       uint8_t                 magic[16];
+
+       uint8_t                 uuid[16];
+       union {
+               uint8_t         set_uuid[16];
+               uint64_t        set_magic;
+       };
+       uint8_t                 label[SB_LABEL_SIZE];
+
+       uint64_t                flags;
+       uint64_t                seq;
+       uint64_t                pad[8];
+
+       union {
+       struct {
+               /* Cache devices */
+               uint64_t        nbuckets;       /* device size */
+
+               uint16_t        block_size;     /* sectors */
+               uint16_t        bucket_size;    /* sectors */
+
+               uint16_t        nr_in_set;
+               uint16_t        nr_this_dev;
+       };
+       struct {
+               /* Backing devices */
+               uint64_t        data_offset;
+
+               /*
+                * block_size from the cache device section is still used by
+                * backing devices, so don't add anything here until we fix
+                * things to not need it for backing devices anymore
+                */
+       };
+       };
+
+       uint32_t                last_mount;     /* time_t */
+
+       uint16_t                first_bucket;
+       union {
+               uint16_t        njournal_buckets;
+               uint16_t        keys;
+       };
+       uint64_t                d[SB_JOURNAL_BUCKETS];  /* journal buckets */
+};
+
+/* magic string */
+#define BCACHE_SB_MAGIC     bcache_magic
+/* magic string len */
+#define BCACHE_SB_MAGIC_LEN sizeof (bcache_magic)
+/* super block offset */
+#define BCACHE_SB_OFF       0x1000
+/* supper block offset in kB */
+#define BCACHE_SB_KBOFF     (BCACHE_SB_OFF >> 10)
+/* magic string offset within super block */
+#define BCACHE_SB_MAGIC_OFF offsetof (struct bcache_super_block, magic)
+
+static uint64_t bcache_crc64(struct bcache_super_block *bcs)
+{
+       unsigned char *data = (unsigned char *) bcs;
+       size_t sz;
+
+       data += 8;              /* skip csum field */
+       sz = (unsigned char *) end(bcs) - data;
+
+       return crc64(0xFFFFFFFFFFFFFFFFULL, data, sz) ^ 0xFFFFFFFFFFFFFFFFULL;
+}
+
+static int probe_bcache (blkid_probe pr, const struct blkid_idmag *mag)
+{
+       struct bcache_super_block *bcs;
+
+       bcs = blkid_probe_get_sb(pr, mag, struct bcache_super_block);
+       if (!bcs)
+               return -1;
+
+       if (le64_to_cpu(bcs->offset) != BCACHE_SB_OFF / 512)
+               return 1;
+       if (!blkid_probe_verify_csum(pr, bcache_crc64(bcs), le64_to_cpu(bcs->csum)))
+               return 1;
+
+       if (blkid_probe_set_uuid(pr, bcs->uuid) < 0)
+               return -1;
+
+       return 0;
+};
+
+const struct blkid_idinfo bcache_idinfo =
+{
+       .name           = "bcache",
+       .usage          = BLKID_USAGE_OTHER,
+       .probefunc      = probe_bcache,
+       .minsz          = 8192,
+       .magics         =
+       {
+               { .magic = BCACHE_SB_MAGIC
+               , .len   = BCACHE_SB_MAGIC_LEN
+               , .kboff = BCACHE_SB_KBOFF
+               , .sboff = BCACHE_SB_MAGIC_OFF
+               } ,
+               { NULL }
+       }
+};
+
index d5478551fed825c9e59762e33aa036530f3a5840..c6394c4b325530d4268c5eb77a18a2c0976e1135 100644 (file)
@@ -101,6 +101,7 @@ static const struct blkid_idinfo *idinfos[] =
        &adraid_idinfo,
        &jmraid_idinfo,
 
+       &bcache_idinfo,
        &drbd_idinfo,
        &drbdproxy_datalog_idinfo,
        &lvm2_idinfo,
index 90847151ba48ba15f6c9037f052158bf1c7b1a47..2cae66a4184255b33a6eced023c21d1cfb6476cd 100644 (file)
@@ -72,6 +72,7 @@ extern const struct blkid_idinfo befs_idinfo;
 extern const struct blkid_idinfo nilfs2_idinfo;
 extern const struct blkid_idinfo exfat_idinfo;
 extern const struct blkid_idinfo f2fs_idinfo;
+extern const struct blkid_idinfo bcache_idinfo;
 
 /*
  * superblock functions