diff options
Diffstat (limited to 'util-linux/volume_id/erofs.c')
-rw-r--r-- | util-linux/volume_id/erofs.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/util-linux/volume_id/erofs.c b/util-linux/volume_id/erofs.c new file mode 100644 index 000000000..a163a353d --- /dev/null +++ b/util-linux/volume_id/erofs.c | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * volume_id - reads filesystem label and uuid | ||
3 | * | ||
4 | * Copyright (C) 2020 Norbert Lange <nolange79@gmail.com> | ||
5 | * | ||
6 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
7 | */ | ||
8 | //config:config FEATURE_VOLUMEID_EROFS | ||
9 | //config: bool "erofs filesystem" | ||
10 | //config: default y | ||
11 | //config: depends on VOLUMEID | ||
12 | //config: help | ||
13 | //config: Erofs is a compressed readonly filesystem for Linux. | ||
14 | |||
15 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_EROFS) += erofs.o | ||
16 | |||
17 | #include "volume_id_internal.h" | ||
18 | |||
19 | #define EROFS_SUPER_MAGIC_V1 0xE0F5E1E2 | ||
20 | #define EROFS_SUPER_OFFSET 1024 | ||
21 | #define EROFS_FEATURE_COMPAT_SB_CHKSUM 0x00000001 | ||
22 | |||
23 | /* 128-byte erofs on-disk super block */ | ||
24 | struct erofs_super_block { | ||
25 | uint32_t magic; /* file system magic number */ | ||
26 | uint32_t checksum; /* crc32c(super_block) */ | ||
27 | uint32_t feature_compat; | ||
28 | uint8_t blkszbits; /* support block_size == PAGE_SIZE only */ | ||
29 | uint8_t reserved; | ||
30 | |||
31 | uint16_t root_nid; /* nid of root directory */ | ||
32 | uint64_t inos; /* total valid ino # (== f_files - f_favail) */ | ||
33 | |||
34 | uint64_t build_time; /* inode v1 time derivation */ | ||
35 | uint32_t build_time_nsec; /* inode v1 time derivation in nano scale */ | ||
36 | uint32_t blocks; /* used for statfs */ | ||
37 | uint32_t meta_blkaddr; /* start block address of metadata area */ | ||
38 | uint32_t xattr_blkaddr; /* start block address of shared xattr area */ | ||
39 | uint8_t uuid[16]; /* 128-bit uuid for volume */ | ||
40 | uint8_t volume_name[16]; /* volume name */ | ||
41 | uint32_t feature_incompat; | ||
42 | uint8_t reserved2[44]; | ||
43 | } PACKED; | ||
44 | |||
45 | int FAST_FUNC volume_id_probe_erofs(struct volume_id *id /*,uint64_t off*/) | ||
46 | { | ||
47 | struct erofs_super_block *sb; | ||
48 | |||
49 | BUILD_BUG_ON(sizeof(struct erofs_super_block) != 128); | ||
50 | |||
51 | dbg("erofs: probing at offset 0x%llx", EROFS_SUPER_OFFSET); | ||
52 | sb = volume_id_get_buffer(id, EROFS_SUPER_OFFSET, sizeof(*sb)); | ||
53 | if (!sb) | ||
54 | return -1; | ||
55 | |||
56 | if (sb->magic != cpu_to_le32(EROFS_SUPER_MAGIC_V1)) | ||
57 | return -1; | ||
58 | |||
59 | IF_FEATURE_BLKID_TYPE(id->type = "erofs"); | ||
60 | |||
61 | volume_id_set_label_string(id, sb->volume_name, | ||
62 | MIN(sizeof(sb->volume_name), VOLUME_ID_LABEL_SIZE)); | ||
63 | |||
64 | volume_id_set_uuid(id, sb->uuid, UUID_DCE); | ||
65 | |||
66 | return 0; | ||
67 | } | ||