diff options
Diffstat (limited to 'util-linux/volume_id/lfs.c')
-rw-r--r-- | util-linux/volume_id/lfs.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/util-linux/volume_id/lfs.c b/util-linux/volume_id/lfs.c new file mode 100644 index 000000000..1a2a2987f --- /dev/null +++ b/util-linux/volume_id/lfs.c | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * volume_id - reads filesystem label and uuid | ||
3 | * | ||
4 | * Copyright (C) 2018 Sven-Göran Bergh <sgb@systemaxion.se> | ||
5 | * | ||
6 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
7 | */ | ||
8 | //config:config FEATURE_VOLUMEID_LFS | ||
9 | //config: bool "LittleFS filesystem" | ||
10 | //config: default y | ||
11 | //config: depends on VOLUMEID && FEATURE_BLKID_TYPE | ||
12 | //config: help | ||
13 | //config: LittleFS is a small fail-safe filesystem designed for embedded | ||
14 | //config: systems. It has strong copy-on-write guarantees and storage on disk | ||
15 | //config: is always kept in a valid state. It also provides a form of dynamic | ||
16 | //config: wear levelling for systems that can not fit a full flash translation | ||
17 | //config: layer. | ||
18 | |||
19 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_LFS) += lfs.o | ||
20 | |||
21 | #include "volume_id_internal.h" | ||
22 | |||
23 | #define LFS_SB1_OFFSET 0x10 | ||
24 | #define LFS_MAGIC_NAME "littlefs" | ||
25 | #define LFS_MAGIC_LEN 8 | ||
26 | |||
27 | // The superblock is stored in the first metadata pair, i.e the first two blocks. | ||
28 | struct lfs_super_block { // A block in a metadata pair | ||
29 | // /* 0x00 */ uint32_t rev_count; // Revision count | ||
30 | // /* 0x04 */ uint32_t dir_size; // Directory size | ||
31 | // /* 0x08 */ uint64_t tail_ptr; // Tail pointer | ||
32 | /* 0x10 */ uint8_t entry_type; // Entry type | ||
33 | /* 0x11 */ uint8_t entry_len; // Entry length | ||
34 | /* 0x12 */ uint8_t att_len; // Attribute length | ||
35 | /* 0x13 */ uint8_t name_len; // Name length | ||
36 | /* 0x14 */ uint64_t root_dir; // Root directory | ||
37 | /* 0x1C */ uint32_t block_size; // Block size | ||
38 | /* 0x20 */ uint32_t block_count; // Block count | ||
39 | /* 0x24 */ uint16_t ver_major; // Version major | ||
40 | /* 0x26 */ uint16_t ver_minor; // Version minor | ||
41 | /* 0x28 */ uint8_t magic[LFS_MAGIC_LEN]; // Magic string "littlefs" | ||
42 | // /* 0x30 */ uint32_t crc; // CRC-32 checksum | ||
43 | } PACKED; | ||
44 | |||
45 | int FAST_FUNC volume_id_probe_lfs(struct volume_id *id /*,uint64_t off*/) | ||
46 | { | ||
47 | struct lfs_super_block *sb; | ||
48 | |||
49 | // Go for primary super block (ignore second sb) | ||
50 | dbg("lfs: probing at offset 0x%x", LFS_SB1_OFFSET); | ||
51 | sb = volume_id_get_buffer(id, LFS_SB1_OFFSET, sizeof(*sb)); | ||
52 | |||
53 | if (!sb) | ||
54 | return -1; | ||
55 | |||
56 | if (memcmp(sb->magic, LFS_MAGIC_NAME, LFS_MAGIC_LEN) != 0) | ||
57 | return -1; | ||
58 | |||
59 | IF_FEATURE_BLKID_TYPE(id->type = LFS_MAGIC_NAME); | ||
60 | |||
61 | return 0; | ||
62 | } | ||