Coverage Report

Created: 2026-03-10 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/util-linux/libblkid/src/superblocks/befs.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2010 Jeroen Oortwijn <oortwijn@gmail.com>
3
 *
4
 * Partly based on the Haiku BFS driver by
5
 *     Axel Dörfler <axeld@pinc-software.de>
6
 *
7
 * Also inspired by the Linux BeFS driver by
8
 *     Will Dyson <will_dyson@pobox.com>, et al.
9
 *
10
 * This file may be redistributed under the terms of the
11
 * GNU Lesser General Public License.
12
 */
13
#include <stdio.h>
14
#include <stdlib.h>
15
#include <unistd.h>
16
#include <string.h>
17
#include <inttypes.h>
18
19
#include "superblocks.h"
20
21
2.34k
#define B_OS_NAME_LENGTH  0x20
22
6.59k
#define SUPER_BLOCK_MAGIC1  0x42465331  /* BFS1 */
23
5.64k
#define SUPER_BLOCK_MAGIC2  0xdd121031
24
4.82k
#define SUPER_BLOCK_MAGIC3  0x15b6830e
25
1.47k
#define SUPER_BLOCK_FS_ENDIAN 0x42494745  /* BIGE */
26
2.43k
#define INODE_MAGIC1    0x3bbe0ad9
27
950
#define BPLUSTREE_MAGIC   0x69f6c2e8
28
6.41k
#define BPLUSTREE_NULL    -1LL
29
295
#define NUM_DIRECT_BLOCKS 12
30
8.27k
#define B_UINT64_TYPE   0x554c4c47  /* ULLG */
31
1.16k
#define KEY_NAME    "be:volume_id"
32
4.13k
#define KEY_SIZE    8
33
34
27.1M
#define FS16_TO_CPU(value, fs_is_le) (fs_is_le ? le16_to_cpu(value) \
35
27.1M
              : be16_to_cpu(value))
36
27.1M
#define FS32_TO_CPU(value, fs_is_le) (fs_is_le ? le32_to_cpu(value) \
37
27.1M
              : be32_to_cpu(value))
38
36.1k
#define FS64_TO_CPU(value, fs_is_le) (fs_is_le ? le64_to_cpu(value) \
39
36.1k
              : be64_to_cpu(value))
40
41
typedef struct block_run {
42
  int32_t   allocation_group;
43
  uint16_t  start;
44
  uint16_t  len;
45
} __attribute__((packed)) block_run, inode_addr;
46
47
struct befs_super_block {
48
  char    name[B_OS_NAME_LENGTH];
49
  int32_t   magic1;
50
  int32_t   fs_byte_order;
51
  uint32_t  block_size;
52
  uint32_t  block_shift;
53
  int64_t   num_blocks;
54
  int64_t   used_blocks;
55
  int32_t   inode_size;
56
  int32_t   magic2;
57
  int32_t   blocks_per_ag;
58
  int32_t   ag_shift;
59
  int32_t   num_ags;
60
  int32_t   flags;
61
  block_run log_blocks;
62
  int64_t   log_start;
63
  int64_t   log_end;
64
  int32_t   magic3;
65
  inode_addr  root_dir;
66
  inode_addr  indices;
67
  int32_t   pad[8];
68
} __attribute__((packed));
69
70
typedef struct data_stream {
71
  block_run direct[NUM_DIRECT_BLOCKS];
72
  int64_t   max_direct_range;
73
  block_run indirect;
74
  int64_t   max_indirect_range;
75
  block_run double_indirect;
76
  int64_t   max_double_indirect_range;
77
  int64_t   size;
78
} __attribute__((packed)) data_stream;
79
80
struct befs_inode {
81
  int32_t   magic1;
82
  inode_addr  inode_num;
83
  int32_t   uid;
84
  int32_t   gid;
85
  int32_t   mode;
86
  int32_t   flags;
87
  int64_t   create_time;
88
  int64_t   last_modified_time;
89
  inode_addr  parent;
90
  inode_addr  attributes;
91
  uint32_t  type;
92
  int32_t   inode_size;
93
  uint32_t  etc;
94
  data_stream data;
95
  int32_t   pad[4];
96
  int32_t   small_data[0];
97
} __attribute__((packed));
98
99
struct small_data {
100
  uint32_t  type;
101
  uint16_t  name_size;
102
  uint16_t  data_size;
103
  char    name[0];
104
} __attribute__((packed));
105
106
struct bplustree_header {
107
  uint32_t  magic;
108
  uint32_t  node_size;
109
  uint32_t  max_number_of_levels;
110
  uint32_t  data_type;
111
  int64_t   root_node_pointer;
112
  int64_t   free_node_pointer;
113
  int64_t   maximum_size;
114
} __attribute__((packed));
115
116
struct bplustree_node {
117
  int64_t   left_link;
118
  int64_t   right_link;
119
  int64_t   overflow_link;
120
  uint16_t  all_key_count;
121
  uint16_t  all_key_length;
122
  char    name[0];
123
} __attribute__((packed));
124
125
static const unsigned char *get_block_run(blkid_probe pr, const struct befs_super_block *bs,
126
          const struct block_run *br, int fs_le)
