am c86ab6f5: Trim both internal and adopted private storage.

* commit 'c86ab6f538bec63638c168d6c843fe7cf73add3b':
  Trim both internal and adopted private storage.
gugelfrei
Jeff Sharkey 9 years ago committed by Android Git Automerger
commit 3ff337db56

@ -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 \

@ -22,6 +22,7 @@
#include <base/file.h>
#include <base/logging.h>
#include <cutils/iosched_policy.h>
#include <private/android_filesystem_config.h>
#include <sys/time.h>
#include <sys/resource.h>
@ -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,38 +123,26 @@ 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");
// 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;
}
notifyResult(path, create_d, drop_d, run_d, destroy_d);
VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
ResponseCode::BenchmarkResult, detail.c_str(), false);
return run_d;
}
if (chdir(orig_cwd) != 0) {
PLOG(ERROR) << "Failed to chdir";
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;
}
if (android_set_ioprio(0, orig_clazz, orig_ioprio)) {
PLOG(ERROR) << "Failed to android_set_ioprio";
benchPath += "/vold";
if (android::vold::PrepareDir(benchPath, 0700, AID_ROOT, AID_ROOT)) {
return -1;
}
if (setpriority(PRIO_PROCESS, 0, orig_prio) != 0) {
PLOG(ERROR) << "Failed to setpriority";
benchPath += "/bench";
if (android::vold::PrepareDir(benchPath, 0700, AID_ROOT, AID_ROOT)) {
return -1;
}
return run_d;
return benchmark(benchPath);
}
} // namespace vold

@ -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

@ -46,8 +46,8 @@
#include "Devmapper.h"
#include "Ext4Crypt.h"
#include "cryptfs.h"
#include "fstrim.h"
#include "MoveTask.h"
#include "TrimTask.h"
#define DUMP_ARGS 0
@ -256,7 +256,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);
@ -601,32 +601,23 @@ int CommandListener::FstrimCmd::runCommand(SocketClient *cli,
return 0;
}
int rc = 0;
VolumeManager *vm = VolumeManager::Instance();
std::lock_guard<std::mutex> 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;
// 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);
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;
}
return 0;
(new android::vold::TrimTask(flags))->start();
return sendGenericOkFail(cli, 0);
}

@ -105,6 +105,15 @@ std::shared_ptr<VolumeBase> Disk::findVolume(const std::string& id) {
return nullptr;
}
void Disk::listVolumes(VolumeBase::Type type, std::list<std::string>& 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;
}

@ -18,6 +18,7 @@
#define ANDROID_VOLD_DISK_H
#include "Utils.h"
#include "VolumeBase.h"
#include <utils/Errors.h>
@ -64,6 +65,8 @@ public:
std::shared_ptr<VolumeBase> findVolume(const std::string& id);
void listVolumes(VolumeBase::Type type, std::list<std::string>& list);
status_t create();
status_t destroy();

@ -22,6 +22,7 @@
#include <base/stringprintf.h>
#include <base/logging.h>
#include <private/android_filesystem_config.h>
#include <hardware_legacy/power.h>
#include <dirent.h>
#include <sys/wait.h>
@ -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<VolumeBase>& from,
const std::shared_ptr<VolumeBase>& to) :
mFrom(from), mTo(to) {
@ -168,6 +171,8 @@ static void bringOnline(const std::shared_ptr<VolumeBase>& 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;
}

@ -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();
};

@ -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 <base/stringprintf.h>
#include <base/logging.h>
#include <cutils/properties.h>
#include <fs_mgr.h>
#include <private/android_filesystem_config.h>
#include <hardware_legacy/power.h>
#include <dirent.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
/* 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<std::string> 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

@ -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 <thread>
#include <list>
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<std::string> mPaths;
std::thread mThread;
void addFromFstab();
void run();
DISALLOW_COPY_AND_ASSIGN(TrimTask);
};
} // namespace vold
} // namespace android
#endif

@ -22,6 +22,7 @@
#include <base/logging.h>
#include <base/stringprintf.h>
#include <cutils/fs.h>
#include <cutils/properties.h>
#include <private/android_filesystem_config.h>
#include <logwrap/logwrap.h>
@ -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

@ -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

@ -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<android::vold::VolumeBase> VolumeManager::findVolume(const std::
return nullptr;
}
nsecs_t VolumeManager::benchmarkVolume(const std::string& id) {
void VolumeManager::listVolumes(android::vold::VolumeBase::Type type,
std::list<std::string>& 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) {
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();
auto disk = findDisk(vol->getDiskId());
if (disk != nullptr) {
sysPath = disk->getSysPath();
}
}
} else {
path = "/data";
}
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) {

@ -118,7 +118,9 @@ public:
std::shared_ptr<android::vold::Disk> findDisk(const std::string& id);
std::shared_ptr<android::vold::VolumeBase> findVolume(const std::string& id);
nsecs_t benchmarkVolume(const std::string& id);
void listVolumes(android::vold::VolumeBase::Type type, std::list<std::string>& list);
nsecs_t benchmarkPrivate(const std::string& id);
int forgetPartition(const std::string& partGuid);

@ -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 <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>
#include <limits.h>
#include <linux/fs.h>
#include <time.h>
#include <fs_mgr.h>
#include <pthread.h>
#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;
}

@ -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

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

Loading…
Cancel
Save