diff --git a/DirectVolume.cpp b/DirectVolume.cpp index 515a33a..cd12cf4 100644 --- a/DirectVolume.cpp +++ b/DirectVolume.cpp @@ -31,6 +31,8 @@ DirectVolume::DirectVolume(const char *label, const char *mount_point, int partI mPartIdx = partIdx; mPaths = new PathCollection(); + for (int i = 0; i < MAX_PARTITIONS; i++) + mPartMinors[i] = -1; } DirectVolume::~DirectVolume() { @@ -80,7 +82,8 @@ int DirectVolume::handleBlockEvent(NetlinkEvent *evt) { } 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 @@ void DirectVolume::handlePartitionAdded(const char *devpath, NetlinkEvent *evt) 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::handleDiskRemoved(const char *devpath, NetlinkEvent *evt) { 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 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 @@ void Volume::setState(int state) { 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 @@ int Volume::mount() { 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 @@ protected: virtual int prepareToMount(int *major, int *minor) = 0; + int createDeviceNode(const char *path, int major, int minor); + private: int checkFilesystem(const char *nodepath); };