[FP4-128]add exfat support
diff --git a/model/Disk.cpp b/model/Disk.cpp
index 98b9596..0ca894b 100644
--- a/model/Disk.cpp
+++ b/model/Disk.cpp
@@ -23,6 +23,8 @@
#include "VolumeEncryption.h"
#include "VolumeManager.h"
+#include "fs/Exfat.h"
+
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
@@ -384,6 +386,8 @@
}
switch (type) {
+ case 0x01: // FAT12 (in first 32 MB of disk)
+ case 0x04: // FAT16 (in first 32 MB of disk)
case 0x06: // FAT16
case 0x07: // HPFS/NTFS/exFAT
case 0x0b: // W95 FAT32 (LBA)
@@ -458,6 +462,12 @@
LOG(WARNING) << "Failed to zap; status " << res;
}
+ if (exfat::CheckSize(mDevPath, false) == 1) {
+ /* Should format filesystem as exFAT, so we must partition the device
+ * according to SDXC rules. */
+ return exfat::PartitionDisk(mDevPath);
+ }
+
// Now let's build the new MBR table. We heavily rely on sgdisk to
// force optimal alignment on the created partitions.
cmd.clear();
diff --git a/model/PublicVolume.cpp b/model/PublicVolume.cpp
index 12e31ff..552eab1 100644
--- a/model/PublicVolume.cpp
+++ b/model/PublicVolume.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2010-2021 Tuxera Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +21,7 @@
#include "Utils.h"
#include "VolumeManager.h"
#include "fs/Exfat.h"
+#include "fs/Filesystems.h"
#include "fs/Vfat.h"
#include <android-base/logging.h>
@@ -57,6 +59,13 @@
PublicVolume::~PublicVolume() {}
status_t PublicVolume::readMetadata() {
+ if(filesystems::Detect(mDevPath, &mFsTypeId)) {
+ /* Error while detecting filesystem. This should not happen, but in case
+ * it does, pretend that it is recognized as FAT since this most
+ * accurately reflects the behaviour of a stock AOSP vold. */
+ mFsTypeId = FSTYPE_FAT;
+ }
+
status_t res = ReadMetadataUntrusted(mDevPath, &mFsType, &mFsUuid, &mFsLabel);
auto listener = getListener();
@@ -100,21 +109,16 @@
bool isVisible = getMountFlags() & MountFlags::kVisible;
readMetadata();
- if (mFsType == "vfat" && vfat::IsSupported()) {
- if (vfat::Check(mDevPath)) {
- LOG(ERROR) << getId() << " failed filesystem check";
- return -EIO;
- }
- } else if (mFsType == "exfat" && exfat::IsSupported()) {
- if (exfat::Check(mDevPath)) {
- LOG(ERROR) << getId() << " failed filesystem check";
- return -EIO;
- }
- } else {
+ if (!filesystems::IsSupported(mFsTypeId)) {
LOG(ERROR) << getId() << " unsupported filesystem " << mFsType;
return -EIO;
}
+ if (filesystems::Check(mFsTypeId, mDevPath)) {
+ LOG(ERROR) << getId() << " failed filesystem check";
+ return -EIO;
+ }
+
// Use UUID as stable name, if available
std::string stableName = getId();
if (!mFsUuid.empty()) {
@@ -140,18 +144,11 @@
return -errno;
}
- if (mFsType == "vfat") {
- if (vfat::Mount(mDevPath, mRawPath, false, false, false, AID_ROOT,
- (isVisible ? AID_MEDIA_RW : AID_EXTERNAL_STORAGE), 0007, true)) {
- PLOG(ERROR) << getId() << " failed to mount " << mDevPath;
- return -EIO;
- }
- } else if (mFsType == "exfat") {
- if (exfat::Mount(mDevPath, mRawPath, AID_ROOT,
- (isVisible ? AID_MEDIA_RW : AID_EXTERNAL_STORAGE), 0007)) {
- PLOG(ERROR) << getId() << " failed to mount " << mDevPath;
- return -EIO;
- }
+ if (filesystems::Mount(mFsTypeId, mDevPath, mRawPath, false, false, false,
+ AID_ROOT, (isVisible ? AID_MEDIA_RW : AID_EXTERNAL_STORAGE),
+ 0007, true)) {
+ PLOG(ERROR) << getId() << " failed to mount " << mDevPath;
+ return -EIO;
}
if (getMountFlags() & MountFlags::kPrimary) {
@@ -308,33 +305,26 @@
}
status_t PublicVolume::doFormat(const std::string& fsType) {
- bool useVfat = vfat::IsSupported();
- bool useExfat = exfat::IsSupported();
status_t res = OK;
+ status_t (*formatFunction)(const std::string&, unsigned long) = NULL;
+
// Resolve the target filesystem type
- if (fsType == "auto" && useVfat && useExfat) {
- uint64_t size = 0;
-
- res = GetBlockDevSize(mDevPath, &size);
- if (res != OK) {
- LOG(ERROR) << "Couldn't get device size " << mDevPath;
- return res;
- }
-
- // If both vfat & exfat are supported use exfat for SDXC (>~32GiB) cards
- if (size > 32896LL * 1024 * 1024) {
- useVfat = false;
- } else {
- useExfat = false;
+ if (fsType == "auto") {
+ if (exfat::IsSupported() && exfat::CheckSize(mDevPath, true) == 1) {
+ /* Should format filesystem as exFAT, so we must format the
+ * partition according to SDXC rules. */
+ formatFunction = &exfat::Format;
+ } else if(vfat::IsSupported()) {
+ formatFunction = &vfat::Format;
}
} else if (fsType == "vfat") {
- useExfat = false;
+ formatFunction = vfat::IsSupported() ? &vfat::Format : NULL;
} else if (fsType == "exfat") {
- useVfat = false;
+ formatFunction = exfat::IsSupported() ? &exfat::Format : NULL;
}
- if (!useVfat && !useExfat) {
+ if (!formatFunction) {
LOG(ERROR) << "Unsupported filesystem " << fsType;
return -EINVAL;
}
@@ -343,11 +333,7 @@
LOG(WARNING) << getId() << " failed to wipe";
}
- if (useVfat) {
- res = vfat::Format(mDevPath, 0);
- } else if (useExfat) {
- res = exfat::Format(mDevPath);
- }
+ res = formatFunction(mDevPath, 0);
if (res != OK) {
LOG(ERROR) << getId() << " failed to format";
diff --git a/model/PublicVolume.h b/model/PublicVolume.h
index 3156b53..0f4a795 100644
--- a/model/PublicVolume.h
+++ b/model/PublicVolume.h
@@ -18,6 +18,7 @@
#define ANDROID_VOLD_PUBLIC_VOLUME_H
#include "VolumeBase.h"
+#include "fs/Filesystems.h"
#include <cutils/multiuser.h>
@@ -71,6 +72,8 @@
/* Whether to use sdcardfs for this volume */
bool mUseSdcardFs;
+ /* Type ID of filesystem (see Filesystems.h). */
+ FSType mFsTypeId = FSTYPE_UNRECOGNIZED;
/* Filesystem type */
std::string mFsType;
/* Filesystem UUID */