赞
踩
最近客户反馈一个问题,就是Android
系统的机顶盒插上exfat
格式的U盘后,获取不到UUID
这个信息。
/system/vold/
中已经添加对exfat
格式U
盘的支持,并且通过df
命令能够看到U
盘已经挂载上,但是执行blkid
时,并未显示exfat
格式U
盘信息。
blkid /dev/block/sda1
命令(sda1
为U
盘挂载点),若U
盘格式为vfat
的,则能够正常显示,若U
盘格式为exfat
的,则不能显示。blkid
命令不健全导致的,可以补充一部分代码,让其能够显示出来。external/e2fsprogs/lib/blkid
路径下。e2fsprogs
是一个Ext2
(及Ext3/4
)文件系统工具(Ext2Filesystems Utilities
),它包含了诸如创建、修复、配置、调试ext2
文件系统等的标准工具。e2fsprogs
是开放源代码软件 ,遵从GPLv2
或LGPLv2
。e2fsprogs
的开源代码,里面已经添加对exfat
的相应支持,我们可以在这个里面搜寻相应的修改同步过来。probe.c
和probe.h
。下面是针对exfat
格式的设备修改的,代码如下:
From 05cf6cbb92bf6d65ef0480053ddcc4a625f0e86b Mon Sep 17 00:00:00 2001 From: Amosstan Date: Tue, 6 Jul 2021 16:02:38 +0800 Subject: [PATCH] aaa --- external/e2fsprogs/lib/blkid/probe.c | 131 +++++++++++++++++++++++++++ external/e2fsprogs/lib/blkid/probe.h | 41 +++++++++ 2 files changed, 172 insertions(+) diff --git a/external/e2fsprogs/lib/blkid/probe.c b/external/e2fsprogs/lib/blkid/probe.c index 1867129..36f5ca3 100644 --- a/external/e2fsprogs/lib/blkid/probe.c +++ b/external/e2fsprogs/lib/blkid/probe.c @@ -1158,6 +1158,38 @@ static void unicode_16be_to_utf8(unsigned char *str, int out_len, str[j] = '\0'; } +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'; +} + + static int probe_hfs(struct blkid_probe *probe __BLKID_ATTR((unused)), struct blkid_magic *id __BLKID_ATTR((unused)), unsigned char *buf) @@ -1383,6 +1415,104 @@ static int probe_btrfs(struct blkid_probe *probe, set_uuid(probe->dev, bs->fsid, 0); return 0; } + +static uint64_t exfat_block_to_offset(const struct exfat_super_block *sb, + uint64_t block) +{ + return block << sb->block_bits; +} + +static uint64_t exfat_cluster_to_block(const struct exfat_super_block *sb, + uint32_t cluster) +{ + return sb->cluster_block_start + + ((uint64_t)(cluster - EXFAT_FIRST_DATA_CLUSTER) << sb->bpc_bits); +} + +static uint64_t exfat_cluster_to_offset(const struct exfat_super_block *sb, + uint32_t cluster) +{ + return exfat_block_to_offset(sb, exfat_cluster_to_block(sb, cluster)); +} + +static uint32_t exfat_next_cluster(struct blkid_probe *probe, + const struct exfat_super_block *sb, + uint32_t cluster) +{ + uint32_t *next; + uint64_t offset; + + offset = exfat_block_to_offset(sb, sb->fat_block_start) + + (uint64_t) cluster * sizeof (cluster); + next = (uint32_t *)get_buffer(probe, offset, sizeof (uint32_t)); + + return next ? *next : 0; +} + +static struct exfat_entry_label *find_exfat_entry_label( + struct blkid_probe *probe, const struct exfat_super_block *sb) +{ + uint32_t cluster = sb->rootdir_cluster; + uint64_t offset = exfat_cluster_to_offset(sb, cluster); + uint8_t *entry; + const size_t max_iter = 10000; + size_t i = 0; + + for (; i < max_iter; ++i) { + entry = (uint8_t *)get_buffer(probe, offset, EXFAT_ENTRY_SIZE); + if (!entry) + return NULL; + if (entry[0] == EXFAT_ENTRY_EOD) + return NULL; + if (entry[0] == EXFAT_ENTRY_LABEL) + return (struct exfat_entry_label*) entry; + + offset += EXFAT_ENTRY_SIZE; + if (offset % CLUSTER_SIZE(sb) == 0) { + cluster = exfat_next_cluster(probe, sb, cluster); + if (cluster < EXFAT_FIRST_DATA_CLUSTER) + return NULL; + if (cluster > EXFAT_LAST_DATA_CLUSTER) + return NULL; + offset = exfat_cluster_to_offset(sb, cluster); + } + } + + return NULL; +} + +static int probe_exfat(struct blkid_probe *probe, + struct blkid_magic *id __BLKID_ATTR((unused)), + unsigned char *buf) +{ + struct exfat_super_block *sb; + struct exfat_entry_label *label; + char uuid[40]; + + sb = (struct exfat_super_block *)buf; + if (!sb || CLUSTER_SIZE(sb) == 0) { + DBG(DEBUG_PROBE, printf("bad exfat superblock.\n")); + return errno ? - errno : 1; + } + + label = find_exfat_entry_label(probe, sb); + if (label) { + unsigned char utf8_label[128]; + unicode_16le_to_utf8(utf8_label, sizeof(utf8_label), label->name, label->length * 2); + blkid_set_tag(probe->dev, "LABEL", (char *) utf8_label, 0); + } else { + blkid_set_tag(probe->dev, "LABEL", "disk", 4); + } + + memset(uuid, 0, sizeof (uuid)); + snprintf(uuid, sizeof (uuid), "%02hhX%02hhX-%02hhX%02hhX", + sb->volume_serial[3], sb->volume_serial[2], + sb->volume_serial[1], sb->volume_serial[0]); + blkid_set_tag(probe->dev, "UUID", uuid, strlen(uuid)); + + return 0; +} + /* * Various filesystem magics that we can check for. Note that kboff and * sboff are in kilobytes and bytes respectively. All magics are in @@ -1482,6 +1612,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 }, + { "exfat", 0, 3, 8, "EXFAT ", probe_exfat }, { NULL, 0, 0, 0, NULL, NULL } }; diff --git a/external/e2fsprogs/lib/blkid/probe.h b/external/e2fsprogs/lib/blkid/probe.h index 37fc9c0..2c6acea 100644 --- a/external/e2fsprogs/lib/blkid/probe.h +++ b/external/e2fsprogs/lib/blkid/probe.h @@ -14,6 +14,8 @@ #ifndef _BLKID_PROBE_H #define _BLKID_PROBE_H +#include <stdint.h> + #include <blkid/blkid_types.h> struct blkid_magic; @@ -725,6 +727,45 @@ struct btrfs_super_block { __u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE]; } __attribute__ ((__packed__)); +struct exfat_super_block { + uint8_t jump[3]; + uint8_t oem_name[8]; + uint8_t __unused1[53]; + uint64_t block_start; + uint64_t block_count; + uint32_t fat_block_start; + uint32_t fat_block_count; + uint32_t cluster_block_start; + uint32_t cluster_count; + uint32_t rootdir_cluster; + uint8_t volume_serial[4]; + struct { + uint8_t vermin; + uint8_t vermaj; + } version; + uint16_t volume_state; + uint8_t block_bits; + uint8_t bpc_bits; + uint8_t fat_count; + uint8_t drive_no; + uint8_t allocated_percent; +} __attribute__ ((__packed__)); + +struct exfat_entry_label { + uint8_t type; + uint8_t length; + uint8_t name[30]; +} __attribute__ ((__packed__)); + +#define BLOCK_SIZE(sb) (1 << (sb)->block_bits) +#define CLUSTER_SIZE(sb) (BLOCK_SIZE(sb) << (sb)->bpc_bits) + +#define EXFAT_FIRST_DATA_CLUSTER 2 +#define EXFAT_LAST_DATA_CLUSTER 0xffffff6 +#define EXFAT_ENTRY_SIZE 32 + +#define EXFAT_ENTRY_EOD 0x00 +#define EXFAT_ENTRY_LABEL 0x83 /* * Byte swap functions */ -- 2.17.1
codechina上的提交id
号:
AOSP: blkid: add support to recognize exfat to blkid.
AOSP: blkid: Resolve to the exFAT uuid change on reboot.
AOSP: blkid: Correct the label name for exfat
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。