vold2: Some more work on partitioning support

Signed-off-by: San Mehat <san@google.com>
diff --git a/DirectVolume.cpp b/DirectVolume.cpp
index 515a33a..cd12cf4 100644
--- a/DirectVolume.cpp
+++ b/DirectVolume.cpp
@@ -31,6 +31,8 @@
     mPartIdx = partIdx;
   
     mPaths = new PathCollection();
+    for (int i = 0; i < MAX_PARTITIONS; i++)
+        mPartMinors[i] = -1;
 }
 
 DirectVolume::~DirectVolume() {
@@ -80,7 +82,8 @@
 }
 
 void DirectVolume::handleDiskAdded(const char *devpath, NetlinkEvent *evt) {
-    mDiskMaj = atoi(evt->findParam("MAJOR"));
+    mDiskMajor = atoi(evt->findParam("MAJOR"));
+    mDiskMinor = atoi(evt->findParam("MAJOR"));
     mDiskNumParts = atoi(evt->findParam("NPARTS"));
 
     int partmask = 0;
@@ -105,6 +108,12 @@
     int minor = atoi(evt->findParam("MINOR"));
     int part_num = atoi(evt->findParam("PARTN"));
 
+    if (major != mDiskMajor) {
+        LOGE("Partition '%s' has a different major than its disk!", devpath);
+        return;
+    }
+    mPartMinors[part_num -1] = minor;
+
     mPendingPartMap &= ~(1 << part_num);
     if (!mPendingPartMap) {
         LOGD("Dv:partAdd: Got all partitions - ready to rock!");
@@ -120,7 +129,37 @@
 void DirectVolume::handlePartitionRemoved(const char *devpath, NetlinkEvent *evt) {
 }
 
+/*
+ * Called from Volume to determine the major/minor numbers
+ * to be used for mounting
+ */
 int DirectVolume::prepareToMount(int *major, int *minor) {
-    errno = ENOSYS;
-    return -1;
+    *major = mDiskMajor;
+
+    if (mPartIdx == -1) {
+        /* No specific partition specified */
+
+        if (!mDiskNumParts) {
+            *minor = mDiskMinor;
+            return 0;
+        }
+
+        /* 
+         * XXX: Use first partition for now.
+         * The right thing to do would be to choose
+         * this based on the partition type.
+         *
+         */
+  
+        *minor = mPartMinors[0];
+        return 0;
+    }
+
+    if (mPartIdx - 1 > mDiskNumParts) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    *minor = mPartMinors[mPartIdx-1];
+    return 0;
 }
diff --git a/DirectVolume.h b/DirectVolume.h
index 3dbe76c..a66d27a 100644
--- a/DirectVolume.h
+++ b/DirectVolume.h
@@ -21,13 +21,19 @@
 
 #include "Volume.h"
 
+#define MAX_PARTS 4
+
 typedef android::List<char *> PathCollection;
 
 class DirectVolume : public Volume {
+public:
+    static const int MAX_PARTITIONS = 4;
 protected:
     PathCollection *mPaths;
     int            mPartIdx;
-    int            mDiskMaj;
+    int            mDiskMajor;
+    int            mDiskMinor;
+    int            mPartMinors[MAX_PARTITIONS];
     int            mDiskNumParts;
     unsigned char  mPendingPartMap;
 
diff --git a/Volume.cpp b/Volume.cpp
index 75767e9..bdd0ada 100644
--- a/Volume.cpp
+++ b/Volume.cpp
@@ -56,6 +56,17 @@
     mState = state;
 }
 
+int Volume::createDeviceNode(const char *path, int major, int minor) {
+    mode_t mode = 0660 | S_IFBLK;
+    dev_t dev = (major << 8) | minor;
+    if (mknod(path, mode, dev) < 0) {
+        if (errno != EEXIST) {
+            return -1;
+        }
+    }
+    return 0;
+}
+
 int Volume::mount() {
     char nodepath[255];
     int major = -1, minor = -1;
@@ -65,22 +76,27 @@
         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));
+
+    LOGD("nodepath = %s\n", nodepath);
+
+    /* Create device nodes */
+    if (createDeviceNode(nodepath, major, minor)) {
+        LOGE("Error making device nodes for '%s' (%s)", nodepath,
+             strerror(errno));
+        // XXX: cleanup will be needed eventually
         return -1;
     }
 
     /* Run disk checker */
     if (checkFilesystem(nodepath)) {
+        LOGE("Error checking filesystem (%s)", strerror(errno));
         setState(Volume::State_Idle);
         return -1;
     }
 
+    
+
     setState(Volume::State_Idle);
     return 0;
 }
diff --git a/Volume.h b/Volume.h
index 70169f6..689cd53 100644
--- a/Volume.h
+++ b/Volume.h
@@ -55,6 +55,8 @@
 
     virtual int prepareToMount(int *major, int *minor) = 0;
 
+    int createDeviceNode(const char *path, int major, int minor);
+
 private:
     int checkFilesystem(const char *nodepath);
 };