1 /*
2 * Copyright (C) 2020 Western Digital Corporation or its affiliates.
3 *
4 * This file may be redistributed under the terms of the
5 * GNU Lesser General Public License
6 */
7 #include <stddef.h>
8 #include <string.h>
9
10 #include "superblocks.h"
11 #include "crc32.h"
12
13 #define ZONEFS_MAGIC "SFOZ" /* 0x5a4f4653 'Z' 'O' 'F' 'S' */
14 #define ZONEFS_MAGIC_SIZE 4
15 #define ZONEFS_MAGIC_OFST 0
16 #define ZONEFS_UUID_SIZE 16
17 #define ZONEFS_LABEL_SIZE 32
18 #define ZONEFS_SB_OFST 0
19
20 #define ZONEFS_BLOCK_SIZE 4096U
21
22 /* All in little-endian */
23 struct zonefs_super {
24
25 /* Magic number */
26 int32_t s_magic;
27
28 /* Checksum */
29 int32_t s_crc;
30
31 /* Volume label */
32 char s_label[ZONEFS_LABEL_SIZE];
33
34 /* 128-bit uuid */
35 uint8_t s_uuid[ZONEFS_UUID_SIZE];
36
37 /* Features */
38 int64_t s_features;
39
40 /* UID/GID to use for files */
41 int32_t s_uid;
42 int32_t s_gid;
43
44 /* File permissions */
45 int32_t s_perm;
46
47 /* Padding to 4096 bytes */
48 uint8_t s_reserved[4020];
49
50 } __attribute__ ((packed));
51
52 static int zonefs_verify_csum(blkid_probe pr, struct zonefs_super *sb)
53 {
54 uint32_t expected = le32_to_cpu(sb->s_crc);
55 sb->s_crc = 0;
56 uint32_t crc = ul_crc32(~0LL, (unsigned char *) sb, sizeof(*sb));
57 return blkid_probe_verify_csum(pr, crc, expected);
58 }
59
60 static int probe_zonefs(blkid_probe pr,
61 const struct blkid_idmag *mag __attribute__((__unused__)))
62 {
63 struct zonefs_super *sb;
64
65 sb = (struct zonefs_super *)
66 blkid_probe_get_buffer(pr, ZONEFS_SB_OFST,
67 sizeof(struct zonefs_super));
68 if (!sb)
69 return errno ? -errno : 1;
70
71 if (!zonefs_verify_csum(pr, sb))
72 return 1;
73
74 if (sb->s_label[0])
75 blkid_probe_set_label(pr, (unsigned char *) sb->s_label,
76 sizeof(sb->s_label));
77
78 blkid_probe_set_uuid(pr, sb->s_uuid);
79 blkid_probe_set_fsblocksize(pr, ZONEFS_BLOCK_SIZE);
80 blkid_probe_set_block_size(pr, ZONEFS_BLOCK_SIZE);
81
82 return 0;
83 }
84
85 const struct blkid_idinfo zonefs_idinfo =
86 {
87 .name = "zonefs",
88 .usage = BLKID_USAGE_FILESYSTEM,
89 .probefunc = probe_zonefs,
90 .magics =
91 {
92 {
93 .magic = (char *)ZONEFS_MAGIC,
94 .len = ZONEFS_MAGIC_SIZE,
95 .kboff = ZONEFS_SB_OFST,
96 .sboff = ZONEFS_MAGIC_OFST,
97 },
98 { NULL }
99 }
100 };