bc: convert to "G trick" - this returns bc to zero bss increase
[oweals/busybox.git] / util-linux / volume_id / lfs.c
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 }