Merge changes from topic "exfat-update"
* changes: Use exFAT for SDXC cards Add GetBlockDevSize, GetBlockDevSectors helpers
This commit is contained in:
commit
a2a227e382
9 changed files with 104 additions and 100 deletions
|
@ -100,20 +100,10 @@ static KeyBuffer default_key_params(const std::string& real_blkdev, const KeyBuf
|
|||
}
|
||||
|
||||
static bool get_number_of_sectors(const std::string& real_blkdev, uint64_t* nr_sec) {
|
||||
android::base::unique_fd dev_fd(
|
||||
TEMP_FAILURE_RETRY(open(real_blkdev.c_str(), O_RDONLY | O_CLOEXEC, 0)));
|
||||
if (dev_fd == -1) {
|
||||
PLOG(ERROR) << "Unable to open " << real_blkdev << " to measure size";
|
||||
return false;
|
||||
}
|
||||
unsigned long res;
|
||||
// TODO: should use BLKGETSIZE64
|
||||
get_blkdev_size(dev_fd.get(), &res);
|
||||
if (res == 0) {
|
||||
if (android::vold::GetBlockDev512Sectors(real_blkdev, nr_sec) != android::OK) {
|
||||
PLOG(ERROR) << "Unable to measure size of " << real_blkdev;
|
||||
return false;
|
||||
}
|
||||
*nr_sec = res;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
44
Utils.cpp
44
Utils.cpp
|
@ -476,6 +476,42 @@ status_t NormalizeHex(const std::string& in, std::string& out) {
|
|||
return StrToHex(tmp, out);
|
||||
}
|
||||
|
||||
status_t GetBlockDevSize(int fd, uint64_t* size) {
|
||||
if (ioctl(fd, BLKGETSIZE64, size)) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
status_t GetBlockDevSize(const std::string& path, uint64_t* size) {
|
||||
int fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
||||
status_t res = OK;
|
||||
|
||||
if (fd < 0) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
res = GetBlockDevSize(fd, size);
|
||||
|
||||
close(fd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
status_t GetBlockDev512Sectors(const std::string& path, uint64_t* nr_sec) {
|
||||
uint64_t size;
|
||||
status_t res = GetBlockDevSize(path, &size);
|
||||
|
||||
if (res != OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
*nr_sec = size / 512;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
uint64_t GetFreeBytes(const std::string& path) {
|
||||
struct statvfs sb;
|
||||
if (statvfs(path.c_str(), &sb) == 0) {
|
||||
|
@ -560,8 +596,7 @@ bool IsFilesystemSupported(const std::string& fsType) {
|
|||
status_t WipeBlockDevice(const std::string& path) {
|
||||
status_t res = -1;
|
||||
const char* c_path = path.c_str();
|
||||
unsigned long nr_sec = 0;
|
||||
unsigned long long range[2];
|
||||
uint64_t range[2] = {0, 0};
|
||||
|
||||
int fd = TEMP_FAILURE_RETRY(open(c_path, O_RDWR | O_CLOEXEC));
|
||||
if (fd == -1) {
|
||||
|
@ -569,14 +604,11 @@ status_t WipeBlockDevice(const std::string& path) {
|
|||
goto done;
|
||||
}
|
||||
|
||||
if ((ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) {
|
||||
if (GetBlockDevSize(fd, &range[1]) != OK) {
|
||||
PLOG(ERROR) << "Failed to determine size of " << path;
|
||||
goto done;
|
||||
}
|
||||
|
||||
range[0] = 0;
|
||||
range[1] = (unsigned long long)nr_sec * 512;
|
||||
|
||||
LOG(INFO) << "About to discard " << range[1] << " on " << path;
|
||||
if (ioctl(fd, BLKDISCARD, &range) == 0) {
|
||||
LOG(INFO) << "Discard success on " << path;
|
||||
|
|
6
Utils.h
6
Utils.h
|
@ -76,6 +76,12 @@ status_t ForkExecvp(const std::vector<std::string>& args, std::vector<std::strin
|
|||
|
||||
pid_t ForkExecvpAsync(const std::vector<std::string>& args);
|
||||
|
||||
/* Gets block device size in bytes */
|
||||
status_t GetBlockDevSize(int fd, uint64_t* size);
|
||||
status_t GetBlockDevSize(const std::string& path, uint64_t* size);
|
||||
/* Gets block device size in 512 byte sectors */
|
||||
status_t GetBlockDev512Sectors(const std::string& path, uint64_t* nr_sec);
|
||||
|
||||
status_t ReadRandomBytes(size_t bytes, std::string& out);
|
||||
status_t ReadRandomBytes(size_t bytes, char* buffer);
|
||||
status_t GenerateRandomUuid(std::string& out);
|
||||
|
|
|
@ -18,9 +18,3 @@
|
|||
#include <sys/ioctl.h>
|
||||
|
||||
struct fstab* fstab_default;
|
||||
|
||||
void get_blkdev_size(int fd, unsigned long* nr_sec) {
|
||||
if ((ioctl(fd, BLKGETSIZE, nr_sec)) == -1) {
|
||||
*nr_sec = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,4 @@ extern struct fstab* fstab_default;
|
|||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
|
||||
|
||||
void get_blkdev_size(int fd, unsigned long* nr_sec);
|
||||
|
||||
#endif
|
||||
|
|
50
cryptfs.cpp
50
cryptfs.cpp
|
@ -393,10 +393,10 @@ const char* cryptfs_get_crypto_name() {
|
|||
return get_crypto_type().get_crypto_name();
|
||||
}
|
||||
|
||||
static unsigned int get_fs_size(char* dev) {
|
||||
static uint64_t get_fs_size(char* dev) {
|
||||
int fd, block_size;
|
||||
struct ext4_super_block sb;
|
||||
off64_t len;
|
||||
uint64_t len;
|
||||
|
||||
if ((fd = open(dev, O_RDONLY | O_CLOEXEC)) < 0) {
|
||||
SLOGE("Cannot open device to get filesystem size ");
|
||||
|
@ -421,17 +421,16 @@ static unsigned int get_fs_size(char* dev) {
|
|||
}
|
||||
block_size = 1024 << sb.s_log_block_size;
|
||||
/* compute length in bytes */
|
||||
len = (((off64_t)sb.s_blocks_count_hi << 32) + sb.s_blocks_count_lo) * block_size;
|
||||
len = (((uint64_t)sb.s_blocks_count_hi << 32) + sb.s_blocks_count_lo) * block_size;
|
||||
|
||||
/* return length in sectors */
|
||||
return (unsigned int)(len / 512);
|
||||
return len / 512;
|
||||
}
|
||||
|
||||
static int get_crypt_ftr_info(char** metadata_fname, off64_t* off) {
|
||||
static int cached_data = 0;
|
||||
static off64_t cached_off = 0;
|
||||
static uint64_t cached_off = 0;
|
||||
static char cached_metadata_fname[PROPERTY_VALUE_MAX] = "";
|
||||
int fd;
|
||||
char key_loc[PROPERTY_VALUE_MAX];
|
||||
char real_blkdev[PROPERTY_VALUE_MAX];
|
||||
int rc = -1;
|
||||
|
@ -440,25 +439,17 @@ static int get_crypt_ftr_info(char** metadata_fname, off64_t* off) {
|
|||
fs_mgr_get_crypt_info(fstab_default, key_loc, real_blkdev, sizeof(key_loc));
|
||||
|
||||
if (!strcmp(key_loc, KEY_IN_FOOTER)) {
|
||||
if ((fd = open(real_blkdev, O_RDWR | O_CLOEXEC)) < 0) {
|
||||
SLOGE("Cannot open real block device %s\n", real_blkdev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned long nr_sec = 0;
|
||||
get_blkdev_size(fd, &nr_sec);
|
||||
if (nr_sec != 0) {
|
||||
if (android::vold::GetBlockDevSize(real_blkdev, &cached_off) == android::OK) {
|
||||
/* If it's an encrypted Android partition, the last 16 Kbytes contain the
|
||||
* encryption info footer and key, and plenty of bytes to spare for future
|
||||
* growth.
|
||||
*/
|
||||
strlcpy(cached_metadata_fname, real_blkdev, sizeof(cached_metadata_fname));
|
||||
cached_off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET;
|
||||
cached_off -= CRYPT_FOOTER_OFFSET;
|
||||
cached_data = 1;
|
||||
} else {
|
||||
SLOGE("Cannot get size of block device %s\n", real_blkdev);
|
||||
}
|
||||
close(fd);
|
||||
} else {
|
||||
strlcpy(cached_metadata_fname, key_loc, sizeof(cached_metadata_fname));
|
||||
cached_off = 0;
|
||||
|
@ -1816,17 +1807,8 @@ errout:
|
|||
*/
|
||||
int cryptfs_setup_ext_volume(const char* label, const char* real_blkdev, const unsigned char* key,
|
||||
char* out_crypto_blkdev) {
|
||||
int fd = open(real_blkdev, O_RDONLY | O_CLOEXEC);
|
||||
if (fd == -1) {
|
||||
SLOGE("Failed to open %s: %s", real_blkdev, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned long nr_sec = 0;
|
||||
get_blkdev_size(fd, &nr_sec);
|
||||
close(fd);
|
||||
|
||||
if (nr_sec == 0) {
|
||||
uint64_t nr_sec = 0;
|
||||
if (android::vold::GetBlockDev512Sectors(real_blkdev, &nr_sec) != android::OK) {
|
||||
SLOGE("Failed to get size of %s: %s", real_blkdev, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
@ -2090,7 +2072,6 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
|||
off64_t previously_encrypted_upto = 0;
|
||||
bool rebootEncryption = false;
|
||||
bool onlyCreateHeader = false;
|
||||
int fd = -1;
|
||||
|
||||
if (get_crypt_ftr_and_key(&crypt_ftr) == 0) {
|
||||
if (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS) {
|
||||
|
@ -2134,22 +2115,15 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
|||
fs_mgr_get_crypt_info(fstab_default, 0, real_blkdev, sizeof(real_blkdev));
|
||||
|
||||
/* Get the size of the real block device */
|
||||
fd = open(real_blkdev, O_RDONLY | O_CLOEXEC);
|
||||
if (fd == -1) {
|
||||
SLOGE("Cannot open block device %s\n", real_blkdev);
|
||||
goto error_unencrypted;
|
||||
}
|
||||
unsigned long nr_sec;
|
||||
get_blkdev_size(fd, &nr_sec);
|
||||
if (nr_sec == 0) {
|
||||
uint64_t nr_sec;
|
||||
if (android::vold::GetBlockDev512Sectors(real_blkdev, &nr_sec) != android::OK) {
|
||||
SLOGE("Cannot get size of block device %s\n", real_blkdev);
|
||||
goto error_unencrypted;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
/* If doing inplace encryption, make sure the orig fs doesn't include the crypto footer */
|
||||
if (!strcmp(key_loc, KEY_IN_FOOTER)) {
|
||||
unsigned int fs_size_sec, max_fs_size_sec;
|
||||
uint64_t fs_size_sec, max_fs_size_sec;
|
||||
fs_size_sec = get_fs_size(real_blkdev);
|
||||
if (fs_size_sec == 0) fs_size_sec = get_f2fs_filesystem_size_sec(real_blkdev);
|
||||
|
||||
|
|
|
@ -243,12 +243,8 @@ status_t Disk::readMetadata() {
|
|||
mSize = -1;
|
||||
mLabel.clear();
|
||||
|
||||
int fd = open(mDevPath.c_str(), O_RDONLY | O_CLOEXEC);
|
||||
if (fd != -1) {
|
||||
if (ioctl(fd, BLKGETSIZE64, &mSize)) {
|
||||
mSize = -1;
|
||||
}
|
||||
close(fd);
|
||||
if (GetBlockDevSize(mDevPath, &mSize) != OK) {
|
||||
mSize = -1;
|
||||
}
|
||||
|
||||
unsigned int majorId = major(mDevice);
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <cutils/fs.h>
|
||||
#include <private/android_filesystem_config.h>
|
||||
|
||||
|
@ -36,7 +35,6 @@
|
|||
#include <sys/wait.h>
|
||||
|
||||
using android::base::StringPrintf;
|
||||
using android::base::unique_fd;
|
||||
|
||||
namespace android {
|
||||
namespace vold {
|
||||
|
@ -59,19 +57,10 @@ status_t ObbVolume::doCreate() {
|
|||
}
|
||||
|
||||
if (!mSourceKey.empty()) {
|
||||
unsigned long nr_sec = 0;
|
||||
{
|
||||
unique_fd loop_fd(open(mLoopPath.c_str(), O_RDWR | O_CLOEXEC));
|
||||
if (loop_fd.get() == -1) {
|
||||
PLOG(ERROR) << getId() << " failed to open loop";
|
||||
return -1;
|
||||
}
|
||||
|
||||
get_blkdev_size(loop_fd.get(), &nr_sec);
|
||||
if (nr_sec == 0) {
|
||||
PLOG(ERROR) << getId() << " failed to get loop size";
|
||||
return -1;
|
||||
}
|
||||
uint64_t nr_sec = 0;
|
||||
if (GetBlockDev512Sectors(mLoopPath, &nr_sec) != OK) {
|
||||
PLOG(ERROR) << getId() << " failed to get loop size";
|
||||
return -1;
|
||||
}
|
||||
|
||||
char tmp[PATH_MAX];
|
||||
|
|
|
@ -246,28 +246,53 @@ status_t PublicVolume::doUnmount() {
|
|||
}
|
||||
|
||||
status_t PublicVolume::doFormat(const std::string& fsType) {
|
||||
if ((fsType == "vfat" || fsType == "auto") && vfat::IsSupported()) {
|
||||
if (WipeBlockDevice(mDevPath) != OK) {
|
||||
LOG(WARNING) << getId() << " failed to wipe";
|
||||
bool useVfat = vfat::IsSupported();
|
||||
bool useExfat = exfat::IsSupported();
|
||||
status_t res = OK;
|
||||
|
||||
// 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 (vfat::Format(mDevPath, 0)) {
|
||||
LOG(ERROR) << getId() << " failed to format";
|
||||
return -errno;
|
||||
|
||||
// If both vfat & exfat are supported use exfat for SDXC (>~32GiB) cards
|
||||
if (size > 32896LL * 1024 * 1024) {
|
||||
useVfat = false;
|
||||
} else {
|
||||
useExfat = false;
|
||||
}
|
||||
} else if ((fsType == "exfat" || fsType == "auto") && exfat::IsSupported()) {
|
||||
if (WipeBlockDevice(mDevPath) != OK) {
|
||||
LOG(WARNING) << getId() << " failed to wipe";
|
||||
}
|
||||
if (exfat::Format(mDevPath)) {
|
||||
LOG(ERROR) << getId() << " failed to format";
|
||||
return -errno;
|
||||
}
|
||||
} else {
|
||||
} else if (fsType == "vfat") {
|
||||
useExfat = false;
|
||||
} else if (fsType == "exfat") {
|
||||
useVfat = false;
|
||||
}
|
||||
|
||||
if (!useVfat && !useExfat) {
|
||||
LOG(ERROR) << "Unsupported filesystem " << fsType;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
if (WipeBlockDevice(mDevPath) != OK) {
|
||||
LOG(WARNING) << getId() << " failed to wipe";
|
||||
}
|
||||
|
||||
if (useVfat) {
|
||||
res = vfat::Format(mDevPath, 0);
|
||||
} else if (useExfat) {
|
||||
res = exfat::Format(mDevPath);
|
||||
}
|
||||
|
||||
if (res != OK) {
|
||||
LOG(ERROR) << getId() << " failed to format";
|
||||
res = -errno;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace vold
|
||||
|
|
Loading…
Reference in a new issue