Coverage Report

Created: 2025-10-12 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/util-linux/libblkid/src/superblocks/scoutfs.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2025 Versity, Inc.
3
 *
4
 * This file may be redistributed under the terms of the
5
 * GNU Lesser General Public License.
6
 */
7
8
#include <inttypes.h>
9
10
#include "superblocks.h"
11
#include "crc32c.h"
12
13
enum {
14
  SCOUTFS_TYPE_DATA,
15
  SCOUTFS_TYPE_METADATA,
16
};
17
18
#define SCOUTFS_UUID_BYTES 16
19
20
0
#define SCOUTFS_BLOCK_SM_SHIFT 12
21
0
#define SCOUTFS_BLOCK_SM_SIZE  (1 << SCOUTFS_BLOCK_SM_SHIFT)
22
0
#define SCOUTFS_BLOCK_LG_SHIFT 16
23
0
#define SCOUTFS_BLOCK_LG_SIZE  (1 << SCOUTFS_BLOCK_LG_SHIFT)
24
25
struct scoutfs_block_header {
26
  uint32_t crc;
27
  uint32_t magic;
28
  uint64_t fsid;
29
  uint64_t seq;
30
  uint64_t blkno;
31
};
32
33
0
#define SCOUTFS_FLAG_IS_META_BDEV 0x01
34
35
struct scoutfs_super_block {
36
  struct scoutfs_block_header hdr;
37
  uint64_t id;
38
  uint64_t fmt_vers;
39
  uint64_t flags;
40
  uint8_t uuid[SCOUTFS_UUID_BYTES];
41
  /* rest omitted */
42
};
43
44
static int probe_scoutfs(blkid_probe pr, const struct blkid_idmag *mag)
45
0
{
46
0
  const struct scoutfs_super_block *sb;
47
0
  const unsigned char *buf;
48
0
  uint32_t crc;
49
50
  /* scoutfs_super_block is always in a SCOUTFS_BLOCK_SM_SIZE block */
51
0
  buf = blkid_probe_get_sb_buffer(pr, mag, SCOUTFS_BLOCK_SM_SIZE);
52
0
  if (buf == NULL)
53
0
    return errno ? -errno : 1;
54
0
  sb = (struct scoutfs_super_block *)buf;
55
56
0
  crc = crc32c(~0, (char *)buf + sizeof(sb->hdr.crc), SCOUTFS_BLOCK_SM_SIZE - sizeof(sb->hdr.crc));
57
0
  if (!blkid_probe_verify_csum(pr, crc, le32_to_cpu(sb->hdr.crc)))
58
0
    return BLKID_PROBE_NONE;
59
60
0
  blkid_probe_sprintf_version(pr, "%"PRIu64, le64_to_cpu(sb->fmt_vers));
61
0
  blkid_probe_set_uuid(pr, sb->uuid);
62
0
  blkid_probe_sprintf_value(pr, "FSID", "%016"PRIx64, le64_to_cpu(sb->hdr.fsid));
63
0
  blkid_probe_set_wiper(pr, 0, 0x10000);
64
65
0
  if (mag->hint == SCOUTFS_TYPE_METADATA) {
66
    /* meta blocksize is 64k blocks */
67
0
    blkid_probe_set_fsblocksize(pr, SCOUTFS_BLOCK_LG_SIZE);
68
0
    blkid_probe_set_block_size(pr, SCOUTFS_BLOCK_LG_SIZE);
69
70
0
    if (!(le64_to_cpu(sb->flags) & SCOUTFS_FLAG_IS_META_BDEV))
71
0
      return BLKID_PROBE_NONE;
72
0
  } else {
73
    /* data blocksize is 4k blocks */
74
0
    blkid_probe_set_fsblocksize(pr, SCOUTFS_BLOCK_SM_SIZE);
75
0
    blkid_probe_set_block_size(pr, SCOUTFS_BLOCK_SM_SIZE);
76
77
0
    if (le64_to_cpu(sb->flags) & SCOUTFS_FLAG_IS_META_BDEV)
78
0
      return BLKID_PROBE_NONE;
79
0
  }
80
81
0
  return 0;
82
0
}
83
84
/*
85
 * Scoutfs has the same magic value for the data and the meta devices,
86
 * and the superblock format used in them is identical, except for the
87
 * flag used to indicate the meta device superblock.
88
 */
89
const struct blkid_idinfo scoutfs_meta_idinfo =
90
{
91
  .name   = "scoutfs_meta",
92
  .usage    = BLKID_USAGE_FILESYSTEM,
93
  .probefunc  = probe_scoutfs,
94
  .minsz    = 0x20000,
95
  .magics   = {
96
    {
97
      .magic  = "\x8b\x42\x3c\x10",
98
      .hint         = SCOUTFS_TYPE_METADATA,
99
      .kboff  = 64,
100
      .sboff  = 4,
101
      .len    = 4,
102
    },
103
    { NULL }
104
  }
105
};
106
107
const struct blkid_idinfo scoutfs_data_idinfo =
108
{
109
  .name   = "scoutfs_data",
110
  .usage    = BLKID_USAGE_FILESYSTEM,
111
  .probefunc  = probe_scoutfs,
112
  .minsz    = 0x20000,
113
  .magics   = {
114
    {
115
      .magic  = "\x8b\x42\x3c\x10",
116
      .hint         = SCOUTFS_TYPE_DATA,
117
      .kboff  = 64,
118
      .sboff  = 4,
119
      .len    = 4,
120
    },
121
    { NULL }
122
  }
123
};