aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKetut Putu Kumajaya <ketut.kumajaya@gmail.com>2014-03-19 01:20:03 +0700
committerKetut Putu Kumajaya <ketut.kumajaya@gmail.com>2014-03-19 10:22:44 +0700
commitc2c2ab933f10ffcd4745f6dbfa9ebea99d06269a (patch)
treed93b6441e13e82e5f112911813b428ac36bb42f1
parent650530dbed28fe4c2f8f499177a6b27170acfd51 (diff)
downloadandroid_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
Backported from mainline util-linux Change-Id: I3afb543ed027786ee20c3e7c9093ff7f5af54a04
-rw-r--r--lib/blkid/Android.mk1
-rw-r--r--lib/blkid/probe.c5
-rw-r--r--lib/blkid/probe_f2fs.c126
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;
+}