diff --git a/Android.mk b/Android.mk index d403b96..38da8c7 100644 --- a/Android.mk +++ b/Android.mk @@ -17,7 +17,6 @@ common_src_files := \ CheckBattery.cpp \ Ext4Crypt.cpp \ VoldUtil.c \ - fstrim.c \ cryptfs.c \ Disk.cpp \ VolumeBase.cpp \ @@ -27,6 +26,7 @@ common_src_files := \ Utils.cpp \ MoveTask.cpp \ Benchmark.cpp \ + TrimTask.cpp \ common_c_includes := \ system/extras/ext4_utils \ diff --git a/Benchmark.cpp b/Benchmark.cpp index e329588..7a3af65 100644 --- a/Benchmark.cpp +++ b/Benchmark.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -33,14 +34,19 @@ using android::base::WriteStringToFile; namespace android { namespace vold { -static std::string simpleRead(const std::string& path) { - std::string tmp; - ReadFileToString(path, &tmp); - tmp.erase(tmp.find_last_not_of(" \n\r") + 1); - return tmp; +static void notifyResult(const std::string& path, int64_t create_d, + int64_t drop_d, int64_t run_d, int64_t destroy_d) { + std::string res(path + + + " " + BenchmarkIdent() + + " " + std::to_string(create_d) + + " " + std::to_string(drop_d) + + " " + std::to_string(run_d) + + " " + std::to_string(destroy_d)); + VolumeManager::Instance()->getBroadcaster()->sendBroadcast( + ResponseCode::BenchmarkResult, res.c_str(), false); } -nsecs_t Benchmark(const std::string& path, const std::string& sysPath) { +static nsecs_t benchmark(const std::string& path) { errno = 0; int orig_prio = getpriority(PRIO_PROCESS, 0); if (errno != 0) { @@ -82,9 +88,11 @@ nsecs_t Benchmark(const std::string& path, const std::string& sysPath) { sync(); nsecs_t create = systemTime(SYSTEM_TIME_BOOTTIME); + LOG(VERBOSE) << "Before drop_caches"; if (!WriteStringToFile("3", "/proc/sys/vm/drop_caches")) { PLOG(ERROR) << "Failed to drop_caches"; } + LOG(VERBOSE) << "After drop_caches"; nsecs_t drop = systemTime(SYSTEM_TIME_BOOTTIME); BenchmarkRun(); @@ -95,6 +103,16 @@ nsecs_t Benchmark(const std::string& path, const std::string& sysPath) { sync(); nsecs_t destroy = systemTime(SYSTEM_TIME_BOOTTIME); + if (chdir(orig_cwd) != 0) { + PLOG(ERROR) << "Failed to chdir"; + } + if (android_set_ioprio(0, orig_clazz, orig_ioprio)) { + PLOG(ERROR) << "Failed to android_set_ioprio"; + } + if (setpriority(PRIO_PROCESS, 0, orig_prio) != 0) { + PLOG(ERROR) << "Failed to setpriority"; + } + nsecs_t create_d = create - start; nsecs_t drop_d = drop - create; nsecs_t run_d = run - drop; @@ -105,39 +123,27 @@ nsecs_t Benchmark(const std::string& path, const std::string& sysPath) { LOG(INFO) << "run took " << nanoseconds_to_milliseconds(run_d) << "ms"; LOG(INFO) << "destroy took " << nanoseconds_to_milliseconds(destroy_d) << "ms"; - std::string detail; - detail += "id=" + BenchmarkIdent() - + ",cr=" + std::to_string(create_d) - + ",dr=" + std::to_string(drop_d) - + ",ru=" + std::to_string(run_d) - + ",de=" + std::to_string(destroy_d) - + ",si=" + simpleRead(sysPath + "/size") - + ",ve=" + simpleRead(sysPath + "/device/vendor") - + ",mo=" + simpleRead(sysPath + "/device/model") - + ",csd=" + simpleRead(sysPath + "/device/csd"); + notifyResult(path, create_d, drop_d, run_d, destroy_d); - // Scrub CRC and serial number out of CID - std::string cid = simpleRead(sysPath + "/device/cid"); - if (cid.length() == 32) { - cid.erase(32, 1); - cid.erase(18, 8); - detail += ",cid=" + cid; - } - - VolumeManager::Instance()->getBroadcaster()->sendBroadcast( - ResponseCode::BenchmarkResult, detail.c_str(), false); - - if (chdir(orig_cwd) != 0) { - PLOG(ERROR) << "Failed to chdir"; - } - if (android_set_ioprio(0, orig_clazz, orig_ioprio)) { - PLOG(ERROR) << "Failed to android_set_ioprio"; - } - if (setpriority(PRIO_PROCESS, 0, orig_prio) != 0) { - PLOG(ERROR) << "Failed to setpriority"; - } return run_d; } +nsecs_t BenchmarkPrivate(const std::string& path) { + std::string benchPath(path); + benchPath += "/misc"; + if (android::vold::PrepareDir(benchPath, 01771, AID_SYSTEM, AID_MISC)) { + return -1; + } + benchPath += "/vold"; + if (android::vold::PrepareDir(benchPath, 0700, AID_ROOT, AID_ROOT)) { + return -1; + } + benchPath += "/bench"; + if (android::vold::PrepareDir(benchPath, 0700, AID_ROOT, AID_ROOT)) { + return -1; + } + return benchmark(benchPath); +} + } // namespace vold } // namespace android diff --git a/Benchmark.h b/Benchmark.h index 02e22d5..13f9009 100644 --- a/Benchmark.h +++ b/Benchmark.h @@ -25,7 +25,8 @@ namespace android { namespace vold { -nsecs_t Benchmark(const std::string& path, const std::string& sysPath); +/* Benchmark a private volume mounted at the given path */ +nsecs_t BenchmarkPrivate(const std::string& path); } // namespace vold } // namespace android diff --git a/CommandListener.cpp b/CommandListener.cpp index 32be05c..36d2950 100644 --- a/CommandListener.cpp +++ b/CommandListener.cpp @@ -45,8 +45,8 @@ #include "Loop.h" #include "Devmapper.h" #include "cryptfs.h" -#include "fstrim.h" #include "MoveTask.h" +#include "TrimTask.h" #define DUMP_ARGS 0 @@ -255,7 +255,7 @@ int CommandListener::VolumeCmd::runCommand(SocketClient *cli, } else if (cmd == "benchmark" && argc > 2) { // benchmark [volId] std::string id(argv[2]); - nsecs_t res = vm->benchmarkVolume(id); + nsecs_t res = vm->benchmarkPrivate(id); return cli->sendMsg(ResponseCode::CommandOkay, android::base::StringPrintf("%" PRId64, res).c_str(), false); @@ -600,32 +600,23 @@ int CommandListener::FstrimCmd::runCommand(SocketClient *cli, return 0; } - int rc = 0; + VolumeManager *vm = VolumeManager::Instance(); + std::lock_guard lock(vm->getLock()); - if (!strcmp(argv[1], "dotrim")) { - if (argc != 2) { - cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: fstrim dotrim", false); - return 0; - } - dumpArgs(argc, argv, -1); - rc = fstrim_filesystems(0); - } else if (!strcmp(argv[1], "dodtrim")) { - if (argc != 2) { - cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: fstrim dodtrim", false); - return 0; - } - dumpArgs(argc, argv, -1); - rc = fstrim_filesystems(1); /* Do Deep Discard trim */ - } else { - dumpArgs(argc, argv, -1); - cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown fstrim cmd", false); + int flags = 0; + + std::string cmd(argv[1]); + if (cmd == "dotrim") { + flags = 0; + } else if (cmd == "dotrimbench") { + flags = android::vold::TrimTask::Flags::kBenchmarkAfter; + } else if (cmd == "dodtrim") { + flags = android::vold::TrimTask::Flags::kDeepTrim; + } else if (cmd == "dodtrimbench") { + flags = android::vold::TrimTask::Flags::kDeepTrim + | android::vold::TrimTask::Flags::kBenchmarkAfter; } - // Always report that the command succeeded and return the error code. - // The caller will check the return value to see what the error was. - char msg[255]; - snprintf(msg, sizeof(msg), "%d", rc); - cli->sendMsg(ResponseCode::CommandOkay, msg, false); - - return 0; + (new android::vold::TrimTask(flags))->start(); + return sendGenericOkFail(cli, 0); } diff --git a/Disk.cpp b/Disk.cpp index df53d07..1e76bee 100644 --- a/Disk.cpp +++ b/Disk.cpp @@ -105,6 +105,15 @@ std::shared_ptr Disk::findVolume(const std::string& id) { return nullptr; } +void Disk::listVolumes(VolumeBase::Type type, std::list& list) { + for (auto vol : mVolumes) { + if (vol->getType() == type) { + list.push_back(vol->getId()); + } + // TODO: consider looking at stacked volumes + } +} + status_t Disk::create() { CHECK(!mCreated); mCreated = true; @@ -229,6 +238,7 @@ status_t Disk::readMetadata() { notifyEvent(ResponseCode::DiskSizeChanged, StringPrintf("%" PRId64, mSize)); notifyEvent(ResponseCode::DiskLabelChanged, mLabel); + notifyEvent(ResponseCode::DiskSysPathChanged, mSysPath); return OK; } diff --git a/Disk.h b/Disk.h index 60e4fa9..77ec7df 100644 --- a/Disk.h +++ b/Disk.h @@ -18,6 +18,7 @@ #define ANDROID_VOLD_DISK_H #include "Utils.h" +#include "VolumeBase.h" #include @@ -64,6 +65,8 @@ public: std::shared_ptr findVolume(const std::string& id); + void listVolumes(VolumeBase::Type type, std::list& list); + status_t create(); status_t destroy(); diff --git a/MoveTask.cpp b/MoveTask.cpp index e0eec12..10cd549 100644 --- a/MoveTask.cpp +++ b/MoveTask.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -40,6 +41,8 @@ static const int kMoveFailedInternalError = -6; static const char* kCpPath = "/system/bin/cp"; static const char* kRmPath = "/system/bin/rm"; +static const char* kWakeLock = "MoveTask"; + MoveTask::MoveTask(const std::shared_ptr& from, const std::shared_ptr& to) : mFrom(from), mTo(to) { @@ -168,6 +171,8 @@ static void bringOnline(const std::shared_ptr& vol) { } void MoveTask::run() { + acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLock); + std::string fromPath; std::string toPath; @@ -205,11 +210,13 @@ void MoveTask::run() { } notifyProgress(kMoveSucceeded); + release_wake_lock(kWakeLock); return; fail: bringOnline(mFrom); bringOnline(mTo); notifyProgress(kMoveFailedInternalError); + release_wake_lock(kWakeLock); return; } diff --git a/ResponseCode.h b/ResponseCode.h index 2d01087..f2c533e 100644 --- a/ResponseCode.h +++ b/ResponseCode.h @@ -70,6 +70,7 @@ public: static const int DiskSizeChanged = 641; static const int DiskLabelChanged = 642; static const int DiskScanned = 643; + static const int DiskSysPathChanged = 644; static const int DiskDestroyed = 649; static const int VolumeCreated = 650; @@ -83,6 +84,7 @@ public: static const int MoveStatus = 660; static const int BenchmarkResult = 661; + static const int TrimResult = 662; static int convertFromErrno(); }; diff --git a/TrimTask.cpp b/TrimTask.cpp new file mode 100644 index 0000000..1c6eb1f --- /dev/null +++ b/TrimTask.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "TrimTask.h" +#include "Benchmark.h" +#include "Utils.h" +#include "VolumeManager.h" +#include "ResponseCode.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* From a would-be kernel header */ +#define FIDTRIM _IOWR('f', 128, struct fstrim_range) /* Deep discard trim */ + +#define BENCHMARK_ENABLED 0 + +using android::base::StringPrintf; + +namespace android { +namespace vold { + +static const char* kWakeLock = "TrimTask"; + +TrimTask::TrimTask(int flags) : mFlags(flags) { + // Collect both fstab and vold volumes + addFromFstab(); + + VolumeManager* vm = VolumeManager::Instance(); + std::list privateIds; + vm->listVolumes(VolumeBase::Type::kPrivate, privateIds); + for (auto id : privateIds) { + auto vol = vm->findVolume(id); + if (vol != nullptr && vol->getState() == VolumeBase::State::kMounted) { + mPaths.push_back(vol->getPath()); + } + } +} + +TrimTask::~TrimTask() { +} + +void TrimTask::addFromFstab() { + struct fstab *fstab; + struct fstab_rec *prev_rec = NULL; + + fstab = fs_mgr_read_fstab(android::vold::DefaultFstabPath().c_str()); + for (int i = 0; i < fstab->num_entries; i++) { + /* Skip raw partitions */ + if (!strcmp(fstab->recs[i].fs_type, "emmc") || + !strcmp(fstab->recs[i].fs_type, "mtd")) { + continue; + } + /* Skip read-only filesystems */ + if (fstab->recs[i].flags & MS_RDONLY) { + continue; + } + if (fs_mgr_is_voldmanaged(&fstab->recs[i])) { + continue; /* Should we trim fat32 filesystems? */ + } + if (fs_mgr_is_notrim(&fstab->recs[i])) { + continue; + } + + /* Skip the multi-type partitions, which are required to be following each other. + * See fs_mgr.c's mount_with_alternatives(). + */ + if (prev_rec && !strcmp(prev_rec->mount_point, fstab->recs[i].mount_point)) { + continue; + } + + mPaths.push_back(fstab->recs[i].mount_point); + prev_rec = &fstab->recs[i]; + } + fs_mgr_free_fstab(fstab); +} + +void TrimTask::start() { + mThread = std::thread(&TrimTask::run, this); +} + +static void notifyResult(const std::string& path, int64_t bytes, int64_t delta) { + std::string res(path + + " " + std::to_string(bytes) + + " " + std::to_string(delta)); + VolumeManager::Instance()->getBroadcaster()->sendBroadcast( + ResponseCode::TrimResult, res.c_str(), false); +} + +void TrimTask::run() { + acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLock); + + for (auto path : mPaths) { + LOG(DEBUG) << "Starting trim of " << path; + + int fd = open(path.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW); + if (fd < 0) { + PLOG(WARNING) << "Failed to open " << path; + continue; + } + + struct fstrim_range range; + memset(&range, 0, sizeof(range)); + range.len = ULLONG_MAX; + + nsecs_t start = systemTime(SYSTEM_TIME_BOOTTIME); + if (ioctl(fd, (mFlags & Flags::kDeepTrim) ? FIDTRIM : FITRIM, &range)) { + PLOG(WARNING) << "Trim failed on " << path; + notifyResult(path, -1, -1); + } else { + nsecs_t delta = systemTime(SYSTEM_TIME_BOOTTIME) - start; + LOG(INFO) << "Trimmed " << range.len << " bytes on " << path + << " in " << nanoseconds_to_milliseconds(delta) << "ms"; + notifyResult(path, range.len, delta); + } + close(fd); + + if (mFlags & Flags::kBenchmarkAfter) { +#if BENCHMARK_ENABLED + BenchmarkPrivate(path); +#else + LOG(DEBUG) << "Benchmark disabled"; +#endif + } + } + + release_wake_lock(kWakeLock); +} + +} // namespace vold +} // namespace android diff --git a/TrimTask.h b/TrimTask.h new file mode 100644 index 0000000..57be802 --- /dev/null +++ b/TrimTask.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_VOLD_TRIM_TASK_H +#define ANDROID_VOLD_TRIM_TASK_H + +#include "Utils.h" + +#include +#include + +namespace android { +namespace vold { + +class TrimTask { +public: + TrimTask(int flags); + virtual ~TrimTask(); + + enum Flags { + kDeepTrim = 1 << 0, + kBenchmarkAfter = 1 << 1, + }; + + void start(); + +private: + int mFlags; + std::list mPaths; + std::thread mThread; + + void addFromFstab(); + void run(); + + DISALLOW_COPY_AND_ASSIGN(TrimTask); +}; + +} // namespace vold +} // namespace android + +#endif diff --git a/Utils.cpp b/Utils.cpp index ec9c906..06222c3 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -532,5 +533,11 @@ dev_t GetDevice(const std::string& path) { } } +std::string DefaultFstabPath() { + char hardware[PROPERTY_VALUE_MAX]; + property_get("ro.hardware", hardware, ""); + return StringPrintf("/fstab.%s", hardware); +} + } // namespace vold } // namespace android diff --git a/Utils.h b/Utils.h index ce0f7c8..f33a379 100644 --- a/Utils.h +++ b/Utils.h @@ -92,6 +92,8 @@ std::string BuildKeyPath(const std::string& partGuid); dev_t GetDevice(const std::string& path); +std::string DefaultFstabPath(); + } // namespace vold } // namespace android diff --git a/VolumeManager.cpp b/VolumeManager.cpp index d1a0b2f..6710b0c 100755 --- a/VolumeManager.cpp +++ b/VolumeManager.cpp @@ -60,7 +60,6 @@ #include "Asec.h" #include "VoldUtil.h" #include "cryptfs.h" -#include "fstrim.h" #define MASS_STORAGE_FILE_PATH "/sys/class/android_usb/android0/f_mass_storage/lun/file" @@ -370,20 +369,23 @@ std::shared_ptr VolumeManager::findVolume(const std:: return nullptr; } -nsecs_t VolumeManager::benchmarkVolume(const std::string& id) { +void VolumeManager::listVolumes(android::vold::VolumeBase::Type type, + std::list& list) { + list.clear(); + for (auto disk : mDisks) { + disk->listVolumes(type, list); + } +} + +nsecs_t VolumeManager::benchmarkPrivate(const std::string& id) { std::string path; - std::string sysPath; - auto vol = findVolume(id); - if (vol != nullptr) { - if (vol->getState() == android::vold::VolumeBase::State::kMounted) { - path = vol->getPath(); - auto disk = findDisk(vol->getDiskId()); - if (disk != nullptr) { - sysPath = disk->getSysPath(); - } - } - } else { + if (id == "private" || id == "null") { path = "/data"; + } else { + auto vol = findVolume(id); + if (vol != nullptr && vol->getState() == android::vold::VolumeBase::State::kMounted) { + path = vol->getPath(); + } } if (path.empty()) { @@ -391,20 +393,7 @@ nsecs_t VolumeManager::benchmarkVolume(const std::string& id) { return -1; } - path += "/misc"; - if (android::vold::PrepareDir(path, 01771, AID_SYSTEM, AID_MISC)) { - return -1; - } - path += "/vold"; - if (android::vold::PrepareDir(path, 0700, AID_ROOT, AID_ROOT)) { - return -1; - } - path += "/bench"; - if (android::vold::PrepareDir(path, 0700, AID_ROOT, AID_ROOT)) { - return -1; - } - - return android::vold::Benchmark(path, sysPath); + return android::vold::BenchmarkPrivate(path); } int VolumeManager::forgetPartition(const std::string& partGuid) { diff --git a/VolumeManager.h b/VolumeManager.h index 6c094fc..fa2237f 100644 --- a/VolumeManager.h +++ b/VolumeManager.h @@ -118,7 +118,9 @@ public: std::shared_ptr findDisk(const std::string& id); std::shared_ptr findVolume(const std::string& id); - nsecs_t benchmarkVolume(const std::string& id); + void listVolumes(android::vold::VolumeBase::Type type, std::list& list); + + nsecs_t benchmarkPrivate(const std::string& id); int forgetPartition(const std::string& partGuid); diff --git a/fstrim.c b/fstrim.c deleted file mode 100644 index 60c9f24..0000000 --- a/fstrim.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define LOG_TAG "fstrim" -#include "cutils/log.h" -#include "hardware_legacy/power.h" - -/* These numbers must match what the MountService specified in - * frameworks/base/services/java/com/android/server/EventLogTags.logtags - */ -#define LOG_FSTRIM_START 2755 -#define LOG_FSTRIM_FINISH 2756 - -#define FSTRIM_WAKELOCK "dofstrim" - -#define UNUSED __attribute__((unused)) - -/* From a would-be kernel header */ -#define FIDTRIM _IOWR('f', 128, struct fstrim_range) /* Deep discard trim */ - -static unsigned long long get_boot_time_ms(void) -{ - struct timespec t; - unsigned long long time_ms; - - t.tv_sec = 0; - t.tv_nsec = 0; - clock_gettime(CLOCK_BOOTTIME, &t); - time_ms = (t.tv_sec * 1000LL) + (t.tv_nsec / 1000000); - - return time_ms; -} - -static void *do_fstrim_filesystems(void *thread_arg) -{ - int i; - int fd; - int ret = 0; - struct fstrim_range range = { 0 }; - extern struct fstab *fstab; - int deep_trim = !!thread_arg; - struct fstab_rec *prev_rec = NULL; - - SLOGI("Starting fstrim work...\n"); - - /* Get a wakelock as this may take a while, and we don't want the - * device to sleep on us. - */ - acquire_wake_lock(PARTIAL_WAKE_LOCK, FSTRIM_WAKELOCK); - - /* Log the start time in the event log */ - LOG_EVENT_LONG(LOG_FSTRIM_START, get_boot_time_ms()); - - for (i = 0; i < fstab->num_entries; i++) { - /* Skip raw partitions */ - if (!strcmp(fstab->recs[i].fs_type, "emmc") || - !strcmp(fstab->recs[i].fs_type, "mtd")) { - continue; - } - /* Skip read-only filesystems */ - if (fstab->recs[i].flags & MS_RDONLY) { - continue; - } - if (fs_mgr_is_voldmanaged(&fstab->recs[i])) { - continue; /* Should we trim fat32 filesystems? */ - } - if (fs_mgr_is_notrim(&fstab->recs[i])) { - continue; - } - - /* Skip the multi-type partitions, which are required to be following each other. - * See fs_mgr.c's mount_with_alternatives(). - */ - if (prev_rec && !strcmp(prev_rec->mount_point, fstab->recs[i].mount_point)) { - continue; - } - - fd = open(fstab->recs[i].mount_point, O_RDONLY | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW); - if (fd < 0) { - SLOGE("Cannot open %s for FITRIM\n", fstab->recs[i].mount_point); - ret = -1; - continue; - } - - memset(&range, 0, sizeof(range)); - range.len = ULLONG_MAX; - SLOGI("Invoking %s ioctl on %s", deep_trim ? "FIDTRIM" : "FITRIM", fstab->recs[i].mount_point); - - ret = ioctl(fd, deep_trim ? FIDTRIM : FITRIM, &range); - if (ret) { - SLOGE("%s ioctl failed on %s (error %d/%s)", deep_trim ? "FIDTRIM" : "FITRIM", fstab->recs[i].mount_point, errno, strerror(errno)); - ret = -1; - } else { - SLOGI("Trimmed %llu bytes on %s\n", range.len, fstab->recs[i].mount_point); - } - close(fd); - prev_rec = &fstab->recs[i]; - } - - /* Log the finish time in the event log */ - LOG_EVENT_LONG(LOG_FSTRIM_FINISH, get_boot_time_ms()); - - SLOGI("Finished fstrim work.\n"); - - /* Release the wakelock that let us work */ - release_wake_lock(FSTRIM_WAKELOCK); - - return (void *)(uintptr_t)ret; -} - -int fstrim_filesystems(int deep_trim) -{ - pthread_t t; - int ret; - - /* Depending on the emmc chip and size, this can take upwards - * of a few minutes. If done in the same thread as the caller - * of this function, that would block vold from accepting any - * commands until the trim is finished. So start another thread - * to do the work, and return immediately. - * - * This function should not be called more than once per day, but - * even if it is called a second time before the first one finishes, - * the kernel will "do the right thing" and split the work between - * the two ioctls invoked in separate threads. - */ - ret = pthread_create(&t, NULL, do_fstrim_filesystems, (void *)(intptr_t)deep_trim); - if (ret) { - SLOGE("Cannot create thread to do fstrim"); - return ret; - } - - ret = pthread_detach(t); - if (ret) { - SLOGE("Cannot detach thread doing fstrim"); - return ret; - } - - return 0; -} diff --git a/fstrim.h b/fstrim.h deleted file mode 100644 index 185d998..0000000 --- a/fstrim.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef __cplusplus -extern "C" { -#endif - int fstrim_filesystems(int deep_trim); -#ifdef __cplusplus -} -#endif - diff --git a/main.cpp b/main.cpp index abdff9f..648f36a 100644 --- a/main.cpp +++ b/main.cpp @@ -208,25 +208,15 @@ static void coldboot(const char *path) { } static int process_config(VolumeManager *vm) { - bool has_adoptable = false; - char hardware[PROPERTY_VALUE_MAX]; - property_get("ro.hardware", hardware, ""); - std::string fstab_filename(StringPrintf("/fstab.%s", hardware)); - -#ifdef DEBUG_FSTAB - if (access(DEBUG_FSTAB, R_OK) == 0) { - LOG(DEBUG) << "Found debug fstab; switching!"; - fstab_filename = DEBUG_FSTAB; - } -#endif - - fstab = fs_mgr_read_fstab(fstab_filename.c_str()); + std::string path(android::vold::DefaultFstabPath()); + fstab = fs_mgr_read_fstab(path.c_str()); if (!fstab) { - PLOG(ERROR) << "Failed to open " << fstab_filename; + PLOG(ERROR) << "Failed to open default fstab " << path; return -1; } /* Loop through entries looking for ones that vold manages */ + bool has_adoptable = false; for (int i = 0; i < fstab->num_entries; i++) { if (fs_mgr_is_voldmanaged(&fstab->recs[i])) { if (fs_mgr_is_nonremovable(&fstab->recs[i])) {