vold2: Wire up more of the mount function

Signed-off-by: San Mehat <san@android.com>
diff --git a/Volume.cpp b/Volume.cpp
index 52d02cf..75767e9 100644
--- a/Volume.cpp
+++ b/Volume.cpp
@@ -14,9 +14,16 @@
  * limitations under the License.
  */
 
-#include <stdio.h>
-#include <errno.h>
+#include <stdlib.h>
 #include <string.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
 
 #define LOG_TAG "Vold"
 
@@ -24,6 +31,10 @@
 
 #include "Volume.h"
 
+extern "C" int logwrap(int argc, const char **argv, int background);
+
+static char FSCK_MSDOS_PATH[] = "/system/bin/fsck_msdos";
+
 Volume::Volume(const char *label, const char *mount_point) {
     mLabel = strdup(label);
     mMountpoint = strdup(mount_point);
@@ -44,3 +55,87 @@
     LOGD("Volume %s state changing %d -> %d", mLabel, mState, state);
     mState = state;
 }
+
+int Volume::mount() {
+    char nodepath[255];
+    int major = -1, minor = -1;
+
+    if (prepareToMount(&major, &minor)) {
+        LOGE("Volume failed to prepare: %s", strerror(errno));
+        return -1;
+    }
+
+    /* Create device nodes */
+    mode_t mode = 0660 | S_IFBLK;
+    dev_t dev = (major << 8) | minor;
+    sprintf(nodepath, "/dev/block/vold/%d:%d", major, minor);
+    if (mknod(nodepath, mode, dev) < 0) {
+        LOGE("Error making device nodes for '%s' (%s)",
+             nodepath, strerror(errno));
+        return -1;
+    }
+
+    /* Run disk checker */
+    if (checkFilesystem(nodepath)) {
+        setState(Volume::State_Idle);
+        return -1;
+    }
+
+    setState(Volume::State_Idle);
+    return 0;
+}
+
+int Volume::checkFilesystem(const char *nodepath) {
+
+    bool rw = true;
+    if (access(FSCK_MSDOS_PATH, X_OK)) {
+        LOGW("Skipping fs checks\n");
+        return 0;
+    }
+
+    setState(Volume::State_Checking);
+    int pass = 1;
+    int rc = 0;
+    do {
+        const char *args[5];
+        args[0] = FSCK_MSDOS_PATH;
+        args[1] = "-p";
+        args[2] = "-f";
+        args[3] = nodepath;
+        args[4] = NULL;
+
+        rc = logwrap(4, args, 1);
+
+        switch(rc) {
+        case 0:
+            LOGI("Filesystem check completed OK");
+            return 0;
+
+        case 2:
+            LOGE("Filesystem check failed (not a FAT filesystem)");
+            errno = ENODATA;
+            return -1;
+
+        case 4:
+            if (pass++ <= 3) {
+                LOGW("Filesystem modified - rechecking (pass %d)",
+                        pass);
+                continue;
+            }
+            LOGE("Failing check after too many rechecks");
+            errno = EIO;
+            return -1;
+
+        default:
+            LOGE("Filesystem check failed (unknown exit code %d)", rc);
+            errno = EIO;
+            return -1;
+        }
+    } while (0);
+
+    return 0;
+}
+
+int Volume::unmount() {
+    return 0;
+}