Source file superblock.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
let magic = Cstruct.of_string "littlefs"
let version = (2, 0)
let name_length_max = 32l
let file_size_max = 2147483647l
let file_attribute_size_max = 1022l
type superblock = {
version_minor : Cstruct.uint16;
version_major : Cstruct.uint16;
block_size : Cstruct.uint32;
block_count : Cstruct.uint32;
name_length_max : Cstruct.uint32;
file_size_max : Cstruct.uint32;
file_attribute_size_max : Cstruct.uint32;
}
[%%cstruct
type superblock = {
version_minor : uint16_t;
version_major : uint16_t;
block_size : uint32_t;
block_count : uint32_t;
name_length_max : uint32_t;
file_size_max : uint32_t;
file_attribute_size_max : uint32_t;
} [@@little_endian]]
let parse cs =
if Cstruct.length cs < sizeof_superblock then Error (`Msg "superblock inline struct too small")
else begin
let name_length_max = get_superblock_name_length_max cs
and block_size = get_superblock_block_size cs
in
let overhead = 4
+ Tag.size
+ Tag.size
+ Tag.size + 8
+ Tag.size
in
if (Int32.to_int name_length_max) > ((Int32.to_int block_size) - overhead) then
Error (`Msg (Format.asprintf "name length max %ld is too big for block size %ld after overhead" name_length_max block_size))
else
Ok {
version_minor = get_superblock_version_minor cs;
version_major = get_superblock_version_major cs;
block_size;
block_count = get_superblock_block_count cs;
name_length_max = get_superblock_name_length_max cs;
file_size_max = get_superblock_file_size_max cs;
file_attribute_size_max = get_superblock_file_attribute_size_max cs;
}
end
let into_cstruct cs sb =
set_superblock_version_minor cs sb.version_minor;
set_superblock_version_major cs sb.version_major;
set_superblock_block_size cs sb.block_size;
set_superblock_block_count cs sb.block_count;
set_superblock_name_length_max cs sb.name_length_max;
set_superblock_file_size_max cs sb.file_size_max;
set_superblock_file_attribute_size_max cs sb.file_attribute_size_max
let to_cstruct sb =
let cs = Cstruct.create sizeof_superblock in
into_cstruct cs sb;
cs
let name =
let tag = Tag.({
valid = true;
type3 = LFS_TYPE_NAME, 0xff;
id = 0;
length = 8; })
in
(tag, magic)
let is_valid_name (tag, data) =
tag.Tag.length = 8 &&
tag.Tag.valid = true &&
tag.Tag.type3 = (Tag.LFS_TYPE_NAME, 0xff) &&
tag.Tag.id = 0 &&
Cstruct.equal magic data
let is_valid_superblock (tag, data) =
tag.Tag.valid = true &&
tag.Tag.type3 = (Tag.LFS_TYPE_STRUCT, 0x01) &&
tag.Tag.id = 0 &&
tag.Tag.length = sizeof_superblock &&
Cstruct.length data = sizeof_superblock
let inline_struct block_size block_count =
let entry = {
version_major = (fst version);
version_minor = (snd version);
block_size;
block_count;
name_length_max;
file_size_max;
file_attribute_size_max;
}
and tag = Tag.({
valid = true;
type3 = LFS_TYPE_STRUCT, 0x01;
id = 0;
length = sizeof_superblock;
})
in
(tag, to_cstruct entry)