127
9.94k
{
128
9.94k
  return blkid_probe_get_buffer(pr,
129
9.94k
      ((uint64_t) FS32_TO_CPU(br->allocation_group, fs_le)
130
9.94k
          << FS32_TO_CPU(bs->ag_shift, fs_le)
131
9.94k
          << FS32_TO_CPU(bs->block_shift, fs_le))
132
9.94k
        + ((uint64_t) FS16_TO_CPU(br->start, fs_le)
133
9.94k
          << FS32_TO_CPU(bs->block_shift, fs_le)),
134
9.94k
      (uint64_t) FS16_TO_CPU(br->len, fs_le)
135
9.94k
          << FS32_TO_CPU(bs->block_shift, fs_le));
136
9.94k
}
137
138
static const unsigned char *get_custom_block_run(blkid_probe pr,
139
        const struct befs_super_block *bs,
140
        const struct block_run *br,
141
        int64_t offset, uint32_t length, int fs_le)
142
7.22k
{
143
7.22k
  if (offset + length > (int64_t) FS16_TO_CPU(br->len, fs_le)
144
7.22k
          << FS32_TO_CPU(bs->block_shift, fs_le))
145
109
    return NULL;
146
147
7.11k
  return blkid_probe_get_buffer(pr,
148
7.11k
      ((uint64_t) FS32_TO_CPU(br->allocation_group, fs_le)
149
7.11k
          << FS32_TO_CPU(bs->ag_shift, fs_le)
150
7.11k
          << FS32_TO_CPU(bs->block_shift, fs_le))
151
7.11k
        + ((uint64_t) FS16_TO_CPU(br->start, fs_le)
152
7.11k
          << FS32_TO_CPU(bs->block_shift, fs_le))
153
7.11k
        + offset,
154
7.11k
      length);
155
7.22k
}
156
157
static const unsigned char *get_tree_node(blkid_probe pr, const struct befs_super_block *bs,
158
        const struct data_stream *ds,
159
        int64_t start, uint32_t length, int fs_le)
