Skip to content

Instantly share code, notes, and snippets.

@adrian-bl
Created May 12, 2015 07:47
Show Gist options
  • Save adrian-bl/329af835abadf7e0a8cb to your computer and use it in GitHub Desktop.
Save adrian-bl/329af835abadf7e0a8cb to your computer and use it in GitHub Desktop.
diff --git a/Ext4.cpp b/Ext4.cpp
index dc31fd0..3be0b9a 100644
--- a/Ext4.cpp
+++ b/Ext4.cpp
@@ -159,3 +159,48 @@ int Ext4::format(const char *fsPath, unsigned int numSectors, const char *mountp
}
return 0;
}
+
+int Ext4::check(const char *fsPath) {
+ int rc = 0;
+ int status;
+
+ const char *args[3];
+ args[0] = "/system/bin/e2fsck";
+ args[1] = "-p";
+ args[2] = fsPath;
+
+ rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status,
+ false, true);
+
+ if (rc != 0) {
+ SLOGE("Filesystem (ext4) check failed due to logwrap error");
+ errno = EIO;
+ return -1;
+ }
+
+ if (!WIFEXITED(status)) {
+ SLOGE("Filesystem (ext4) check did not exit properly");
+ errno = EIO;
+ return -1;
+ }
+
+ status = WEXITSTATUS(status);
+
+ switch(status) {
+ case 0:
+ case 1:
+ case 2:
+ SLOGW("ext4fs: Filesystem check exited with state %d\n", status);
+ return 0;
+ case 8:
+ SLOGW("ext4fs: Filesystem check returned operational error\n");
+ errno = ENODATA;
+ return -1;
+ default:
+ SLOGW("ext4fs: Filesystem check returned unknown error: %d\n", status);
+ errno = EIO;
+ return -1;
+ }
+ // not reached
+ return -1;
+}
diff --git a/Ext4.h b/Ext4.h
index c768f5a..71579ce 100644
--- a/Ext4.h
+++ b/Ext4.h
@@ -25,6 +25,7 @@ public:
bool executable);
static int format(const char *fsPath, unsigned int numSectors, const char *mountpoint);
static int resize(const char *fsPath, unsigned int numSectors);
+ static int check(const char *fsPath);
};
#endif
diff --git a/Volume.cpp b/Volume.cpp
index ca56d1c..43c5f45 100644
--- a/Volume.cpp
+++ b/Volume.cpp
@@ -46,6 +46,7 @@
#include "VolumeManager.h"
#include "ResponseCode.h"
#include "Fat.h"
+#include "Ext4.h"
#include "Process.h"
#include "cryptfs.h"
@@ -414,6 +415,7 @@ int Volume::mountVol() {
for (i = 0; i < n; i++) {
char devicePath[255];
+ bool isExt4 = false;
sprintf(devicePath, "/dev/block/vold/%d:%d", major(deviceNodes[i]),
minor(deviceNodes[i]));
@@ -426,7 +428,8 @@ int Volume::mountVol() {
if (Fat::check(devicePath)) {
if (errno == ENODATA) {
SLOGW("%s does not contain a FAT filesystem\n", devicePath);
- continue;
+ isExt4 = true;
+ goto TRY_EXT4;
}
errno = EIO;
/* Badness - abort the mount */
@@ -435,13 +438,34 @@ int Volume::mountVol() {
return -1;
}
+TRY_EXT4:
+ if (isExt4) { // dosfsck failed, but we may try it as ext4
+ if (Ext4::check(devicePath)) {
+ SLOGW("%s does not contain a Ext4 filesystem\n", devicePath);
+ continue;
+ } else {
+ SLOGW("%s passed e2fsck\n", devicePath);
+ }
+ }
+
errno = 0;
int gid;
- if (Fat::doMount(devicePath, getMountpoint(), false, false, false,
- AID_MEDIA_RW, AID_MEDIA_RW, 0007, true)) {
- SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno));
- continue;
+ if (isExt4) {
+ if (Ext4::doMount(devicePath, getMountpoint(), false, false, false)) {
+ SLOGE("%s failed to mount via EXT4 (%s)\n", devicePath, strerror(errno));
+ continue;
+ }
+ SLOGE("%s was mounted as an ext4fs\n", devicePath);
+ SLOGE("--> WARNING: If this device was mounted for the first time, you *MUST* run...\n");
+ SLOGE("# restorecon -r %s ; chmod 0770 %s ; chown %d:%d %s\n", getMountpoint(), getMountpoint(), AID_MEDIA_RW, AID_MEDIA_RW, getMountpoint());
+ SLOGE("--> WARNING: ...to make the sdcard useable\n");
+ } else {
+ if (Fat::doMount(devicePath, getMountpoint(), false, false, false,
+ AID_MEDIA_RW, AID_MEDIA_RW, 0007, true)) {
+ SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno));
+ continue;
+ }
}
extractMetadata(devicePath);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment