Android-x86
Fork
Donation

  • R/O
  • HTTP
  • SSH
  • HTTPS

external-e2fsprogs: 提交

external/e2fsprogs


Commit MetaInfo

修订版e7d5f28661a3452f8470efe65c9e091e79a3bc6c (tree)
时间2014-03-27 13:28:30
作者Steve Kondik <shade@chem...>
CommiterChih-Wei Huang

Log Message

blkid: Add support for probing exFAT

  • e2fsprogs can't currently detect exFAT filesystems.
  • Apply patch from GoogleTV to add support.

Change-Id: Ib08bdb1d13e995d133a62539e3bfa0e3a22eeead

更改概述

差异

--- a/lib/blkid/Android.mk
+++ b/lib/blkid/Android.mk
@@ -8,6 +8,7 @@ libext2_blkid_src_files := \
88 getsize.c \
99 llseek.c \
1010 probe.c \
11+ probe_exfat.c \
1112 read.c \
1213 resolve.c \
1314 save.c \
--- a/lib/blkid/probe.c
+++ b/lib/blkid/probe.c
@@ -36,6 +36,10 @@
3636 #include "uuid/uuid.h"
3737 #include "probe.h"
3838
39+extern int probe_exfat(struct blkid_probe *probe,
40+ struct blkid_magic *id __BLKID_ATTR((unused)),
41+ unsigned char *buf);
42+
3943 static int figure_label_len(const unsigned char *label, int len)
4044 {
4145 const unsigned char *end = label + len - 1;
@@ -87,6 +91,11 @@ static unsigned char *get_buffer(struct blkid_probe *pr,
8791 }
8892 }
8993
94+unsigned char *blkid_probe_get_buffer(struct blkid_probe *pr,
95+ blkid_loff_t off, size_t len)
96+{
97+ return get_buffer(pr, off, len);
98+}
9099
91100 /*
92101 * This is a special case code to check for an MDRAID device. We do
@@ -1392,6 +1401,7 @@ static struct blkid_magic type_array[] = {
13921401 /* type kboff sboff len magic probe */
13931402 { "oracleasm", 0, 32, 8, "ORCLDISK", probe_oracleasm },
13941403 { "ntfs", 0, 3, 8, "NTFS ", probe_ntfs },
1404+ { "exfat", 0, 3, 8, "EXFAT ", probe_exfat },
13951405 { "jbd", 1, 0x38, 2, "\123\357", probe_jbd },
13961406 { "ext4dev", 1, 0x38, 2, "\123\357", probe_ext4dev },
13971407 { "ext4", 1, 0x38, 2, "\123\357", probe_ext4 },
--- a/lib/blkid/probe.h
+++ b/lib/blkid/probe.h
@@ -792,7 +792,8 @@ _INLINE_ __u64 blkid_swab64(__u64 val)
792792 }
793793 #endif
794794
795-
795+unsigned char *blkid_probe_get_buffer(struct blkid_probe *pr,
796+ blkid_loff_t off, size_t len);
796797
797798 #ifdef WORDS_BIGENDIAN
798799 #define blkid_le16(x) blkid_swab16(x)
--- /dev/null
+++ b/lib/blkid/probe_exfat.c
@@ -0,0 +1,179 @@
1+/*
2+ * Copyright (C) 2010 Andrew Nayenko <resver@gmail.com>
3+ *
4+ * This file may be redistributed under the terms of the
5+ * GNU Lesser General Public License.
6+ */
7+
8+#include <stdio.h>
9+#include <string.h>
10+#include <math.h>
11+#include "blkidP.h"
12+#include "probe.h"
13+
14+#define le32_to_cpu(x) blkid_le32(x)
15+
16+typedef __u8 uint8_t;
17+typedef __u16 uint16_t;
18+typedef __u32 uint32_t;
19+typedef __u64 uint64_t;
20+
21+typedef struct blkid_probe* blkid_probe;
22+
23+struct exfat_super_block {
24+ __u8 jump[3];
25+ __u8 oem_name[8];
26+ __u8 __unused1[53];
27+ __u64 block_start;
28+ __u64 block_count;
29+ __u32 fat_block_start;
30+ __u32 fat_block_count;
31+ __u32 cluster_block_start;
32+ __u32 cluster_count;
33+ __u32 rootdir_cluster;
34+ __u8 volume_serial[4];
35+ struct {
36+ __u8 minor;
37+ __u8 major;
38+ } version;
39+ __u16 volume_state;
40+ __u8 block_bits;
41+ __u8 bpc_bits;
42+ __u8 fat_count;
43+ __u8 drive_no;
44+ __u8 allocated_percent;
45+} __attribute__((__packed__));
46+
47+struct exfat_entry_label {
48+ __u8 type;
49+ __u8 length;
50+ __u8 name[30];
51+} __attribute__((__packed__));
52+
53+#define BLOCK_SIZE(sb) (1 << (sb)->block_bits)
54+#define CLUSTER_SIZE(sb) (BLOCK_SIZE(sb) << (sb)->bpc_bits)
55+#define EXFAT_FIRST_DATA_CLUSTER 2
56+#define EXFAT_LAST_DATA_CLUSTER 0xffffff6
57+#define EXFAT_ENTRY_SIZE 32
58+
59+#define EXFAT_ENTRY_EOD 0x00
60+#define EXFAT_ENTRY_LABEL 0x83
61+
62+static blkid_loff_t block_to_offset(const struct exfat_super_block *sb,
63+ blkid_loff_t block)
64+{
65+ return (blkid_loff_t) block << sb->block_bits;
66+}
67+
68+static blkid_loff_t cluster_to_block(const struct exfat_super_block *sb,
69+ uint32_t cluster)
70+{
71+ return le32_to_cpu(sb->cluster_block_start) +
72+ ((blkid_loff_t) (cluster - EXFAT_FIRST_DATA_CLUSTER)
73+ << sb->bpc_bits);
74+}
75+
76+static blkid_loff_t cluster_to_offset(const struct exfat_super_block *sb,
77+ uint32_t cluster)
78+{
79+ return block_to_offset(sb, cluster_to_block(sb, cluster));
80+}
81+
82+static uint32_t next_cluster(blkid_probe pr,
83+ const struct exfat_super_block *sb, uint32_t cluster)
84+{
85+ uint32_t *next;
86+ blkid_loff_t fat_offset;
87+
88+ fat_offset = block_to_offset(sb, le32_to_cpu(sb->fat_block_start))
89+ + (blkid_loff_t) cluster * sizeof(cluster);
90+ next = (uint32_t *) blkid_probe_get_buffer(pr, fat_offset,
91+ sizeof(uint32_t));
92+ if (!next)
93+ return 0;
94+ return le32_to_cpu(*next);
95+}
96+
97+static struct exfat_entry_label *find_label(blkid_probe pr,
98+ const struct exfat_super_block *sb)
99+{
100+ uint32_t cluster = le32_to_cpu(sb->rootdir_cluster);
101+ blkid_loff_t offset = cluster_to_offset(sb, cluster);
102+ uint8_t *entry;
103+
104+ for (;;) {
105+ entry = (uint8_t *) blkid_probe_get_buffer(pr, offset,
106+ EXFAT_ENTRY_SIZE);
107+ if (!entry)
108+ return NULL;
109+ if (entry[0] == EXFAT_ENTRY_EOD)
110+ return NULL;
111+ if (entry[0] == EXFAT_ENTRY_LABEL)
112+ return (struct exfat_entry_label *) entry;
113+ offset += EXFAT_ENTRY_SIZE;
114+ if (offset % CLUSTER_SIZE(sb) == 0) {
115+ cluster = next_cluster(pr, sb, cluster);
116+ if (cluster < EXFAT_FIRST_DATA_CLUSTER)
117+ return NULL;
118+ if (cluster > EXFAT_LAST_DATA_CLUSTER)
119+ return NULL;
120+ offset = cluster_to_offset(sb, cluster);
121+ }
122+ }
123+}
124+
125+static void unicode_16le_to_utf8(char *s, int out_len,
126+ const unsigned char *buf, int in_len)
127+{
128+ int i, j;
129+ unsigned int c;
130+ unsigned char *str = (unsigned char *)s;
131+
132+ for (i = j = 0; i + 2 <= in_len; i += 2) {
133+ c = (buf[i+1] << 8) | buf[i];
134+ if (c == 0) {
135+ str[j] = '\0';
136+ break;
137+ } else if (c < 0x80) {
138+ if (j+1 >= out_len)
139+ break;
140+ str[j++] = (unsigned char) c;
141+ } else if (c < 0x800) {
142+ if (j+2 >= out_len)
143+ break;
144+ str[j++] = (unsigned char) (0xc0 | (c >> 6));
145+ str[j++] = (unsigned char) (0x80 | (c & 0x3f));
146+ } else {
147+ if (j+3 >= out_len)
148+ break;
149+ str[j++] = (unsigned char) (0xe0 | (c >> 12));
150+ str[j++] = (unsigned char) (0x80 | ((c >> 6) & 0x3f));
151+ str[j++] = (unsigned char) (0x80 | (c & 0x3f));
152+ }
153+ }
154+ str[j] = '\0';
155+}
156+
157+int probe_exfat(struct blkid_probe *probe,
158+ struct blkid_magic *id __BLKID_ATTR((unused)),
159+ unsigned char *buf)
160+{
161+ struct exfat_super_block *sb;
162+ struct exfat_entry_label *label;
163+ char serno[10];
164+
165+ sb = (struct exfat_super_block *) buf;
166+
167+ sprintf(serno, "%02X%02X-%02X%02X",
168+ sb->volume_serial[3], sb->volume_serial[2],
169+ sb->volume_serial[1], sb->volume_serial[0]);
170+
171+ blkid_set_tag(probe->dev, "UUID", serno, sizeof(serno)-1);
172+ label = find_label(probe, sb);
173+ if (label) {
174+ char utf8_label[128];
175+ unicode_16le_to_utf8(utf8_label, sizeof(utf8_label), label->name, label->length * 2);
176+ blkid_set_tag(probe->dev, "LABEL", utf8_label, 0);
177+ }
178+ return 0;
179+}
Show on old repository browser