160
7.70k
{
161
7.70k
  if (start < (int64_t) FS64_TO_CPU(ds->max_direct_range, fs_le)) {
162
207
    int64_t br_len;
163
207
    size_t i;
164
165
295
    for (i = 0; i < NUM_DIRECT_BLOCKS; i++) {
166
292
      br_len = (int64_t) FS16_TO_CPU(ds->direct[i].len, fs_le)
167
292
          << FS32_TO_CPU(bs->block_shift, fs_le);
168
292
      if (start < br_len)
169
204
        return get_custom_block_run(pr, bs,
170
204
              &ds->direct[i],
171
204
              start, length, fs_le);
172
88
      start -= br_len;
173
88
      if (start < 0)
174
0
        return NULL; /* Corrupt? */
175
88
    }
176
7.49k
  } else if (start < (int64_t) FS64_TO_CPU(ds->max_indirect_range, fs_le)) {
177
6.95k
    struct block_run *br;
178
6.95k
    int64_t max_br, br_len, i;
179
180
6.95k
    start -= FS64_TO_CPU(ds->max_direct_range, fs_le);
181
6.95k
    if (start < 0)
182
3
      return NULL; /* Corrupt? */
183
184
6.94k
    max_br = ((int64_t) FS16_TO_CPU(ds->indirect.len, fs_le)
185
6.94k
          << FS32_TO_CPU(bs->block_shift, fs_le))
186
6.94k
        / sizeof(struct block_run);
187
188
6.94k
    br = (struct block_run *) get_block_run(pr, bs, &ds->indirect,
189
6.94k
                  fs_le);
190
6.94k
    if (!br)
191
23
      return NULL;
192
193
27.0M
    for (i = 0; i < max_br; i++) {
194
27.0M
      br_len = (int64_t) FS16_TO_CPU(br[i].len, fs_le)
195
27.0M
          << FS32_TO_CPU(bs->block_shift, fs_le);
196
27.0M
      if (start < br_len)
197
6.82k
        return get_custom_block_run(pr, bs, &br[i],
198
6.82k
              start, length, fs_le);
199
26.9M
      start -= br_len;
200
26.9M
    }
201
6.92k
  } else if (start < (int64_t) FS64_TO_CPU(ds->max_double_indirect_range, fs_le)) {
202
404
    struct block_run *br;
203
404
    int64_t max_br, di_br_size, br_per_di_br, di_index, i_index;
204
205
404
    start -= (int64_t) FS64_TO_CPU(ds->max_indirect_range, fs_le);
206
404
    if (start < 0)
207
5
      return NULL; /* Corrupt? */
208
209
399
    di_br_size = (int64_t) FS16_TO_CPU(ds->double_indirect.len,
210
399
        fs_le) << FS32_TO_CPU(bs->block_shift, fs_le);
211
399
    if (di_br_size == 0)
212
32
      return NULL;
213
214
367
    br_per_di_br = di_br_size / sizeof(struct block_run);
215
367
    if (br_per_di_br == 0)
216
0
      return NULL;
217
218
367
    di_index = start / (br_per_di_br * di_br_size);
219
367
    i_index = (start % (br_per_di_br * di_br_size)) / di_br_size;
220
367
    start = (start % (br_per_di_br * di_br_size)) % di_br_size;
221
222
367
    if (di_index >= br_per_di_br)
223
79
      return NULL; /* Corrupt? */
224
225
288
    br = (struct block_run *) get_block_run(pr, bs,
226
288
            &ds->double_indirect, fs_le);
227
288
    if (!br)
228
17
      return NULL;
229
230
271
    max_br = ((int64_t)FS16_TO_CPU(br[di_index].len, fs_le)
231
271
        << FS32_TO_CPU(bs->block_shift, fs_le))
232
271
      / sizeof(struct block_run);
233
234
271
    if (i_index >= max_br)
235
37
      return NULL; /* Corrupt? */
236
237
234
    br = (struct block_run *) get_block_run(pr, bs, &br[di_index],
238
234
                  fs_le);
239
234
    if (!br)
240
39
      return NULL;
241
242
195
    return get_custom_block_run(pr, bs, &br[i_index], start, length,
243
195
                  fs_le);
244
234
  }
245
245
  return NULL;
246
7.70k
}
247
248
13.1k
#define BAD_KEYS -2
249
250
static int32_t compare_keys(const char keys1[], uint16_t keylengths1[],
251
          int32_t index, const char *key2,
252
          uint16_t keylength2, uint16_t all_key_length,
253
          int fs_le)
