1 | /*
|
---|
2 | * Copyright (C) 2013 Rolf Fokkens <rolf@fokkens.nl>
|
---|
3 | *
|
---|
4 | * This file may be redistributed under the terms of the
|
---|
5 | * GNU Lesser General Public License.
|
---|
6 | *
|
---|
7 | * Based on code fragments from bcache-tools by Kent Overstreet:
|
---|
8 | * http://evilpiepirate.org/git/bcache-tools.git
|
---|
9 | */
|
---|
10 |
|
---|
11 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_BCACHE) += bcache.o
|
---|
12 |
|
---|
13 | //config:
|
---|
14 | //config:config FEATURE_VOLUMEID_BCACHE
|
---|
15 | //config: bool "bcache filesystem"
|
---|
16 | //config: default y
|
---|
17 | //config: depends on VOLUMEID
|
---|
18 | //config: help
|
---|
19 | //config: TODO
|
---|
20 | //config:
|
---|
21 |
|
---|
22 | #include "volume_id_internal.h"
|
---|
23 |
|
---|
24 | #define SB_LABEL_SIZE 32
|
---|
25 | #define SB_JOURNAL_BUCKETS 256U
|
---|
26 |
|
---|
27 | static const char bcache_magic[] ALIGN1 = {
|
---|
28 | 0xc6, 0x85, 0x73, 0xf6, 0x4e, 0x1a, 0x45, 0xca,
|
---|
29 | 0x82, 0x65, 0xf5, 0x7f, 0x48, 0xba, 0x6d, 0x81
|
---|
30 | };
|
---|
31 |
|
---|
32 | struct bcache_super_block {
|
---|
33 | uint64_t csum;
|
---|
34 | uint64_t offset; /* sector where this sb was written */
|
---|
35 | uint64_t version;
|
---|
36 |
|
---|
37 | uint8_t magic[16];
|
---|
38 |
|
---|
39 | uint8_t uuid[16];
|
---|
40 | union {
|
---|
41 | uint8_t set_uuid[16];
|
---|
42 | uint64_t set_magic;
|
---|
43 | };
|
---|
44 | uint8_t label[SB_LABEL_SIZE];
|
---|
45 |
|
---|
46 | uint64_t flags;
|
---|
47 | uint64_t seq;
|
---|
48 | uint64_t pad[8];
|
---|
49 |
|
---|
50 | union {
|
---|
51 | struct {
|
---|
52 | /* Cache devices */
|
---|
53 | uint64_t nbuckets; /* device size */
|
---|
54 |
|
---|
55 | uint16_t block_size; /* sectors */
|
---|
56 | uint16_t bucket_size; /* sectors */
|
---|
57 |
|
---|
58 | uint16_t nr_in_set;
|
---|
59 | uint16_t nr_this_dev;
|
---|
60 | };
|
---|
61 | struct {
|
---|
62 | /* Backing devices */
|
---|
63 | uint64_t data_offset;
|
---|
64 |
|
---|
65 | /*
|
---|
66 | * block_size from the cache device section is still used by
|
---|
67 | * backing devices, so don't add anything here until we fix
|
---|
68 | * things to not need it for backing devices anymore
|
---|
69 | */
|
---|
70 | };
|
---|
71 | };
|
---|
72 |
|
---|
73 | uint32_t last_mount; /* time_t */
|
---|
74 |
|
---|
75 | uint16_t first_bucket;
|
---|
76 | union {
|
---|
77 | uint16_t njournal_buckets;
|
---|
78 | uint16_t keys;
|
---|
79 | };
|
---|
80 | uint64_t d[SB_JOURNAL_BUCKETS]; /* journal buckets */
|
---|
81 | };
|
---|
82 |
|
---|
83 | /* magic string */
|
---|
84 | #define BCACHE_SB_MAGIC bcache_magic
|
---|
85 | /* magic string len */
|
---|
86 | #define BCACHE_SB_MAGIC_LEN sizeof (bcache_magic)
|
---|
87 | /* super block offset */
|
---|
88 | #define BCACHE_SB_OFF 0x1000
|
---|
89 | /* supper block offset in kB */
|
---|
90 | #define BCACHE_SB_KBOFF (BCACHE_SB_OFF >> 10)
|
---|
91 | /* magic string offset within super block */
|
---|
92 | #define BCACHE_SB_MAGIC_OFF offsetof (struct bcache_super_block, magic)
|
---|
93 |
|
---|
94 | int FAST_FUNC volume_id_probe_bcache(struct volume_id *id /*,uint64_t off*/)
|
---|
95 | {
|
---|
96 | struct bcache_super_block *sb;
|
---|
97 |
|
---|
98 | sb = volume_id_get_buffer(id, BCACHE_SB_OFF, sizeof(*sb));
|
---|
99 | if (sb == NULL)
|
---|
100 | return -1;
|
---|
101 |
|
---|
102 | if (memcmp(sb->magic, BCACHE_SB_MAGIC, BCACHE_SB_MAGIC_LEN) != 0)
|
---|
103 | return -1;
|
---|
104 |
|
---|
105 | volume_id_set_label_string(id, sb->label, SB_LABEL_SIZE);
|
---|
106 | volume_id_set_uuid(id, sb->uuid, UUID_DCE);
|
---|
107 | IF_FEATURE_BLKID_TYPE(id->type = "bcache";)
|
---|
108 |
|
---|
109 | return 0;
|
---|
110 | }
|
---|