[3621] | 1 | /*
|
---|
| 2 | * volume_id - reads filesystem label and uuid
|
---|
| 3 | *
|
---|
| 4 | * Copyright (C) 2012 S-G Bergh <sgb@systemasis.org>
|
---|
| 5 | *
|
---|
| 6 | * Licensed under GPLv2, see file LICENSE in this source tree.
|
---|
| 7 | */
|
---|
| 8 |
|
---|
| 9 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_F2FS) += f2fs.o
|
---|
| 10 |
|
---|
| 11 | //config:
|
---|
| 12 | //config:config FEATURE_VOLUMEID_F2FS
|
---|
| 13 | //config: bool "f2fs filesystem"
|
---|
| 14 | //config: default y
|
---|
| 15 | //config: depends on VOLUMEID
|
---|
| 16 | //config: help
|
---|
| 17 | //config: F2FS (aka Flash-Friendly File System) is a log-structured file system,
|
---|
| 18 | //config: which is adapted to newer forms of storage. F2FS also remedies some
|
---|
| 19 | //config: known issues of the older log structured file systems, such as high
|
---|
| 20 | //config: cleaning overhead.
|
---|
| 21 | //config:
|
---|
| 22 |
|
---|
| 23 | #include "volume_id_internal.h"
|
---|
| 24 |
|
---|
| 25 | #define F2FS_MAGIC 0xF2F52010 // F2FS Magic Number
|
---|
| 26 | #define F2FS_UUID_SIZE 16
|
---|
| 27 | #define F2FS_LABEL_SIZE 512
|
---|
| 28 | #define F2FS_LABEL_BYTES 1024
|
---|
| 29 | #define F2FS_SB1_OFFSET 0x400 // offset for 1:st super block
|
---|
| 30 | /*
|
---|
| 31 | #define F2FS_SB2_OFFSET 0x1400 // offset for 2:nd super block
|
---|
| 32 | */
|
---|
| 33 |
|
---|
| 34 | struct f2fs_super_block { // According to version 1.1
|
---|
| 35 | /* 0x00 */ uint32_t magic; // Magic Number
|
---|
| 36 | /* 0x04 */ uint16_t major_ver; // Major Version
|
---|
| 37 | /* 0x06 */ uint16_t minor_ver; // Minor Version
|
---|
| 38 | /* 0x08 */ uint32_t log_sectorsize; // log2 sector size in bytes
|
---|
| 39 | /* 0x0C */ uint32_t log_sectors_per_block; // log2 # of sectors per block
|
---|
| 40 | /* 0x10 */ uint32_t log_blocksize; // log2 block size in bytes
|
---|
| 41 | /* 0x14 */ uint32_t log_blocks_per_seg; // log2 # of blocks per segment
|
---|
| 42 | /* 0x18 */ uint32_t segs_per_sec; // # of segments per section
|
---|
| 43 | /* 0x1C */ uint32_t secs_per_zone; // # of sections per zone
|
---|
| 44 | /* 0x20 */ uint32_t checksum_offset; // checksum offset inside super block
|
---|
| 45 | /* 0x24 */ uint64_t block_count; // total # of user blocks
|
---|
| 46 | /* 0x2C */ uint32_t section_count; // total # of sections
|
---|
| 47 | /* 0x30 */ uint32_t segment_count; // total # of segments
|
---|
| 48 | /* 0x34 */ uint32_t segment_count_ckpt; // # of segments for checkpoint
|
---|
| 49 | /* 0x38 */ uint32_t segment_count_sit; // # of segments for SIT
|
---|
| 50 | /* 0x3C */ uint32_t segment_count_nat; // # of segments for NAT
|
---|
| 51 | /* 0x40 */ uint32_t segment_count_ssa; // # of segments for SSA
|
---|
| 52 | /* 0x44 */ uint32_t segment_count_main; // # of segments for main area
|
---|
| 53 | /* 0x48 */ uint32_t segment0_blkaddr; // start block address of segment 0
|
---|
| 54 | /* 0x4C */ uint32_t cp_blkaddr; // start block address of checkpoint
|
---|
| 55 | /* 0x50 */ uint32_t sit_blkaddr; // start block address of SIT
|
---|
| 56 | /* 0x54 */ uint32_t nat_blkaddr; // start block address of NAT
|
---|
| 57 | /* 0x58 */ uint32_t ssa_blkaddr; // start block address of SSA
|
---|
| 58 | /* 0x5C */ uint32_t main_blkaddr; // start block address of main area
|
---|
| 59 | /* 0x60 */ uint32_t root_ino; // root inode number
|
---|
| 60 | /* 0x64 */ uint32_t node_ino; // node inode number
|
---|
| 61 | /* 0x68 */ uint32_t meta_ino; // meta inode number
|
---|
| 62 | /* 0x6C */ uint8_t uuid[F2FS_UUID_SIZE]; // 128-bit uuid for volume
|
---|
| 63 | /* 0x7C */ uint16_t volume_name[F2FS_LABEL_SIZE]; // volume name
|
---|
| 64 | // /* 0x47C */ uint32_t extension_count; // # of extensions below
|
---|
| 65 | // /* 0x480 */ uint8_t extension_list[64][8]; // extension array
|
---|
| 66 | } PACKED;
|
---|
| 67 |
|
---|
| 68 |
|
---|
| 69 | int FAST_FUNC volume_id_probe_f2fs(struct volume_id *id /*,uint64_t off*/)
|
---|
| 70 | {
|
---|
| 71 | struct f2fs_super_block *sb;
|
---|
| 72 |
|
---|
| 73 | // Go for primary super block (ignore second sb)
|
---|
| 74 | dbg("f2fs: probing at offset 0x%x", F2FS_SB1_OFFSET);
|
---|
| 75 | sb = volume_id_get_buffer(id, F2FS_SB1_OFFSET, sizeof(*sb));
|
---|
| 76 |
|
---|
| 77 | if (!sb)
|
---|
| 78 | return -1;
|
---|
| 79 |
|
---|
| 80 | if (sb->magic != cpu_to_le32(F2FS_MAGIC))
|
---|
| 81 | return -1;
|
---|
| 82 |
|
---|
| 83 | IF_FEATURE_BLKID_TYPE(id->type = "f2fs");
|
---|
| 84 |
|
---|
| 85 | // For version 1.0 we don't know sb structure and can't set label/uuid
|
---|
| 86 | if (sb->major_ver == cpu_to_le16(1) && sb->minor_ver == cpu_to_le16(0))
|
---|
| 87 | return 0;
|
---|
| 88 |
|
---|
| 89 | volume_id_set_label_unicode16(id, (uint8_t *)sb->volume_name,
|
---|
| 90 | LE, MIN(F2FS_LABEL_BYTES, VOLUME_ID_LABEL_SIZE));
|
---|
| 91 |
|
---|
| 92 | volume_id_set_uuid(id, sb->uuid, UUID_DCE);
|
---|
| 93 |
|
---|
| 94 | return 0;
|
---|
| 95 | }
|
---|