vold: remove f2fs reserved_blocks from storage total size
F2FS reserved_blocks should not be included for storage total size,
since it can't be used by users and users must not be aware of this
space.
Bug: 394342775
Test: check the total storage size of Setting App
Change-Id: I4eba69938dee3edfce2db37e6703edccc685b63d
Signed-off-by: Daeho Jeong <daehojeong@google.com>
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index d932ec8..657f051 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -1247,7 +1247,8 @@
return android::vold::OpenAppFuseFile(uid, mountId, fileId, flags);
}
-static android::status_t getDeviceSize(std::string& device, int64_t* storageSize) {
+static android::status_t getDeviceSize(std::string& device, int64_t* storageSize,
+ bool isF2fsPrimary) {
// Follow any symbolic links
std::string dataDevice;
if (!android::base::Realpath(device, &dataDevice)) {
@@ -1256,14 +1257,35 @@
// Handle mapped volumes.
auto& dm = android::dm::DeviceMapper::Instance();
- for (;;) {
- auto parent = dm.GetParentBlockDeviceByPath(dataDevice);
- if (!parent.has_value()) break;
- dataDevice = *parent;
+ std::string dmPath = dataDevice;
+ if (dm.IsDmBlockDevice(dataDevice)) {
+ for (;;) {
+ auto parent = dm.GetParentBlockDeviceByPath(dataDevice);
+ if (!parent.has_value()) break;
+ dataDevice = *parent;
+ }
+ } else if (isF2fsPrimary) {
+ if (!dm.GetDmDevicePathByName(android::base::Basename(device), &dmPath)) {
+ LOG(WARNING) << "No proper dm device for " << device;
+ isF2fsPrimary = false;
+ }
+ }
+
+ // Find a device name for F2FS primary partition
+ std::string f2fsReservedBlocksSysfs;
+ std::size_t leaf;
+ if (isF2fsPrimary) {
+ leaf = dmPath.rfind('/');
+ if (leaf == std::string::npos) {
+ LOG(WARNING) << "dm device " << dmPath << " is not a path";
+ isF2fsPrimary = false;
+ }
+ f2fsReservedBlocksSysfs =
+ std::string() + "/sys/fs/f2fs/" + dmPath.substr(leaf + 1) + "/reserved_blocks";
}
// Get the potential /sys/block entry
- std::size_t leaf = dataDevice.rfind('/');
+ leaf = dataDevice.rfind('/');
if (leaf == std::string::npos) {
LOG(ERROR) << "data device " << dataDevice << " is not a path";
return EINVAL;
@@ -1293,14 +1315,32 @@
}
// Read the size file and be done
+ int64_t sizeNum;
std::stringstream ssSize(size);
- ssSize >> *storageSize;
+ ssSize >> sizeNum;
if (ssSize.fail()) {
LOG(ERROR) << sizeFile << " cannot be read as an integer";
return EINVAL;
}
- *storageSize *= 512;
+ sizeNum *= 512;
+ if (isF2fsPrimary) {
+ int64_t reservedBlocksNum = 0;
+ if (!android::base::ReadFileToString(f2fsReservedBlocksSysfs, &size, true)) {
+ LOG(WARNING) << "Could not find valid entry from " << f2fsReservedBlocksSysfs;
+ } else {
+ std::stringstream reservedBlocks(size);
+ reservedBlocks >> reservedBlocksNum;
+ if (reservedBlocks.fail()) {
+ LOG(WARNING) << f2fsReservedBlocksSysfs << " cannot be read as an integer";
+ reservedBlocksNum = 0;
+ }
+ }
+ int64_t blockSize = android::base::GetIntProperty("ro.boot.hardware.cpu.pagesize", 0);
+ sizeNum -= reservedBlocksNum * blockSize;
+ }
+
+ *storageSize = sizeNum;
return OK;
}
@@ -1313,14 +1353,14 @@
return EINVAL;
}
- status = getDeviceSize(entry->blk_device, storageSize);
+ status = getDeviceSize(entry->blk_device, storageSize, entry->fs_type == "f2fs");
if (status != OK) {
return status;
}
for (auto device : entry->user_devices) {
int64_t deviceStorageSize;
- status = getDeviceSize(device, &deviceStorageSize);
+ status = getDeviceSize(device, &deviceStorageSize, false);
if (status != OK) {
return status;
}