From 625dc787c629cd04e30328a9b1cf4a8e7d6210bc Mon Sep 17 00:00:00 2001 From: Oleksiy Avramchenko Date: Wed, 23 May 2018 10:50:46 +0200 Subject: [PATCH] Add GetBlockDevSize, GetBlockDevSectors helpers Helpers to get a block device size in bytes or 512 byte sectors, using BLKGETSIZE64 and returning value of uint64_t type. This also removes get_blkdev_size(). Test: build, manual, mount exFAT volume Bug: 80202067 Change-Id: Ib07e8ac6ef7ff49de0ed570d1fa202e8b558b80c --- MetadataCrypt.cpp | 12 +---------- Utils.cpp | 44 +++++++++++++++++++++++++++++++++------ Utils.h | 6 ++++++ VoldUtil.cpp | 6 ------ VoldUtil.h | 2 -- cryptfs.cpp | 50 +++++++++++---------------------------------- model/Disk.cpp | 8 ++------ model/ObbVolume.cpp | 19 ++++------------- 8 files changed, 63 insertions(+), 84 deletions(-) diff --git a/MetadataCrypt.cpp b/MetadataCrypt.cpp index 842b19b..e5bf819 100644 --- a/MetadataCrypt.cpp +++ b/MetadataCrypt.cpp @@ -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; } diff --git a/Utils.cpp b/Utils.cpp index f085c22..736d721 100644 --- a/Utils.cpp +++ b/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; diff --git a/Utils.h b/Utils.h index 09ce8fa..40f4d0a 100644 --- a/Utils.h +++ b/Utils.h @@ -76,6 +76,12 @@ status_t ForkExecvp(const std::vector& args, std::vector& 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); diff --git a/VoldUtil.cpp b/VoldUtil.cpp index 26c817c..4b980be 100644 --- a/VoldUtil.cpp +++ b/VoldUtil.cpp @@ -18,9 +18,3 @@ #include struct fstab* fstab_default; - -void get_blkdev_size(int fd, unsigned long* nr_sec) { - if ((ioctl(fd, BLKGETSIZE, nr_sec)) == -1) { - *nr_sec = 0; - } -} diff --git a/VoldUtil.h b/VoldUtil.h index 4311586..782e36d 100644 --- a/VoldUtil.h +++ b/VoldUtil.h @@ -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 diff --git a/cryptfs.cpp b/cryptfs.cpp index 00e5519..0b52650 100644 --- a/cryptfs.cpp +++ b/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); diff --git a/model/Disk.cpp b/model/Disk.cpp index 13cb1c7..2b6773d 100644 --- a/model/Disk.cpp +++ b/model/Disk.cpp @@ -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); diff --git a/model/ObbVolume.cpp b/model/ObbVolume.cpp index ec3d267..21479c4 100644 --- a/model/ObbVolume.cpp +++ b/model/ObbVolume.cpp @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -36,7 +35,6 @@ #include 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];