2
* Copyright (C) 2010 Jeroen Oortwijn <oortwijn@gmail.com>
4
* This file may be redistributed under the terms of the
5
* GNU Lesser General Public License.
13
#include "superblocks.h"
15
#define B_OS_NAME_LENGTH 0x20
16
#define SUPER_BLOCK_MAGIC1 0x42465331 /* BFS1 */
17
#define SUPER_BLOCK_MAGIC2 0xdd121031
18
#define SUPER_BLOCK_MAGIC3 0x15b6830e
19
#define SUPER_BLOCK_FS_ENDIAN 0x42494745 /* BIGE */
20
#define INODE_MAGIC1 0x3bbe0ad9
21
#define B_UINT64_TYPE 0x554C4C47 /* ULLG */
23
#define FS16_TO_CPU(value, fs_is_le) (fs_is_le ? le16_to_cpu(value) \
25
#define FS32_TO_CPU(value, fs_is_le) (fs_is_le ? le32_to_cpu(value) \
27
#define FS64_TO_CPU(value, fs_is_le) (fs_is_le ? le64_to_cpu(value) \
30
typedef struct block_run {
31
int32_t allocation_group;
34
} __attribute__((packed)) block_run, inode_addr;
36
struct befs_super_block {
37
char name[B_OS_NAME_LENGTH];
39
int32_t fs_byte_order;
46
int32_t blocks_per_ag;
57
} __attribute__((packed));
59
typedef struct data_stream {
61
int64_t max_direct_range;
63
int64_t max_indirect_range;
64
block_run double_indirect;
65
int64_t max_double_indirect_range;
67
} __attribute__((packed)) data_stream;
77
int64_t last_modified_time;
79
inode_addr attributes;
85
int32_t small_data[1];
86
} __attribute__((packed));
93
} __attribute__((packed));
95
static int probe_befs(blkid_probe pr, const struct blkid_idmag *mag)
97
struct befs_super_block *bs;
98
struct befs_inode *bi;
99
struct small_data *sd;
101
uint64_t volume_id = 0;
102
const char *version = NULL;
104
bs = (struct befs_super_block *) blkid_probe_get_buffer(pr,
105
mag->sboff - B_OS_NAME_LENGTH,
106
sizeof(struct befs_super_block));
110
if (le32_to_cpu(bs->magic1) == SUPER_BLOCK_MAGIC1
111
&& le32_to_cpu(bs->magic2) == SUPER_BLOCK_MAGIC2
112
&& le32_to_cpu(bs->magic3) == SUPER_BLOCK_MAGIC3
113
&& le32_to_cpu(bs->fs_byte_order) == SUPER_BLOCK_FS_ENDIAN) {
115
version = "little-endian";
116
} else if (be32_to_cpu(bs->magic1) == SUPER_BLOCK_MAGIC1
117
&& be32_to_cpu(bs->magic2) == SUPER_BLOCK_MAGIC2
118
&& be32_to_cpu(bs->magic3) == SUPER_BLOCK_MAGIC3
119
&& be32_to_cpu(bs->fs_byte_order) == SUPER_BLOCK_FS_ENDIAN) {
121
version = "big-endian";
125
bi = (struct befs_inode *) blkid_probe_get_buffer(pr,
126
(FS32_TO_CPU(bs->root_dir.allocation_group, fs_le)
127
<< FS32_TO_CPU(bs->ag_shift, fs_le)
128
<< FS32_TO_CPU(bs->block_shift, fs_le))
129
+ (FS16_TO_CPU(bs->root_dir.start, fs_le)
130
<< FS32_TO_CPU(bs->block_shift, fs_le)),
131
FS16_TO_CPU(bs->root_dir.len, fs_le)
132
<< FS32_TO_CPU(bs->block_shift, fs_le));
136
if (FS32_TO_CPU(bi->magic1, fs_le) != INODE_MAGIC1)
140
* all checks pass, set LABEL and VERSION
142
if (strlen(bs->name))
143
blkid_probe_set_label(pr, (unsigned char *) bs->name,
146
blkid_probe_set_version(pr, version);
151
sd = (struct small_data *) bi->small_data;
154
if (FS32_TO_CPU(sd->type, fs_le) == B_UINT64_TYPE
155
&& FS16_TO_CPU(sd->name_size, fs_le) == 12
156
&& FS16_TO_CPU(sd->data_size, fs_le) == 8
157
&& strcmp(sd->name, "be:volume_id") == 0) {
158
volume_id = *(uint64_t *) ((uint8_t *) sd->name
159
+ FS16_TO_CPU(sd->name_size, fs_le)
161
blkid_probe_sprintf_uuid(pr,
162
(unsigned char *) &volume_id,
165
FS64_TO_CPU(volume_id, fs_le));
167
} else if (FS32_TO_CPU(sd->type, fs_le) == 0
168
&& FS16_TO_CPU(sd->name_size, fs_le) == 0
169
&& FS16_TO_CPU(sd->data_size, fs_le) == 0) {
173
sd = (struct small_data *) ((uint8_t *) sd
174
+ sizeof(struct small_data)
175
+ FS16_TO_CPU(sd->name_size, fs_le) + 3
176
+ FS16_TO_CPU(sd->data_size, fs_le) + 1);
178
} while ((intptr_t) sd < (intptr_t) bi
179
+ FS32_TO_CPU(bi->inode_size, fs_le)
180
- sizeof(struct small_data));
182
if (volume_id == 0) {
184
* TODO: Search for the be:volume_id attribute in the
185
* attributes directory of the root directory.
192
const struct blkid_idinfo befs_idinfo =
195
.usage = BLKID_USAGE_FILESYSTEM,
196
.probefunc = probe_befs,
197
.minsz = 1024 * 1440,
199
{ .magic = "BFS1", .len = 4, .sboff = B_OS_NAME_LENGTH },
200
{ .magic = "1SFB", .len = 4, .sboff = B_OS_NAME_LENGTH },
201
{ .magic = "BFS1", .len = 4, .sboff = 0x200 +
203
{ .magic = "1SFB", .len = 4, .sboff = 0x200 +