254
12.9k
{
255
12.9k
  const char *key1;
256
12.9k
  uint16_t keylength1, keystart1;
257
12.9k
  int32_t result;
258
259
12.9k
  keystart1 = index == 0 ? 0 : FS16_TO_CPU(keylengths1[index - 1], fs_le);
260
12.9k
  keylength1 = FS16_TO_CPU(keylengths1[index], fs_le) - keystart1;
261
262
12.9k
  if (keystart1 + keylength1 > all_key_length)
263
142
    return BAD_KEYS; /* Corrupt? */
264
265
12.8k
  key1 = &keys1[keystart1];
266
267
12.8k
  result = strncmp(key1, key2, min(keylength1, keylength2));
268
269
12.8k
  if (result == 0)
270
8.69k
    return keylength1 - keylength2;
271
272
4.13k
  if (result < 0) /* Don't clash with BAD_KEYS */
273
1.93k
    result = -1;
274
275
4.13k
  return result;
276
12.8k
}
277
278
static int64_t get_key_value(blkid_probe pr, const struct befs_super_block *bs,
279
      const struct befs_inode *bi, const char *key, int fs_le)
280
1.14k
{
281
1.14k
  struct bplustree_header *bh;
282
1.14k
  struct bplustree_node *bn;
283
1.14k
  uint16_t *keylengths;
284
1.14k
  int64_t *values;
285
1.14k
  int64_t node_pointer;
286
1.14k
  uint32_t bn_size, all_key_count, all_key_length;
287
1.14k
  uint32_t keylengths_offset, values_offset;
288
1.14k
  int32_t first, last, mid, cmp;
289
1.14k
  int loop_detect = 0;
290
291
1.14k
  errno = 0;
292
1.14k
  bh = (struct bplustree_header *) get_tree_node(pr, bs, &bi->data, 0,
293
1.14k
          sizeof(struct bplustree_header), fs_le);
294
1.14k
  if (!bh)
295
199
    return errno ? -errno : -ENOENT;
296
297
950
  if ((int32_t) FS32_TO_CPU(bh->magic, fs_le) != BPLUSTREE_MAGIC)
298
86
    return -ENOENT;
299
300
864
  node_pointer = FS64_TO_CPU(bh->root_node_pointer, fs_le);
301
864
  bn_size = FS32_TO_CPU(bh->node_size, fs_le);
302
303
864
  if (bn_size < sizeof(struct bplustree_node))
304
3
    return -ENOENT; /* Corrupt? */
305
306
6.55k
  do {
307
6.55k
    errno = 0;
308
309
6.55k
    bn = (struct bplustree_node *) get_tree_node(pr, bs, &bi->data,
310
6.55k
      node_pointer, bn_size, fs_le);
311
6.55k
    if (!bn)
312
646
      return errno ? -errno : -ENOENT;
313
314
5.91k
    all_key_count = FS16_TO_CPU(bn->all_key_count, fs_le);
315
5.91k
    all_key_length = FS16_TO_CPU(bn->all_key_length, fs_le);
316
5.91k
    keylengths_offset =
317
5.91k
      (sizeof(struct bplustree_node) + all_key_length
318
5.91k
       + sizeof(int64_t) - 1) & ~(sizeof(int64_t) - 1);
319
5.91k
    values_offset = keylengths_offset +
320
5.91k
      all_key_count * sizeof(uint16_t);
321
322
5.91k
    if (values_offset + all_key_count * sizeof(uint64_t) > bn_size)
323
24
      return -ENOENT; /* Corrupt? */
324
325
5.88k
    keylengths = (uint16_t *) ((uint8_t *) bn + keylengths_offset);
326
5.88k
    values = (int64_t *) ((uint8_t *) bn + values_offset);
327
328
5.88k
    first = 0;
329
5.88k
    mid = 0;
330
5.88k
    last = all_key_count - 1;
331
332
5.88k
    cmp = compare_keys(bn->name, keylengths, last, key,
333
5.88k
           strlen(key), all_key_length, fs_le);
334
5.88k
    if (cmp == BAD_KEYS)
335
84
      return -ENOENT;
336
337
5.80k
    if (cmp == 0) {
338
411
      if ((int64_t) FS64_TO_CPU(bn->overflow_link, fs_le)
339
411
              == BPLUSTREE_NULL)
340
1
        return FS64_TO_CPU(values[last], fs_le);
341
342
410
      node_pointer = FS64_TO_CPU(values[last], fs_le);
343
5.39k
    } else if (cmp < 0)
344
4.27k
      node_pointer = FS64_TO_CPU(bn->overflow_link, fs_le);
345
1.12k
    else {
346
7.83k
      while (first <= last) {
347
7.08k
        mid = (first + last) / 2;
348
349
7.08k
        cmp = compare_keys(bn->name, keylengths, mid,
350
7.08k
               key, strlen(key),
351
7.08k
               all_key_length, fs_le);
352
7.08k
        if (cmp == BAD_KEYS)
353
58
          return -ENOENT;
354
355
7.02k
        if (cmp == 0) {
356
312
          if ((int64_t) FS64_TO_CPU(bn->overflow_link,
357
312
            fs_le) == BPLUSTREE_NULL)
358
1
            return FS64_TO_CPU(values[mid],
359
312
                  fs_le);
360
311
          break;
361
312
        }
362
363
6.71k
        if (cmp < 0)
364
5.28k
          first = mid + 1;
365
1.42k
        else
366
1.42k
          last = mid - 1;
367
6.71k
      }
368
1.06k
      if (cmp < 0)
369
332
        node_pointer = FS64_TO_CPU(values[mid + 1],
370
1.06k
                  fs_le);
371
730
      else
372
730
        node_pointer = FS64_TO_CPU(values[mid], fs_le);
373
1.06k
    }
374
5.80k
  } while (++loop_detect < 100 &&
375
5.69k
    (int64_t) FS64_TO_CPU(bn->overflow_link, fs_le)
376
5.69k
            != BPLUSTREE_NULL);
377
47
  return 0;
378
861
}
379
380
static int get_uuid(blkid_probe pr, const struct befs_super_block *bs,
381
          uint64_t * const uuid, int fs_le)
