diff options
author | Ketut Putu Kumajaya <ketut.kumajaya@gmail.com> | 2014-03-19 01:20:03 +0700 |
---|---|---|
committer | Ketut Putu Kumajaya <ketut.kumajaya@gmail.com> | 2014-03-19 10:22:44 +0700 |
commit | c2c2ab933f10ffcd4745f6dbfa9ebea99d06269a (patch) | |
tree | d93b6441e13e82e5f112911813b428ac36bb42f1 | |
parent | 650530dbed28fe4c2f8f499177a6b27170acfd51 (diff) | |
download | android_external_e2fsprogs-shipping/cm-11.0.tar.gz android_external_e2fsprogs-shipping/cm-11.0.tar.bz2 android_external_e2fsprogs-shipping/cm-11.0.zip |
e2fsprogs: blkid: Add Flash-Friendly File System (f2fs) supportcm-11.0-XNPH05Q-tomato-9828f8e9cccm-11.0-XNPH05Q-bacon-5229c4ef56stable/cm-11.0-XNG3Cstable/cm-11.0-XNG2Sstable/cm-11.0-XNF9Xstable/cm-11.0-XNF8Ystable/cm-11.0shipping/cm-11.0
Backported from mainline util-linux
Change-Id: I3afb543ed027786ee20c3e7c9093ff7f5af54a04
-rw-r--r-- | lib/blkid/Android.mk | 1 | ||||
-rw-r--r-- | lib/blkid/probe.c | 5 | ||||
-rw-r--r-- | lib/blkid/probe_f2fs.c | 126 |
3 files changed, 132 insertions, 0 deletions
diff --git a/lib/blkid/Android.mk b/lib/blkid/Android.mk index 209da822..2aeb375c 100644 --- a/lib/blkid/Android.mk +++ b/lib/blkid/Android.mk @@ -9,6 +9,7 @@ libext2_blkid_src_files := \ llseek.c \ probe.c \ probe_exfat.c \ + probe_f2fs.c \ read.c \ resolve.c \ save.c \ diff --git a/lib/blkid/probe.c b/lib/blkid/probe.c index cd8ada63..cdeea5d3 100644 --- a/lib/blkid/probe.c +++ b/lib/blkid/probe.c @@ -40,6 +40,10 @@ extern int probe_exfat(struct blkid_probe *probe, struct blkid_magic *id __BLKID_ATTR((unused)), unsigned char *buf); +extern int probe_f2fs(struct blkid_probe *probe, + struct blkid_magic *id __BLKID_ATTR((unused)), + unsigned char *buf); + static int figure_label_len(const unsigned char *label, int len) { const unsigned char *end = label + len - 1; @@ -1492,6 +1496,7 @@ static struct blkid_magic type_array[] = { { "lvm2pv", 1, 0x018, 8, "LVM2 001", probe_lvm2 }, { "lvm2pv", 1, 0x218, 8, "LVM2 001", probe_lvm2 }, { "btrfs", 64, 0x40, 8, "_BHRfS_M", probe_btrfs }, + { "f2fs", 1, 0, 4, "\x10\x20\xF5\xF2", probe_f2fs }, { NULL, 0, 0, 0, NULL, NULL } }; diff --git a/lib/blkid/probe_f2fs.c b/lib/blkid/probe_f2fs.c new file mode 100644 index 00000000..9cfc64d9 --- /dev/null +++ b/lib/blkid/probe_f2fs.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2013 Alejandro Martinez Ruiz <alex@nowcomputing.com> + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License + * + * Initial Android port + * March 2014 Ketut P. Kumajaya <ketut.kumajaya@gmail.com> + */ + +#include <stddef.h> +#include <string.h> + +#include "blkidP.h" +#include "uuid/uuid.h" +#include "probe.h" + +#define le16_to_cpu(x) blkid_le16(x) + +typedef __u8 uint8_t; +typedef __u16 uint16_t; +typedef __u32 uint32_t; +typedef __u64 uint64_t; + +typedef struct blkid_probe* blkid_probe; + +#define F2FS_UUID_SIZE 16 +#define F2FS_LABEL_SIZE 512 + +struct f2fs_super_block { /* According to version 1.1 */ +/* 0x00 */ __u32 magic; /* Magic Number */ +/* 0x04 */ __u16 major_ver; /* Major Version */ +/* 0x06 */ __u16 minor_ver; /* Minor Version */ +/* 0x08 */ __u32 log_sectorsize; /* log2 sector size in bytes */ +/* 0x0C */ __u32 log_sectors_per_block; /* log2 # of sectors per block */ +/* 0x10 */ __u32 log_blocksize; /* log2 block size in bytes */ +/* 0x14 */ __u32 log_blocks_per_seg; /* log2 # of blocks per segment */ +/* 0x18 */ __u32 segs_per_sec; /* # of segments per section */ +/* 0x1C */ __u32 secs_per_zone; /* # of sections per zone */ +/* 0x20 */ __u32 checksum_offset; /* checksum offset inside super block */ +/* 0x24 */ __u64 block_count; /* total # of user blocks */ +/* 0x2C */ __u32 section_count; /* total # of sections */ +/* 0x30 */ __u32 segment_count; /* total # of segments */ +/* 0x34 */ __u32 segment_count_ckpt; /* # of segments for checkpoint */ +/* 0x38 */ __u32 segment_count_sit; /* # of segments for SIT */ +/* 0x3C */ __u32 segment_count_nat; /* # of segments for NAT */ +/* 0x40 */ __u32 segment_count_ssa; /* # of segments for SSA */ +/* 0x44 */ __u32 segment_count_main; /* # of segments for main area */ +/* 0x48 */ __u32 segment0_blkaddr; /* start block address of segment 0 */ +/* 0x4C */ __u32 cp_blkaddr; /* start block address of checkpoint */ +/* 0x50 */ __u32 sit_blkaddr; /* start block address of SIT */ +/* 0x54 */ __u32 nat_blkaddr; /* start block address of NAT */ +/* 0x58 */ __u32 ssa_blkaddr; /* start block address of SSA */ +/* 0x5C */ __u32 main_blkaddr; /* start block address of main area */ +/* 0x60 */ __u32 root_ino; /* root inode number */ +/* 0x64 */ __u32 node_ino; /* node inode number */ +/* 0x68 */ __u32 meta_ino; /* meta inode number */ +/* 0x6C */ __u8 uuid[F2FS_UUID_SIZE]; /* 128-bit uuid for volume */ +/* 0x7C */ __u16 volume_name[F2FS_LABEL_SIZE]; /* volume name */ +#if 0 +/* 0x47C */ __u32 extension_count; /* # of extensions below */ +/* 0x480 */ __u8 extension_list[64][8]; /* extension array */ +#endif +} __attribute__((packed)); + +static void unicode_16le_to_utf8(unsigned char *str, int out_len, + const unsigned char *buf, int in_len) +{ + int i, j; + unsigned int c; + + for (i = j = 0; i + 2 <= in_len; i += 2) { + c = (buf[i+1] << 8) | buf[i]; + if (c == 0) { + str[j] = '\0'; + break; + } else if (c < 0x80) { + if (j+1 >= out_len) + break; + str[j++] = (unsigned char) c; + } else if (c < 0x800) { + if (j+2 >= out_len) + break; + str[j++] = (unsigned char) (0xc0 | (c >> 6)); + str[j++] = (unsigned char) (0x80 | (c & 0x3f)); + } else { + if (j+3 >= out_len) + break; + str[j++] = (unsigned char) (0xe0 | (c >> 12)); + str[j++] = (unsigned char) (0x80 | ((c >> 6) & 0x3f)); + str[j++] = (unsigned char) (0x80 | (c & 0x3f)); + } + } + str[j] = '\0'; +} + +int probe_f2fs(struct blkid_probe *probe, + struct blkid_magic *id __BLKID_ATTR((unused)), + unsigned char *buf) +{ + struct f2fs_super_block *sb; + uint16_t major, minor; + char uuid_str[37]; + + sb = (struct f2fs_super_block *) buf; + if (!sb) + return -1; + + major = le16_to_cpu(sb->major_ver); + minor = le16_to_cpu(sb->minor_ver); + + /* For version 1.0 we cannot know the correct sb structure */ + if (major == 1 && minor == 0) + return 0; + + if (*((unsigned char *) sb->volume_name)) { + unsigned char utf8_label[512]; + unicode_16le_to_utf8(utf8_label, sizeof(utf8_label), + (unsigned char *) sb->volume_name, sizeof(sb->volume_name)); + blkid_set_tag(probe->dev, "LABEL", utf8_label, 0); + } + + uuid_unparse(sb->uuid, uuid_str); + blkid_set_tag(probe->dev, "UUID", uuid_str, sizeof(uuid_str)); + return 0; +} |