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])) {