382
1.26k
{
383
1.26k
  struct befs_inode *bi;
384
1.26k
  struct small_data *sd;
385
1.26k
  uint64_t bi_size, offset, sd_size, sd_total_size;
386
387
1.26k
  bi = (struct befs_inode *) get_block_run(pr, bs, &bs->root_dir, fs_le);
388
1.26k
  if (!bi)
389
9
    return errno ? -errno : BLKID_PROBE_NONE;
390
391
1.25k
  if (FS32_TO_CPU(bi->magic1, fs_le) != INODE_MAGIC1)
392
49
    return BLKID_PROBE_NONE;
393
394
1.20k
  bi_size = (uint64_t)FS16_TO_CPU(bs->root_dir.len, fs_le) <<
395
1.20k
    FS32_TO_CPU(bs->block_shift, fs_le);
396
1.20k
  sd_total_size = min(bi_size - sizeof(struct befs_inode),
397
1.20k
          (uint64_t)FS32_TO_CPU(bi->inode_size, fs_le));
398
399
1.20k
  offset = 0;
400
401
4.47k
  while (offset + sizeof(struct small_data) <= sd_total_size) {
402
4.45k
    sd = (struct small_data *) ((uint8_t *)bi->small_data + offset);
403
4.45k
    sd_size = sizeof(struct small_data)
404
4.45k
      + FS16_TO_CPU(sd->name_size, fs_le) + 3
405
4.45k
      + FS16_TO_CPU(sd->data_size, fs_le) + 1;
406
407
4.45k
    if (offset + sd_size > sd_total_size)
408
315
      break;
409
410
4.13k
    if (FS32_TO_CPU(sd->type, fs_le) == B_UINT64_TYPE
411
12
      && FS16_TO_CPU(sd->name_size, fs_le) == strlen(KEY_NAME)
412
0
      && FS16_TO_CPU(sd->data_size, fs_le) == KEY_SIZE
413
0
      && strcmp(sd->name, KEY_NAME) == 0) {
414
415
0
      memcpy(uuid,
416
0
             sd->name + FS16_TO_CPU(sd->name_size, fs_le) + 3,
417
0
             sizeof(uint64_t));
418
419
0
      break;
420
0
    }
421
422
4.13k
    if (FS32_TO_CPU(sd->type, fs_le) == 0
423
1.28k
        && FS16_TO_CPU(sd->name_size, fs_le) == 0
424
1.08k
        && FS16_TO_CPU(sd->data_size, fs_le) == 0)
425
867
      break;
426
427
3.26k
    offset += sd_size;
428
3.26k
  }
429
430
1.20k
  if (*uuid == 0
431
1.20k
    && (FS32_TO_CPU(bi->attributes.allocation_group, fs_le) != 0
432
42
      || FS16_TO_CPU(bi->attributes.start, fs_le) != 0
433
1.20k
      || FS16_TO_CPU(bi->attributes.len, fs_le) != 0)) {
434
1.20k
    int64_t value;
435
436
1.20k
    bi = (struct befs_inode *) get_block_run(pr, bs,
437
1.20k
              &bi->attributes, fs_le);
438
1.20k
    if (!bi)
439
33
      return errno ? -errno : BLKID_PROBE_NONE;
440
441
1.17k
    if (FS32_TO_CPU(bi->magic1, fs_le) != INODE_MAGIC1)
442
26
      return BLKID_PROBE_NONE;
443
444
1.14k
    value = get_key_value(pr, bs, bi, KEY_NAME, fs_le);
445
1.14k
    if (value < 0)
446
1.10k
      return value == -ENOENT ? BLKID_PROBE_NONE : value;
447
448
49
    if (value > 0) {
449
0
      bi = (struct befs_inode *) blkid_probe_get_buffer(pr,
450
0
        value << FS32_TO_CPU(bs->block_shift, fs_le),
451
0
        FS32_TO_CPU(bs->block_size, fs_le));
452
0
      if (!bi)
453
0
        return errno ? -errno : BLKID_PROBE_NONE;
454
455
0
      if (FS32_TO_CPU(bi->magic1, fs_le) != INODE_MAGIC1)
456
0
        return 1;
457
458
0
      if (FS32_TO_CPU(bi->type, fs_le) == B_UINT64_TYPE
459
0
        && FS64_TO_CPU(bi->data.size, fs_le) == KEY_SIZE
460
0
        && FS16_TO_CPU(bi->data.direct[0].len, fs_le)
461
0
                  == 1) {
462
0
        uint64_t *attr_data;
463
464
0
        attr_data = (uint64_t *) get_block_run(pr, bs,
465
0
            &bi->data.direct[0], fs_le);
466
0
        if (!attr_data)
467
0
          return errno ? -errno : BLKID_PROBE_NONE;
468
469
0
        *uuid = *attr_data;
470
0
      }
471
0
    }
472
49
  }
473
50
  return 0;
474
1.20k
}
475
476
static int probe_befs(blkid_probe pr, const struct blkid_idmag *mag)
477
2.34k
{
478
2.34k
  struct befs_super_block *bs;
479
2.34k
  const char *version = NULL;
480
2.34k
  uint64_t volume_id = 0;
481
2.34k
  uint32_t block_size, block_shift;
482
2.34k
  int fs_le, ret;
483
484
2.34k
  bs = (struct befs_super_block *) blkid_probe_get_buffer(pr,
485
2.34k
          mag->sboff - B_OS_NAME_LENGTH,
486
2.34k
          sizeof(struct befs_super_block));
487
2.34k
  if (!bs)
488
0
    return errno ? -errno : BLKID_PROBE_NONE;
489
490
2.34k
  if (le32_to_cpu(bs->magic1) == SUPER_BLOCK_MAGIC1
491
1.82k
    && le32_to_cpu(bs->magic2) == SUPER_BLOCK_MAGIC2
492
1.49k
    && le32_to_cpu(bs->magic3) == SUPER_BLOCK_MAGIC3
493
1.45k
    && le32_to_cpu(bs->fs_byte_order) == SUPER_BLOCK_FS_ENDIAN) {
494
1.39k
    fs_le = 1;
495
1.39k
    version = "little-endian";
496
1.39k
  } else if (be32_to_cpu(bs->magic1) == SUPER_BLOCK_MAGIC1
497
518
    && be32_to_cpu(bs->magic2) == SUPER_BLOCK_MAGIC2
498
37
    && be32_to_cpu(bs->magic3) == SUPER_BLOCK_MAGIC3
499
25
    && be32_to_cpu(bs->fs_byte_order) == SUPER_BLOCK_FS_ENDIAN) {
500
18
    fs_le = 0;
501
18
    version = "big-endian";
502
18
  } else
503
935
    return BLKID_PROBE_NONE;
504
505
1.41k
  block_size = FS32_TO_CPU(bs->block_size, fs_le);
506
1.41k
  block_shift = FS32_TO_CPU(bs->block_shift, fs_le);
507
508
1.41k
  if (block_shift < 10 || block_shift > 13 ||
509
1.33k
      block_size != 1U << block_shift)
510
93
    return BLKID_PROBE_NONE;
511
512
1.31k
  if (FS32_TO_CPU(bs->ag_shift, fs_le) > 64)
513
50
    return BLKID_PROBE_NONE;
514
515
1.26k
  ret = get_uuid(pr, bs, &volume_id, fs_le);
516
517
1.26k
  if (ret != 0)
518
1.21k
    return ret;
519
520
  /*
521
   * all checks pass, set LABEL, VERSION and UUID
522
   */
523
50
  if (*bs->name != '\0')
524
50
    blkid_probe_set_label(pr, (unsigned char *) bs->name,
525
50
              sizeof(bs->name));
526
50
  if (version)
527
50
    blkid_probe_set_version(pr, version);
528
529
50
  if (volume_id)
530
0
    blkid_probe_sprintf_uuid(pr, (unsigned char *) &volume_id,
531
0
          sizeof(volume_id), "%016" PRIx64,
532
0
          FS64_TO_CPU(volume_id, fs_le));
533
534
50
  blkid_probe_set_fsblocksize(pr, block_size);
535
50
  blkid_probe_set_block_size(pr, block_size);
536
50
  blkid_probe_set_fsendianness(pr,
537
50
      fs_le ? BLKID_ENDIANNESS_LITTLE : BLKID_ENDIANNESS_BIG);
538
539
50
  return BLKID_PROBE_OK;
540
1.26k
}
541
542
const struct blkid_idinfo befs_idinfo =
543
{
544
  .name   = "befs",
545
  .usage    = BLKID_USAGE_FILESYSTEM,
546
  .probefunc  = probe_befs,
547
  .minsz    = 1024 * 1440,
548
  .magics   = {
549
    { .magic = "BFS1", .len = 4, .sboff = B_OS_NAME_LENGTH },
550
    { .magic = "1SFB", .len = 4, .sboff = B_OS_NAME_LENGTH },
551
    { .magic = "BFS1", .len = 4, .sboff = 0x200 +
552
              B_OS_NAME_LENGTH },
553
    { .magic = "1SFB", .len = 4, .sboff = 0x200 +
554
              B_OS_NAME_LENGTH },
555
    { NULL }
556
  }
557
};