Merge "vold: set klog level so e2fsck output is logged" into jb-mr2-dev
diff --git a/Android.mk b/Android.mk
index d13fa8b..098c3d0 100644
--- a/Android.mk
+++ b/Android.mk
@@ -15,6 +15,7 @@
Devmapper.cpp \
ResponseCode.cpp \
Xwarp.cpp \
+ fstrim.c \
cryptfs.c
common_c_includes := \
@@ -25,6 +26,7 @@
common_shared_libraries := \
libsysutils \
libcutils \
+ liblog \
libdiskconfig \
libhardware_legacy \
liblogwrap \
diff --git a/CommandListener.cpp b/CommandListener.cpp
index 2986cac..f8baff5 100644
--- a/CommandListener.cpp
+++ b/CommandListener.cpp
@@ -38,6 +38,7 @@
#include "Loop.h"
#include "Devmapper.h"
#include "cryptfs.h"
+#include "fstrim.h"
#define DUMP_ARGS 0
@@ -50,6 +51,7 @@
registerCmd(new StorageCmd());
registerCmd(new XwarpCmd());
registerCmd(new CryptfsCmd());
+ registerCmd(new FstrimCmd());
}
void CommandListener::dumpArgs(int argc, char **argv, int argObscure) {
@@ -609,3 +611,41 @@
return 0;
}
+
+CommandListener::FstrimCmd::FstrimCmd() :
+ VoldCommand("fstrim") {
+}
+int CommandListener::FstrimCmd::runCommand(SocketClient *cli,
+ int argc, char **argv) {
+ if ((cli->getUid() != 0) && (cli->getUid() != AID_SYSTEM)) {
+ cli->sendMsg(ResponseCode::CommandNoPermission, "No permission to run fstrim commands", false);
+ return 0;
+ }
+
+ if (argc < 2) {
+ cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
+ return 0;
+ }
+
+ int rc = 0;
+
+ 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();
+ } else {
+ dumpArgs(argc, argv, -1);
+ cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown fstrim cmd", false);
+ }
+
+ // 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;
+}
diff --git a/CommandListener.h b/CommandListener.h
index 4ef4a0c..8cc5b09 100644
--- a/CommandListener.h
+++ b/CommandListener.h
@@ -78,6 +78,13 @@
virtual ~CryptfsCmd() {}
int runCommand(SocketClient *c, int argc, char ** argv);
};
+
+ class FstrimCmd : public VoldCommand {
+ public:
+ FstrimCmd();
+ virtual ~FstrimCmd() {}
+ int runCommand(SocketClient *c, int argc, char ** argv);
+ };
};
#endif
diff --git a/fstrim.c b/fstrim.c
new file mode 100644
index 0000000..156446a
--- /dev/null
+++ b/fstrim.c
@@ -0,0 +1,86 @@
+/*
+ * 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 <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <limits.h>
+#include <linux/fs.h>
+#include <fs_mgr.h>
+#define LOG_TAG "fstrim"
+#include "cutils/log.h"
+
+int fstrim_filesystems(void)
+{
+ int i;
+ int fd;
+ int ret = 0;
+ struct fstrim_range range = { 0 };
+ struct stat sb;
+ extern struct fstab *fstab;
+
+ SLOGI("Starting fstrim work...\n");
+
+ 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 (stat(fstab->recs[i].mount_point, &sb) == -1) {
+ SLOGE("Cannot stat mount point %s\n", fstab->recs[i].mount_point);
+ ret = -1;
+ continue;
+ }
+ if (!S_ISDIR(sb.st_mode)) {
+ SLOGE("%s is not a directory\n", fstab->recs[i].mount_point);
+ ret = -1;
+ continue;
+ }
+
+ fd = open(fstab->recs[i].mount_point, O_RDONLY);
+ 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 FITRIM ioctl on %s", fstab->recs[i].mount_point);
+ if (ioctl(fd, FITRIM, &range)) {
+ SLOGE("FITRIM ioctl failed on %s", fstab->recs[i].mount_point);
+ ret = -1;
+ }
+ SLOGI("Trimmed %llu bytes on %s\n", range.len, fstab->recs[i].mount_point);
+ close(fd);
+ }
+ SLOGI("Finished fstrim work.\n");
+
+ return ret;
+}
+
diff --git a/fstrim.h b/fstrim.h
new file mode 100644
index 0000000..e46e804
--- /dev/null
+++ b/fstrim.h
@@ -0,0 +1,24 @@
+/*
+ * 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(void);
+#ifdef __cplusplus
+}
+#endif
+