blob: 28eb24d5ff524779b5a4233408cac88f5f21b305 [file] [log] [blame]
/*
* 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"
#define SB_LABEL_SIZE 32
#define SB_JOURNAL_BUCKETS 256U
#define node(i, j) ((i)->d + (j))
#define end(i) node(i, le16_to_cpu((i)->keys))
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 "\xc6\x85\x73\xf6\x4e\x1a\x45\xca\x82\x65\xf5\x7f\x48\xba\x6d\x81"
/* magic string len */
#define BCACHE_SB_MAGIC_LEN (sizeof(BCACHE_SB_MAGIC) - 1)
/* 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 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 errno ? -errno : BLKID_PROBE_NONE;
if (le64_to_cpu(bcs->offset) != BCACHE_SB_OFF / 512)
return BLKID_PROBE_NONE;
if (blkid_probe_set_uuid(pr, bcs->uuid) < 0)
return BLKID_PROBE_NONE;
return BLKID_PROBE_OK;
}
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 }
}
};