From 2f720f7ec5c9d0b91defc85878e7330b10f8e89a Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Sun, 10 Apr 2016 20:51:40 -0600 Subject: Use inode numbers for CE storage, fix sizes. Certain operations, such as clearing/destroying app data, or just counting on-disk size, require us to know the CE storage directory of a particular app. To facilitate these operations, offer a method to get the inode of a CE directory, and accept that inode number for later operations. In previous releases, we started installing apps using a new directory-based layout, where all app code, unpacked native libraries, and optimized code is bundled together. So now we only have a single path to measure for code size. Start measuring both CE and DE storage data usage for apps, and tweak the reporting so that empty cache/data directories actually show up as "0 bytes". Fix bugs in disk usage counting, since st_blksize has no bearing on the allocated disk space. Also don't double-count "." and ".." directories when measuring storage. Bug: 27828915, 27197819 Change-Id: I350b951f5c24165edb253ac663c9aae020c24dc9 --- cmds/installd/utils.cpp | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'cmds/installd/utils.cpp') diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp index d84d9f6106..878fb2daa8 100644 --- a/cmds/installd/utils.cpp +++ b/cmds/installd/utils.cpp @@ -81,11 +81,39 @@ std::string create_data_app_package_path(const char* volume_uuid, * volume UUID, package name, and user ID. An empty UUID is assumed to be * internal storage. */ -std::string create_data_user_package_path(const char* volume_uuid, +std::string create_data_user_ce_package_path(const char* volume_uuid, userid_t user, const char* package_name) { check_package_name(package_name); return StringPrintf("%s/%s", - create_data_user_path(volume_uuid, user).c_str(), package_name); + create_data_user_ce_path(volume_uuid, user).c_str(), package_name); +} + +std::string create_data_user_ce_package_path(const char* volume_uuid, userid_t user, + const char* package_name, ino_t ce_data_inode) { + // For testing purposes, rely on the inode when defined; this could be + // optimized to use access() in the future. + auto fallback = create_data_user_ce_package_path(volume_uuid, user, package_name); + if (ce_data_inode != 0) { + auto user_path = create_data_user_ce_path(volume_uuid, user); + DIR* dir = opendir(user_path.c_str()); + if (dir == nullptr) { + PLOG(ERROR) << "Failed to opendir " << user_path; + return fallback; + } + + struct dirent* ent; + while ((ent = readdir(dir))) { + if (ent->d_ino == ce_data_inode) { + closedir(dir); + return StringPrintf("%s/%s", user_path.c_str(), ent->d_name); + } + } + LOG(WARNING) << "Failed to find inode " << ce_data_inode << " for package " << package_name; + closedir(dir); + return fallback; + } else { + return fallback; + } } std::string create_data_user_de_package_path(const char* volume_uuid, @@ -102,7 +130,7 @@ int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname, return -1; } - std::string _tmp(create_data_user_package_path(nullptr, userid, pkgname) + postfix); + std::string _tmp(create_data_user_ce_package_path(nullptr, userid, pkgname) + postfix); const char* tmp = _tmp.c_str(); if (strlen(tmp) >= PKG_PATH_MAX) { path[0] = '\0'; @@ -132,7 +160,7 @@ std::string create_data_app_path(const char* volume_uuid) { /** * Create the path name for user data for a certain userid. */ -std::string create_data_user_path(const char* volume_uuid, userid_t userid) { +std::string create_data_user_ce_path(const char* volume_uuid, userid_t userid) { std::string data(create_data_path(volume_uuid)); if (volume_uuid == nullptr) { if (userid == 0) { -- cgit v1.2.3-59-g8ed1b