Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Unified Diff: utils.cc

Issue 3706006: AU: Add a utility routine to get the filesystem size from a device. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/update_engine.git
Patch Set: review comments Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « utils.h ('k') | utils_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: utils.cc
diff --git a/utils.cc b/utils.cc
index 6006eb85e736f63933380e613f26ebad509b75a6..c8a4da64e29cf1d23037a4b9c7c329ccc593ef72 100644
--- a/utils.cc
+++ b/utils.cc
@@ -18,6 +18,7 @@
#include <algorithm>
+#include <base/eintr_wrapper.h>
#include <base/file_path.h>
#include <base/file_util.h>
#include <base/rand_util.h>
@@ -421,6 +422,61 @@ bool UnmountFilesystem(const string& mountpoint) {
return true;
}
+bool GetFilesystemSize(const std::string& device,
+ int* out_block_count,
+ int* out_block_size) {
+ int fd = HANDLE_EINTR(open(device.c_str(), O_RDONLY));
+ TEST_AND_RETURN_FALSE(fd >= 0);
+ ScopedFdCloser fd_closer(&fd);
+ return GetFilesystemSizeFromFD(fd, out_block_count, out_block_size);
+}
+
+bool GetFilesystemSizeFromFD(int fd,
+ int* out_block_count,
+ int* out_block_size) {
+ TEST_AND_RETURN_FALSE(fd >= 0);
+
+ // Determine the ext3 filesystem size by directly reading the block count and
+ // block size information from the superblock. See include/linux/ext3_fs.h for
+ // more details on the structure.
+ ssize_t kBufferSize = 16 * sizeof(uint32_t);
+ char buffer[kBufferSize];
+ const int kSuperblockOffset = 1024;
+ if (HANDLE_EINTR(pread(fd, buffer, kBufferSize, kSuperblockOffset)) !=
+ kBufferSize) {
+ PLOG(ERROR) << "Unable to determine file system size:";
+ return false;
+ }
+ uint32_t block_count; // ext3_fs.h: ext3_super_block.s_blocks_count
+ uint32_t log_block_size; // ext3_fs.h: ext3_super_block.s_log_block_size
+ uint16_t magic; // ext3_fs.h: ext3_super_block.s_magic
+ memcpy(&block_count, &buffer[1 * sizeof(int32_t)], sizeof(block_count));
+ memcpy(&log_block_size, &buffer[6 * sizeof(int32_t)], sizeof(log_block_size));
+ memcpy(&magic, &buffer[14 * sizeof(int32_t)], sizeof(magic));
+ block_count = le32toh(block_count);
+ const int kExt3MinBlockLogSize = 10; // ext3_fs.h: EXT3_MIN_BLOCK_LOG_SIZE
+ log_block_size = le32toh(log_block_size) + kExt3MinBlockLogSize;
+ magic = le16toh(magic);
+
+ // Sanity check the parameters.
+ const uint16_t kExt3SuperMagic = 0xef53; // ext3_fs.h: EXT3_SUPER_MAGIC
+ TEST_AND_RETURN_FALSE(magic == kExt3SuperMagic);
+ const int kExt3MinBlockSize = 1024; // ext3_fs.h: EXT3_MIN_BLOCK_SIZE
+ const int kExt3MaxBlockSize = 4096; // ext3_fs.h: EXT3_MAX_BLOCK_SIZE
+ int block_size = 1 << log_block_size;
+ TEST_AND_RETURN_FALSE(block_size >= kExt3MinBlockSize &&
+ block_size <= kExt3MaxBlockSize);
+ TEST_AND_RETURN_FALSE(block_count > 0);
+
+ if (out_block_count) {
+ *out_block_count = block_count;
+ }
+ if (out_block_size) {
+ *out_block_size = block_size;
+ }
+ return true;
+}
+
bool GetBootloader(BootLoader* out_bootloader) {
// For now, hardcode to syslinux.
*out_bootloader = BootLoader_SYSLINUX;
« no previous file with comments | « utils.h ('k') | utils_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698