diff --git a/Android.mk b/Android.mk
index 3aa12a5..4563abf 100644
--- a/Android.mk
+++ b/Android.mk
@@ -6,8 +6,6 @@
 	VoldCommand.cpp \
 	NetlinkManager.cpp \
 	NetlinkHandler.cpp \
-	Volume.cpp \
-	DirectVolume.cpp \
 	Process.cpp \
 	Ext4.cpp \
 	Fat.cpp \
diff --git a/CommandListener.cpp b/CommandListener.cpp
index 5e51116..813d831 100644
--- a/CommandListener.cpp
+++ b/CommandListener.cpp
@@ -349,8 +349,8 @@
     if (!strcmp(argv[1], "list")) {
         dumpArgs(argc, argv, -1);
 
-        listAsecsInDirectory(cli, Volume::SEC_ASECDIR_EXT);
-        listAsecsInDirectory(cli, Volume::SEC_ASECDIR_INT);
+        listAsecsInDirectory(cli, VolumeManager::SEC_ASECDIR_EXT);
+        listAsecsInDirectory(cli, VolumeManager::SEC_ASECDIR_INT);
     } else if (!strcmp(argv[1], "create")) {
         dumpArgs(argc, argv, 5);
         if (argc != 8) {
diff --git a/DirectVolume.cpp b/DirectVolume.cpp
deleted file mode 100644
index 6118453..0000000
--- a/DirectVolume.cpp
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- * Copyright (C) 2008 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <fnmatch.h>
-
-#include <linux/kdev_t.h>
-
-#define LOG_TAG "DirectVolume"
-
-#include <cutils/log.h>
-#include <sysutils/NetlinkEvent.h>
-
-#include "DirectVolume.h"
-#include "VolumeManager.h"
-#include "ResponseCode.h"
-#include "cryptfs.h"
-
-// #define PARTITION_DEBUG
-
-PathInfo::PathInfo(const char *p)
-{
-    warned = false;
-    pattern = strdup(p);
-
-    if (!strchr(pattern, '*')) {
-        patternType = prefix;
-    } else {
-        patternType = wildcard;
-    }
-}
-
-PathInfo::~PathInfo()
-{
-    free(pattern);
-}
-
-bool PathInfo::match(const char *path)
-{
-    switch (patternType) {
-    case prefix:
-    {
-        bool ret = (strncmp(path, pattern, strlen(pattern)) == 0);
-        if (!warned && ret && (strlen(pattern) != strlen(path))) {
-            SLOGW("Deprecated implied prefix pattern detected, please use '%s*' instead", pattern);
-            warned = true;
-        }
-        return ret;
-    }
-    case wildcard:
-        return fnmatch(pattern, path, 0) == 0;
-    }
-    SLOGE("Bad matching type");
-    return false;
-}
-
-DirectVolume::DirectVolume(VolumeManager *vm, const fstab_rec* rec, int flags) :
-        Volume(vm, rec, flags) {
-    mPaths = new PathCollection();
-    for (int i = 0; i < MAX_PARTITIONS; i++)
-        mPartMinors[i] = -1;
-    mPendingPartCount = 0;
-    mDiskMajor = -1;
-    mDiskMinor = -1;
-    mDiskNumParts = 0;
-    mIsDecrypted = 0;
-
-    if (strcmp(rec->mount_point, "auto") != 0) {
-        ALOGE("Vold managed volumes must have auto mount point; ignoring %s",
-              rec->mount_point);
-    }
-
-    char mount[PATH_MAX];
-
-    snprintf(mount, PATH_MAX, "%s/%s", Volume::MEDIA_DIR, rec->label);
-    mMountpoint = strdup(mount);
-    snprintf(mount, PATH_MAX, "%s/%s", Volume::FUSE_DIR, rec->label);
-    mFuseMountpoint = strdup(mount);
-
-    setState(Volume::State_NoMedia);
-}
-
-DirectVolume::~DirectVolume() {
-    PathCollection::iterator it;
-
-    for (it = mPaths->begin(); it != mPaths->end(); ++it)
-        delete *it;
-    delete mPaths;
-}
-
-int DirectVolume::addPath(const char *path) {
-    mPaths->push_back(new PathInfo(path));
-    return 0;
-}
-
-dev_t DirectVolume::getDiskDevice() {
-    return MKDEV(mDiskMajor, mDiskMinor);
-}
-
-dev_t DirectVolume::getShareDevice() {
-    if (mPartIdx != -1) {
-        return MKDEV(mDiskMajor, mPartIdx);
-    } else {
-        return MKDEV(mDiskMajor, mDiskMinor);
-    }
-}
-
-void DirectVolume::handleVolumeShared() {
-    setState(Volume::State_Shared);
-}
-
-void DirectVolume::handleVolumeUnshared() {
-    setState(Volume::State_Idle);
-}
-
-int DirectVolume::handleBlockEvent(NetlinkEvent *evt) {
-    const char *dp = evt->findParam("DEVPATH");
-
-    PathCollection::iterator  it;
-    for (it = mPaths->begin(); it != mPaths->end(); ++it) {
-        if ((*it)->match(dp)) {
-            /* We can handle this disk */
-            NetlinkEvent::Action action = evt->getAction();
-            const char *devtype = evt->findParam("DEVTYPE");
-
-            if (action == NetlinkEvent::Action::kAdd) {
-                int major = atoi(evt->findParam("MAJOR"));
-                int minor = atoi(evt->findParam("MINOR"));
-                char nodepath[255];
-
-                snprintf(nodepath,
-                         sizeof(nodepath), "/dev/block/vold/%d:%d",
-                         major, minor);
-                if (createDeviceNode(nodepath, major, minor)) {
-                    SLOGE("Error making device node '%s' (%s)", nodepath,
-                                                               strerror(errno));
-                }
-                if (!strcmp(devtype, "disk")) {
-                    handleDiskAdded(dp, evt);
-                } else {
-                    handlePartitionAdded(dp, evt);
-                }
-                /* Send notification iff disk is ready (ie all partitions found) */
-                if (getState() == Volume::State_Idle) {
-                    char msg[255];
-
-                    snprintf(msg, sizeof(msg),
-                             "Volume %s %s disk inserted (%d:%d)", getLabel(),
-                             getFuseMountpoint(), mDiskMajor, mDiskMinor);
-                    mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeDiskInserted,
-                                                         msg, false);
-                }
-            } else if (action == NetlinkEvent::Action::kRemove) {
-                if (!strcmp(devtype, "disk")) {
-                    handleDiskRemoved(dp, evt);
-                } else {
-                    handlePartitionRemoved(dp, evt);
-                }
-            } else if (action == NetlinkEvent::Action::kChange) {
-                if (!strcmp(devtype, "disk")) {
-                    handleDiskChanged(dp, evt);
-                } else {
-                    handlePartitionChanged(dp, evt);
-                }
-            } else {
-                    SLOGW("Ignoring non add/remove/change event");
-            }
-
-            return 0;
-        }
-    }
-    errno = ENODEV;
-    return -1;
-}
-
-void DirectVolume::handleDiskAdded(const char * /*devpath*/,
-                                   NetlinkEvent *evt) {
-    mDiskMajor = atoi(evt->findParam("MAJOR"));
-    mDiskMinor = atoi(evt->findParam("MINOR"));
-
-    const char *tmp = evt->findParam("NPARTS");
-    if (tmp) {
-        mDiskNumParts = atoi(tmp);
-    } else {
-        SLOGW("Kernel block uevent missing 'NPARTS'");
-        mDiskNumParts = 1;
-    }
-
-    mPendingPartCount = mDiskNumParts;
-    for (int i = 0; i < MAX_PARTITIONS; i++)
-        mPartMinors[i] = -1;
-
-    if (mDiskNumParts == 0) {
-#ifdef PARTITION_DEBUG
-        SLOGD("Dv::diskIns - No partitions - good to go son!");
-#endif
-        setState(Volume::State_Idle);
-    } else {
-#ifdef PARTITION_DEBUG
-        SLOGD("Dv::diskIns - waiting for %d pending partitions", mPendingPartCount);
-#endif
-        setState(Volume::State_Pending);
-    }
-}
-
-void DirectVolume::handlePartitionAdded(const char *devpath, NetlinkEvent *evt) {
-    int major = atoi(evt->findParam("MAJOR"));
-    int minor = atoi(evt->findParam("MINOR"));
-
-    int part_num;
-
-    const char *tmp = evt->findParam("PARTN");
-
-    if (tmp) {
-        part_num = atoi(tmp);
-    } else {
-        SLOGW("Kernel block uevent missing 'PARTN'");
-        part_num = 1;
-    }
-
-    if (part_num > MAX_PARTITIONS || part_num < 1) {
-        SLOGE("Invalid 'PARTN' value");
-        return;
-    }
-
-    if (part_num > mDiskNumParts) {
-        mDiskNumParts = part_num;
-    }
-
-    if (major != mDiskMajor) {
-        SLOGE("Partition '%s' has a different major than its disk!", devpath);
-        return;
-    }
-#ifdef PARTITION_DEBUG
-    SLOGD("Dv:partAdd: part_num = %d, minor = %d\n", part_num, minor);
-#endif
-    if (part_num >= MAX_PARTITIONS) {
-        SLOGE("Dv:partAdd: ignoring part_num = %d (max: %d)\n", part_num, MAX_PARTITIONS-1);
-    } else {
-        if ((mPartMinors[part_num - 1] == -1) && mPendingPartCount)
-            mPendingPartCount--;
-        mPartMinors[part_num -1] = minor;
-    }
-
-    if (!mPendingPartCount) {
-#ifdef PARTITION_DEBUG
-        SLOGD("Dv:partAdd: Got all partitions - ready to rock!");
-#endif
-        if (getState() != Volume::State_Formatting) {
-            setState(Volume::State_Idle);
-            if (mRetryMount == true) {
-                mRetryMount = false;
-                mountVol();
-            }
-        }
-    } else {
-#ifdef PARTITION_DEBUG
-        SLOGD("Dv:partAdd: pending %d disk", mPendingPartCount);
-#endif
-    }
-}
-
-void DirectVolume::handleDiskChanged(const char * /*devpath*/,
-                                     NetlinkEvent *evt) {
-    int major = atoi(evt->findParam("MAJOR"));
-    int minor = atoi(evt->findParam("MINOR"));
-
-    if ((major != mDiskMajor) || (minor != mDiskMinor)) {
-        return;
-    }
-
-    SLOGI("Volume %s disk has changed", getLabel());
-    const char *tmp = evt->findParam("NPARTS");
-    if (tmp) {
-        mDiskNumParts = atoi(tmp);
-    } else {
-        SLOGW("Kernel block uevent missing 'NPARTS'");
-        mDiskNumParts = 1;
-    }
-
-    mPendingPartCount = mDiskNumParts;
-    for (int i = 0; i < MAX_PARTITIONS; i++)
-        mPartMinors[i] = -1;
-
-    if (getState() != Volume::State_Formatting) {
-        if (mDiskNumParts == 0) {
-            setState(Volume::State_Idle);
-        } else {
-            setState(Volume::State_Pending);
-        }
-    }
-}
-
-void DirectVolume::handlePartitionChanged(const char * /*devpath*/,
-                                          NetlinkEvent *evt) {
-    int major = atoi(evt->findParam("MAJOR"));
-    int minor = atoi(evt->findParam("MINOR"));
-    SLOGD("Volume %s %s partition %d:%d changed\n", getLabel(), getMountpoint(), major, minor);
-}
-
-void DirectVolume::handleDiskRemoved(const char * /*devpath*/,
-                                     NetlinkEvent *evt) {
-    int major = atoi(evt->findParam("MAJOR"));
-    int minor = atoi(evt->findParam("MINOR"));
-    char msg[255];
-    bool enabled;
-
-    SLOGD("Volume %s %s disk %d:%d removed\n", getLabel(), getMountpoint(), major, minor);
-    if ((dev_t) MKDEV(major, minor) == mCurrentlyMountedKdev) {
-        /*
-         * Yikes, our mounted disk is going away!
-         */
-
-        doUnmount(major, minor);
-    } else if (mVm->shareEnabled(getLabel(), "ums", &enabled) == 0 && enabled) {
-        mVm->unshareVolume(getLabel(), "ums");
-    }
-
-    snprintf(msg, sizeof(msg), "Volume %s %s disk removed (%d:%d)",
-             getLabel(), getFuseMountpoint(), major, minor);
-    mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeDiskRemoved,
-                                             msg, false);
-    setState(Volume::State_NoMedia);
-}
-
-void DirectVolume::handlePartitionRemoved(const char * /*devpath*/,
-                                          NetlinkEvent *evt) {
-    int major = atoi(evt->findParam("MAJOR"));
-    int minor = atoi(evt->findParam("MINOR"));
-    char msg[255];
-    int state;
-
-    SLOGD("Volume %s %s partition %d:%d removed\n", getLabel(), getMountpoint(), major, minor);
-
-    /*
-     * The framework doesn't need to get notified of
-     * partition removal unless it's mounted. Otherwise
-     * the removal notification will be sent on the Disk
-     * itself
-     */
-    state = getState();
-    if (state != Volume::State_Mounted && state != Volume::State_Shared) {
-        return;
-    }
-
-    if ((dev_t) MKDEV(major, minor) == mCurrentlyMountedKdev) {
-        /*
-         * Yikes, our mounted partition is going away!
-         */
-        doUnmount(major, minor);
-    } else if (state == Volume::State_Shared) {
-        /* removed during mass storage */
-        snprintf(msg, sizeof(msg), "Volume %s bad removal (%d:%d)",
-                 getLabel(), major, minor);
-        mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeBadRemoval,
-                                             msg, false);
-
-        if (mVm->unshareVolume(getLabel(), "ums")) {
-            SLOGE("Failed to unshare volume on bad removal (%s)",
-                strerror(errno));
-        } else {
-            SLOGD("Crisis averted");
-        }
-    }
-}
-
-void DirectVolume::doUnmount(int major, int minor) {
-    char msg[255];
-    bool providesAsec = (getFlags() & VOL_PROVIDES_ASEC) != 0;
-    if (providesAsec && mVm->cleanupAsec(this, true)) {
-        SLOGE("Failed to cleanup ASEC - unmount will probably fail!");
-    }
-
-    snprintf(msg, sizeof(msg), "Volume %s %s bad removal (%d:%d)",
-                getLabel(), getFuseMountpoint(), major, minor);
-    mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeBadRemoval,
-                                            msg, false);
-
-    if (Volume::unmountVol(true, false)) {
-        SLOGE("Failed to unmount volume on bad removal (%s)",
-                strerror(errno));
-        // XXX: At this point we're screwed for now
-    } else {
-        SLOGD("Crisis averted");
-    }
-}
-
-/*
- * Called from base to get a list of devicenodes for mounting
- */
-int DirectVolume::getDeviceNodes(dev_t *devs, int max) {
-
-    if (mPartIdx == -1) {
-        // If the disk has no partitions, try the disk itself
-        if (!mDiskNumParts) {
-            devs[0] = MKDEV(mDiskMajor, mDiskMinor);
-            return 1;
-        }
-
-        int i;
-        for (i = 0; i < mDiskNumParts; i++) {
-            if (i == max)
-                break;
-            devs[i] = MKDEV(mDiskMajor, mPartMinors[i]);
-        }
-        return mDiskNumParts;
-    }
-    devs[0] = MKDEV(mDiskMajor, mPartMinors[mPartIdx -1]);
-    return 1;
-}
-
-/*
- * Called from base to update device info,
- * e.g. When setting up an dm-crypt mapping for the sd card.
- */
-int DirectVolume::updateDeviceInfo(char *new_path, int new_major, int new_minor)
-{
-    PathCollection::iterator it;
-
-    if (mPartIdx == -1) {
-        SLOGE("Can only change device info on a partition\n");
-        return -1;
-    }
-
-    /*
-     * This is to change the sysfs path associated with a partition, in particular,
-     * for an internal SD card partition that is encrypted.  Thus, the list is
-     * expected to be only 1 entry long.  Check that and bail if not.
-     */
-    if (mPaths->size() != 1) {
-        SLOGE("Cannot change path if there are more than one for a volume\n");
-        return -1;
-    }
-
-    it = mPaths->begin();
-    delete *it; /* Free the string storage */
-    mPaths->erase(it); /* Remove it from the list */
-    addPath(new_path); /* Put the new path on the list */
-
-    /* Save away original info so we can restore it when doing factory reset.
-     * Then, when doing the format, it will format the original device in the
-     * clear, otherwise it just formats the encrypted device which is not
-     * readable when the device boots unencrypted after the reset.
-     */
-    mOrigDiskMajor = mDiskMajor;
-    mOrigDiskMinor = mDiskMinor;
-    mOrigPartIdx = mPartIdx;
-    memcpy(mOrigPartMinors, mPartMinors, sizeof(mPartMinors));
-
-    mDiskMajor = new_major;
-    mDiskMinor = new_minor;
-    /* Ugh, virual block devices don't use minor 0 for whole disk and minor > 0 for
-     * partition number.  They don't have partitions, they are just virtual block
-     * devices, and minor number 0 is the first dm-crypt device.  Luckily the first
-     * dm-crypt device is for the userdata partition, which gets minor number 0, and
-     * it is not managed by vold.  So the next device is minor number one, which we
-     * will call partition one.
-     */
-    mPartIdx = new_minor;
-    mPartMinors[new_minor-1] = new_minor;
-
-    mIsDecrypted = 1;
-
-    return 0;
-}
-
-/*
- * Called from base to revert device info to the way it was before a
- * crypto mapping was created for it.
- */
-void DirectVolume::revertDeviceInfo(void)
-{
-    if (mIsDecrypted) {
-        mDiskMajor = mOrigDiskMajor;
-        mDiskMinor = mOrigDiskMinor;
-        mPartIdx = mOrigPartIdx;
-        memcpy(mPartMinors, mOrigPartMinors, sizeof(mPartMinors));
-
-        mIsDecrypted = 0;
-    }
-
-    return;
-}
-
-/*
- * Called from base to give cryptfs all the info it needs to encrypt eligible volumes
- */
-int DirectVolume::getVolInfo(struct volume_info *v)
-{
-    strcpy(v->label, mLabel);
-    strcpy(v->mnt_point, mMountpoint);
-    v->flags = getFlags();
-    /* Other fields of struct volume_info are filled in by the caller or cryptfs.c */
-
-    return 0;
-}
diff --git a/DirectVolume.h b/DirectVolume.h
deleted file mode 100644
index 96f46af..0000000
--- a/DirectVolume.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-#ifndef _DEVICEVOLUME_H
-#define _DEVICEVOLUME_H
-
-#include <utils/List.h>
-
-#include "Volume.h"
-
-class PathInfo {
-public:
-	PathInfo(const char *pattern);
-	~PathInfo();
-	bool match(const char *path);
-private:
-	bool warned;
-	char *pattern;
-	enum PatternType { prefix, wildcard };
-	PatternType patternType;
-};
-
-typedef android::List<PathInfo *> PathCollection;
-
-class DirectVolume : public Volume {
-public:
-    static const int MAX_PARTITIONS = 32;
-protected:
-    const char* mMountpoint;
-    const char* mFuseMountpoint;
-
-    PathCollection *mPaths;
-    int            mDiskMajor;
-    int            mDiskMinor;
-    int            mPartMinors[MAX_PARTITIONS];
-    int            mOrigDiskMajor;
-    int            mOrigDiskMinor;
-    int            mOrigPartMinors[MAX_PARTITIONS];
-    int            mDiskNumParts;
-    int            mPendingPartCount;
-    int            mIsDecrypted;
-
-public:
-    DirectVolume(VolumeManager *vm, const fstab_rec* rec, int flags);
-    virtual ~DirectVolume();
-
-    int addPath(const char *path);
-
-    const char *getMountpoint() { return mMountpoint; }
-    const char *getFuseMountpoint() { return mFuseMountpoint; }
-
-    int handleBlockEvent(NetlinkEvent *evt);
-    dev_t getDiskDevice();
-    dev_t getShareDevice();
-    void handleVolumeShared();
-    void handleVolumeUnshared();
-    int getVolInfo(struct volume_info *v);
-
-protected:
-    int getDeviceNodes(dev_t *devs, int max);
-    int updateDeviceInfo(char *new_path, int new_major, int new_minor);
-    virtual void revertDeviceInfo(void);
-    int isDecrypted() { return mIsDecrypted; }
-
-private:
-    void handleDiskAdded(const char *devpath, NetlinkEvent *evt);
-    void handleDiskRemoved(const char *devpath, NetlinkEvent *evt);
-    void handleDiskChanged(const char *devpath, NetlinkEvent *evt);
-    void handlePartitionAdded(const char *devpath, NetlinkEvent *evt);
-    void handlePartitionRemoved(const char *devpath, NetlinkEvent *evt);
-    void handlePartitionChanged(const char *devpath, NetlinkEvent *evt);
-
-    int doMountVfat(const char *deviceNode, const char *mountPoint);
-    void doUnmount(int major, int minor);
-
-};
-
-typedef android::List<DirectVolume *> DirectVolumeCollection;
-
-#endif
diff --git a/Volume.cpp b/Volume.cpp
deleted file mode 100644
index 625e94d..0000000
--- a/Volume.cpp
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
- * Copyright (C) 2008 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 <stdlib.h>
-#include <string.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <mntent.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/mount.h>
-#include <sys/param.h>
-
-#include <linux/kdev_t.h>
-
-#include <cutils/properties.h>
-
-#include <diskconfig/diskconfig.h>
-
-#include <private/android_filesystem_config.h>
-
-#define LOG_TAG "Vold"
-
-#include <cutils/fs.h>
-#include <cutils/log.h>
-
-#include <string>
-
-#include "Volume.h"
-#include "VolumeManager.h"
-#include "ResponseCode.h"
-#include "Fat.h"
-#include "Process.h"
-#include "cryptfs.h"
-#include "sehandle.h"
-
-extern "C" void dos_partition_dec(void const *pp, struct dos_partition *d);
-extern "C" void dos_partition_enc(void *pp, struct dos_partition *d);
-
-
-/*
- * Media directory - stuff that only media_rw user can see
- */
-const char *Volume::MEDIA_DIR           = "/mnt/media_rw";
-
-/*
- * Fuse directory - location where fuse wrapped filesystems go
- */
-const char *Volume::FUSE_DIR           = "/storage";
-
-/*
- * Path to external storage where *only* root can access ASEC image files
- */
-const char *Volume::SEC_ASECDIR_EXT   = "/mnt/secure/asec";
-
-/*
- * Path to internal storage where *only* root can access ASEC image files
- */
-const char *Volume::SEC_ASECDIR_INT   = "/data/app-asec";
-
-/*
- * Path to where secure containers are mounted
- */
-const char *Volume::ASECDIR           = "/mnt/asec";
-
-/*
- * Path to where OBBs are mounted
- */
-const char *Volume::LOOPDIR           = "/mnt/obb";
-
-const char *Volume::BLKID_PATH = "/system/bin/blkid";
-
-static const char *stateToStr(int state) {
-    if (state == Volume::State_Init)
-        return "Initializing";
-    else if (state == Volume::State_NoMedia)
-        return "No-Media";
-    else if (state == Volume::State_Idle)
-        return "Idle-Unmounted";
-    else if (state == Volume::State_Pending)
-        return "Pending";
-    else if (state == Volume::State_Mounted)
-        return "Mounted";
-    else if (state == Volume::State_Unmounting)
-        return "Unmounting";
-    else if (state == Volume::State_Checking)
-        return "Checking";
-    else if (state == Volume::State_Formatting)
-        return "Formatting";
-    else if (state == Volume::State_Shared)
-        return "Shared-Unmounted";
-    else if (state == Volume::State_SharedMnt)
-        return "Shared-Mounted";
-    else
-        return "Unknown-Error";
-}
-
-Volume::Volume(VolumeManager *vm, const fstab_rec* rec, int flags) {
-    mVm = vm;
-    mDebug = false;
-    mLabel = strdup(rec->label);
-    mUuid = NULL;
-    mUserLabel = NULL;
-    mState = Volume::State_Init;
-    mFlags = flags;
-    mCurrentlyMountedKdev = -1;
-    mPartIdx = rec->partnum;
-    mRetryMount = false;
-}
-
-Volume::~Volume() {
-    free(mLabel);
-    free(mUuid);
-    free(mUserLabel);
-}
-
-void Volume::setDebug(bool enable) {
-    mDebug = enable;
-}
-
-dev_t Volume::getDiskDevice() {
-    return MKDEV(0, 0);
-};
-
-dev_t Volume::getShareDevice() {
-    return getDiskDevice();
-}
-
-void Volume::handleVolumeShared() {
-}
-
-void Volume::handleVolumeUnshared() {
-}
-
-int Volume::handleBlockEvent(NetlinkEvent * /*evt*/) {
-    errno = ENOSYS;
-    return -1;
-}
-
-void Volume::setUuid(const char* uuid) {
-    char msg[256];
-
-    if (mUuid) {
-        free(mUuid);
-    }
-
-    if (uuid) {
-        mUuid = strdup(uuid);
-        snprintf(msg, sizeof(msg), "%s %s \"%s\"", getLabel(),
-                getFuseMountpoint(), mUuid);
-    } else {
-        mUuid = NULL;
-        snprintf(msg, sizeof(msg), "%s %s", getLabel(), getFuseMountpoint());
-    }
-
-    mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeUuidChange, msg,
-            false);
-}
-
-void Volume::setUserLabel(const char* userLabel) {
-    char msg[256];
-
-    if (mUserLabel) {
-        free(mUserLabel);
-    }
-
-    if (userLabel) {
-        mUserLabel = strdup(userLabel);
-        snprintf(msg, sizeof(msg), "%s %s \"%s\"", getLabel(),
-                getFuseMountpoint(), mUserLabel);
-    } else {
-        mUserLabel = NULL;
-        snprintf(msg, sizeof(msg), "%s %s", getLabel(), getFuseMountpoint());
-    }
-
-    mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeUserLabelChange,
-            msg, false);
-}
-
-void Volume::setState(int state) {
-    char msg[255];
-    int oldState = mState;
-
-    if (oldState == state) {
-        SLOGW("Duplicate state (%d)\n", state);
-        return;
-    }
-
-    if ((oldState == Volume::State_Pending) && (state != Volume::State_Idle)) {
-        mRetryMount = false;
-    }
-
-    mState = state;
-
-    SLOGD("Volume %s state changing %d (%s) -> %d (%s)", mLabel,
-         oldState, stateToStr(oldState), mState, stateToStr(mState));
-    snprintf(msg, sizeof(msg),
-             "Volume %s %s state changed from %d (%s) to %d (%s)", getLabel(),
-             getFuseMountpoint(), oldState, stateToStr(oldState), mState,
-             stateToStr(mState));
-
-    mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeStateChange,
-                                         msg, false);
-}
-
-int Volume::createDeviceNode(const char *path, int major, int minor) {
-    char *secontext = NULL;
-    mode_t mode = 0660 | S_IFBLK;
-    dev_t dev = (major << 8) | minor;
-    int rc;
-    if (sehandle) {
-        rc = selabel_lookup(sehandle, &secontext, path, S_IFBLK);
-        if (rc == 0)
-            setfscreatecon(secontext);
-    }
-    if (mknod(path, mode, dev) < 0) {
-        if (errno != EEXIST) {
-            int sverrno = errno;
-            if (secontext) {
-                freecon(secontext);
-                setfscreatecon(NULL);
-            }
-            errno = sverrno;
-            return -1;
-        }
-    }
-    if (secontext) {
-        setfscreatecon(NULL);
-        freecon(secontext);
-    }
-    return 0;
-}
-
-int Volume::formatVol(bool wipe) {
-
-    if (getState() == Volume::State_NoMedia) {
-        errno = ENODEV;
-        return -1;
-    } else if (getState() != Volume::State_Idle) {
-        errno = EBUSY;
-        return -1;
-    }
-
-    if (isMountpointMounted(getMountpoint())) {
-        SLOGW("Volume is idle but appears to be mounted - fixing");
-        setState(Volume::State_Mounted);
-        // mCurrentlyMountedKdev = XXX
-        errno = EBUSY;
-        return -1;
-    }
-
-    bool formatEntireDevice = (mPartIdx == -1);
-    char devicePath[255];
-    dev_t diskNode = getDiskDevice();
-    dev_t partNode =
-        MKDEV(MAJOR(diskNode),
-              MINOR(diskNode) + (formatEntireDevice ? 0 : mPartIdx));
-
-    setState(Volume::State_Formatting);
-
-    int ret = -1;
-    // Only initialize the MBR if we are formatting the entire device
-    if (formatEntireDevice) {
-        sprintf(devicePath, "/dev/block/vold/%d:%d",
-                major(diskNode), minor(diskNode));
-
-        if (initializeMbr(devicePath)) {
-            SLOGE("Failed to initialize MBR (%s)", strerror(errno));
-            goto err;
-        }
-    }
-
-    sprintf(devicePath, "/dev/block/vold/%d:%d",
-            major(partNode), minor(partNode));
-
-    if (mDebug) {
-        SLOGI("Formatting volume %s (%s)", getLabel(), devicePath);
-    }
-
-    if (Fat::format(devicePath, 0, wipe)) {
-        SLOGE("Failed to format (%s)", strerror(errno));
-        goto err;
-    }
-
-    ret = 0;
-
-err:
-    setState(Volume::State_Idle);
-    return ret;
-}
-
-bool Volume::isMountpointMounted(const char *path) {
-    FILE *fp = setmntent("/proc/mounts", "r");
-    if (fp == NULL) {
-        SLOGE("Error opening /proc/mounts (%s)", strerror(errno));
-        return false;
-    }
-
-    bool found_path = false;
-    mntent* mentry;
-    while ((mentry = getmntent(fp)) != NULL) {
-        if (strcmp(mentry->mnt_dir, path) == 0) {
-            found_path = true;
-            break;
-        }
-    }
-    endmntent(fp);
-    return found_path;
-}
-
-int Volume::mountVol() {
-    dev_t deviceNodes[4];
-    int n, i;
-    char errmsg[255];
-
-    int flags = getFlags();
-    bool providesAsec = (flags & VOL_PROVIDES_ASEC) != 0;
-
-    // TODO: handle "bind" style mounts, for emulated storage
-
-    char decrypt_state[PROPERTY_VALUE_MAX];
-    char crypto_state[PROPERTY_VALUE_MAX];
-    char encrypt_progress[PROPERTY_VALUE_MAX];
-
-    property_get("vold.decrypt", decrypt_state, "");
-    property_get("vold.encrypt_progress", encrypt_progress, "");
-
-    /* Don't try to mount the volumes if we have not yet entered the disk password
-     * or are in the process of encrypting.
-     */
-    if ((getState() == Volume::State_NoMedia) ||
-        ((!strcmp(decrypt_state, "1") || encrypt_progress[0]) && providesAsec)) {
-        snprintf(errmsg, sizeof(errmsg),
-                 "Volume %s %s mount failed - no media",
-                 getLabel(), getFuseMountpoint());
-        mVm->getBroadcaster()->sendBroadcast(
-                                         ResponseCode::VolumeMountFailedNoMedia,
-                                         errmsg, false);
-        errno = ENODEV;
-        return -1;
-    } else if (getState() != Volume::State_Idle) {
-        errno = EBUSY;
-        if (getState() == Volume::State_Pending) {
-            mRetryMount = true;
-        }
-        return -1;
-    }
-
-    if (isMountpointMounted(getMountpoint())) {
-        SLOGW("Volume is idle but appears to be mounted - fixing");
-        setState(Volume::State_Mounted);
-        // mCurrentlyMountedKdev = XXX
-        return 0;
-    }
-
-    n = getDeviceNodes((dev_t *) &deviceNodes, 4);
-    if (!n) {
-        SLOGE("Failed to get device nodes (%s)\n", strerror(errno));
-        return -1;
-    }
-
-    /* If we're running encrypted, and the volume is marked as encryptable and nonremovable,
-     * and also marked as providing Asec storage, then we need to decrypt
-     * that partition, and update the volume object to point to it's new decrypted
-     * block device
-     */
-    property_get("ro.crypto.state", crypto_state, "");
-    if (providesAsec &&
-        ((flags & (VOL_NONREMOVABLE | VOL_ENCRYPTABLE))==(VOL_NONREMOVABLE | VOL_ENCRYPTABLE)) &&
-        !strcmp(crypto_state, "encrypted") && !isDecrypted()) {
-       char new_sys_path[MAXPATHLEN];
-       char nodepath[256];
-       int new_major, new_minor;
-
-       if (n != 1) {
-           /* We only expect one device node returned when mounting encryptable volumes */
-           SLOGE("Too many device nodes returned when mounting %s\n", getMountpoint());
-           return -1;
-       }
-
-//       if (cryptfs_setup_volume(getLabel(), MAJOR(deviceNodes[0]), MINOR(deviceNodes[0]),
-//                                new_sys_path, sizeof(new_sys_path),
-//                                &new_major, &new_minor)) {
-           SLOGE("Cannot setup encryption mapping for %s\n", getMountpoint());
-           return -1;
-//       }
-       /* We now have the new sysfs path for the decrypted block device, and the
-        * majore and minor numbers for it.  So, create the device, update the
-        * path to the new sysfs path, and continue.
-        */
-        snprintf(nodepath,
-                 sizeof(nodepath), "/dev/block/vold/%d:%d",
-                 new_major, new_minor);
-        if (createDeviceNode(nodepath, new_major, new_minor)) {
-            SLOGE("Error making device node '%s' (%s)", nodepath,
-                                                       strerror(errno));
-        }
-
-        // Todo: Either create sys filename from nodepath, or pass in bogus path so
-        //       vold ignores state changes on this internal device.
-        updateDeviceInfo(nodepath, new_major, new_minor);
-
-        /* Get the device nodes again, because they just changed */
-        n = getDeviceNodes((dev_t *) &deviceNodes, 4);
-        if (!n) {
-            SLOGE("Failed to get device nodes (%s)\n", strerror(errno));
-            return -1;
-        }
-    }
-
-    for (i = 0; i < n; i++) {
-        char devicePath[255];
-
-        sprintf(devicePath, "/dev/block/vold/%d:%d", major(deviceNodes[i]),
-                minor(deviceNodes[i]));
-
-        SLOGI("%s being considered for volume %s\n", devicePath, getLabel());
-
-        errno = 0;
-        setState(Volume::State_Checking);
-
-        if (Fat::check(devicePath)) {
-            if (errno == ENODATA) {
-                SLOGW("%s does not contain a FAT filesystem\n", devicePath);
-                continue;
-            }
-            errno = EIO;
-            /* Badness - abort the mount */
-            SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno));
-            setState(Volume::State_Idle);
-            return -1;
-        }
-
-        errno = 0;
-
-        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);
-
-        if (providesAsec && mountAsecExternal() != 0) {
-            SLOGE("Failed to mount secure area (%s)", strerror(errno));
-            umount(getMountpoint());
-            setState(Volume::State_Idle);
-            return -1;
-        }
-
-        char service[64];
-        snprintf(service, 64, "fuse_%s", getLabel());
-        property_set("ctl.start", service);
-
-        setState(Volume::State_Mounted);
-        mCurrentlyMountedKdev = deviceNodes[i];
-        return 0;
-    }
-
-    SLOGE("Volume %s found no suitable devices for mounting :(\n", getLabel());
-    setState(Volume::State_Idle);
-
-    return -1;
-}
-
-int Volume::mountAsecExternal() {
-    char legacy_path[PATH_MAX];
-    char secure_path[PATH_MAX];
-
-    snprintf(legacy_path, PATH_MAX, "%s/android_secure", getMountpoint());
-    snprintf(secure_path, PATH_MAX, "%s/.android_secure", getMountpoint());
-
-    // Recover legacy secure path
-    if (!access(legacy_path, R_OK | X_OK) && access(secure_path, R_OK | X_OK)) {
-        if (rename(legacy_path, secure_path)) {
-            SLOGE("Failed to rename legacy asec dir (%s)", strerror(errno));
-        }
-    }
-
-    if (fs_prepare_dir(secure_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) != 0) {
-        SLOGW("fs_prepare_dir failed: %s", strerror(errno));
-        return -1;
-    }
-
-    if (mount(secure_path, SEC_ASECDIR_EXT, "", MS_BIND, NULL)) {
-        SLOGE("Failed to bind mount points %s -> %s (%s)", secure_path,
-                SEC_ASECDIR_EXT, strerror(errno));
-        return -1;
-    }
-
-    return 0;
-}
-
-int Volume::doUnmount(const char *path, bool force) {
-    int retries = 10;
-
-    if (mDebug) {
-        SLOGD("Unmounting {%s}, force = %d", path, force);
-    }
-
-    while (retries--) {
-        if (!umount(path) || errno == EINVAL || errno == ENOENT) {
-            SLOGI("%s sucessfully unmounted", path);
-            return 0;
-        }
-
-        int signal = 0;
-
-        if (force) {
-            if (retries == 1) {
-                signal = SIGKILL;
-            } else if (retries == 2) {
-                signal = SIGTERM;
-            }
-        }
-
-        SLOGW("Failed to unmount %s (%s, retries %d, signal %d)",
-                path, strerror(errno), retries, signal);
-
-        Process::killProcessesWithOpenFiles(path, signal);
-        usleep(1000*1000);
-    }
-    errno = EBUSY;
-    SLOGE("Giving up on unmount %s (%s)", path, strerror(errno));
-    return -1;
-}
-
-int Volume::unmountVol(bool force, bool revert) {
-    int flags = getFlags();
-    bool providesAsec = (flags & VOL_PROVIDES_ASEC) != 0;
-
-    if (getState() != Volume::State_Mounted) {
-        SLOGE("Volume %s unmount request when not mounted", getLabel());
-        errno = EINVAL;
-        return UNMOUNT_NOT_MOUNTED_ERR;
-    }
-
-    setState(Volume::State_Unmounting);
-    usleep(1000 * 1000); // Give the framework some time to react
-
-    char service[64];
-    snprintf(service, 64, "fuse_%s", getLabel());
-    property_set("ctl.stop", service);
-    /* Give it a chance to stop.  I wish we had a synchronous way to determine this... */
-    sleep(1);
-
-    // TODO: determine failure mode if FUSE times out
-
-    if (providesAsec && doUnmount(Volume::SEC_ASECDIR_EXT, force) != 0) {
-        SLOGE("Failed to unmount secure area on %s (%s)", getMountpoint(), strerror(errno));
-        goto out_mounted;
-    }
-
-    /* Now that the fuse daemon is dead, unmount it */
-    if (doUnmount(getFuseMountpoint(), force) != 0) {
-        SLOGE("Failed to unmount %s (%s)", getFuseMountpoint(), strerror(errno));
-        goto fail_remount_secure;
-    }
-
-    /* Unmount the real sd card */
-    if (doUnmount(getMountpoint(), force) != 0) {
-        SLOGE("Failed to unmount %s (%s)", getMountpoint(), strerror(errno));
-        goto fail_remount_secure;
-    }
-
-    SLOGI("%s unmounted successfully", getMountpoint());
-
-    /* If this is an encrypted volume, and we've been asked to undo
-     * the crypto mapping, then revert the dm-crypt mapping, and revert
-     * the device info to the original values.
-     */
-    if (revert && isDecrypted()) {
-//        cryptfs_revert_volume(getLabel());
-//        revertDeviceInfo();
-        SLOGI("Encrypted volume %s reverted successfully", getMountpoint());
-    }
-
-    setUuid(NULL);
-    setUserLabel(NULL);
-    setState(Volume::State_Idle);
-    mCurrentlyMountedKdev = -1;
-    return 0;
-
-fail_remount_secure:
-    if (providesAsec && mountAsecExternal() != 0) {
-        SLOGE("Failed to remount secure area (%s)", strerror(errno));
-        goto out_nomedia;
-    }
-
-out_mounted:
-    setState(Volume::State_Mounted);
-    return -1;
-
-out_nomedia:
-    setState(Volume::State_NoMedia);
-    return -1;
-}
-
-int Volume::initializeMbr(const char *deviceNode) {
-    struct disk_info dinfo;
-
-    memset(&dinfo, 0, sizeof(dinfo));
-
-    if (!(dinfo.part_lst = (struct part_info *) malloc(MAX_NUM_PARTS * sizeof(struct part_info)))) {
-        SLOGE("Failed to malloc prt_lst");
-        return -1;
-    }
-
-    memset(dinfo.part_lst, 0, MAX_NUM_PARTS * sizeof(struct part_info));
-    dinfo.device = strdup(deviceNode);
-    dinfo.scheme = PART_SCHEME_MBR;
-    dinfo.sect_size = 512;
-    dinfo.skip_lba = 2048;
-    dinfo.num_lba = 0;
-    dinfo.num_parts = 1;
-
-    struct part_info *pinfo = &dinfo.part_lst[0];
-
-    pinfo->name = strdup("android_sdcard");
-    pinfo->flags |= PART_ACTIVE_FLAG;
-    pinfo->type = PC_PART_TYPE_FAT32;
-    pinfo->len_kb = -1;
-
-    int rc = apply_disk_config(&dinfo, 0);
-
-    if (rc) {
-        SLOGE("Failed to apply disk configuration (%d)", rc);
-        goto out;
-    }
-
- out:
-    free(pinfo->name);
-    free(dinfo.device);
-    free(dinfo.part_lst);
-
-    return rc;
-}
-
-/*
- * Use blkid to extract UUID and label from device, since it handles many
- * obscure edge cases around partition types and formats. Always broadcasts
- * updated metadata values.
- */
-int Volume::extractMetadata(const char* devicePath) {
-    int res = 0;
-
-    std::string cmd;
-    cmd = BLKID_PATH;
-    cmd += " -c /dev/null ";
-    cmd += devicePath;
-
-    FILE* fp = popen(cmd.c_str(), "r");
-    if (!fp) {
-        ALOGE("Failed to run %s: %s", cmd.c_str(), strerror(errno));
-        res = -1;
-        goto done;
-    }
-
-    char line[1024];
-    char value[128];
-    if (fgets(line, sizeof(line), fp) != NULL) {
-        ALOGD("blkid identified as %s", line);
-
-        char* start = strstr(line, "UUID=");
-        if (start != NULL && sscanf(start + 5, "\"%127[^\"]\"", value) == 1) {
-            setUuid(value);
-        } else {
-            setUuid(NULL);
-        }
-
-        start = strstr(line, "LABEL=");
-        if (start != NULL && sscanf(start + 6, "\"%127[^\"]\"", value) == 1) {
-            setUserLabel(value);
-        } else {
-            setUserLabel(NULL);
-        }
-    } else {
-        ALOGW("blkid failed to identify %s", devicePath);
-        res = -1;
-    }
-
-    pclose(fp);
-
-done:
-    if (res == -1) {
-        setUuid(NULL);
-        setUserLabel(NULL);
-    }
-    return res;
-}
diff --git a/Volume.h b/Volume.h
deleted file mode 100644
index 1444ed3..0000000
--- a/Volume.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-#ifndef _VOLUME_H
-#define _VOLUME_H
-
-#include <utils/List.h>
-#include <fs_mgr.h>
-
-class NetlinkEvent;
-class VolumeManager;
-
-class Volume {
-private:
-    int mState;
-    int mFlags;
-
-public:
-    static const int State_Init       = -1;
-    static const int State_NoMedia    = 0;
-    static const int State_Idle       = 1;
-    static const int State_Pending    = 2;
-    static const int State_Checking   = 3;
-    static const int State_Mounted    = 4;
-    static const int State_Unmounting = 5;
-    static const int State_Formatting = 6;
-    static const int State_Shared     = 7;
-    static const int State_SharedMnt  = 8;
-
-    static const char *MEDIA_DIR;
-    static const char *FUSE_DIR;
-    static const char *SEC_ASECDIR_EXT;
-    static const char *SEC_ASECDIR_INT;
-    static const char *ASECDIR;
-    static const char *LOOPDIR;
-    static const char *BLKID_PATH;
-
-protected:
-    char* mLabel;
-    char* mUuid;
-    char* mUserLabel;
-    VolumeManager *mVm;
-    bool mDebug;
-    int mPartIdx;
-    int mOrigPartIdx;
-    bool mRetryMount;
-
-    /*
-     * The major/minor tuple of the currently mounted filesystem.
-     */
-    dev_t mCurrentlyMountedKdev;
-
-public:
-    Volume(VolumeManager *vm, const fstab_rec* rec, int flags);
-    virtual ~Volume();
-
-    int mountVol();
-    int unmountVol(bool force, bool revert);
-    int formatVol(bool wipe);
-
-    const char* getLabel() { return mLabel; }
-    const char* getUuid() { return mUuid; }
-    const char* getUserLabel() { return mUserLabel; }
-    int getState() { return mState; }
-    int getFlags() { return mFlags; };
-
-    /* Mountpoint of the raw volume */
-    virtual const char *getMountpoint() = 0;
-    virtual const char *getFuseMountpoint() = 0;
-
-    virtual int handleBlockEvent(NetlinkEvent *evt);
-    virtual dev_t getDiskDevice();
-    virtual dev_t getShareDevice();
-    virtual void handleVolumeShared();
-    virtual void handleVolumeUnshared();
-
-    void setDebug(bool enable);
-    virtual int getVolInfo(struct volume_info *v) = 0;
-
-protected:
-    void setUuid(const char* uuid);
-    void setUserLabel(const char* userLabel);
-    void setState(int state);
-
-    virtual int getDeviceNodes(dev_t *devs, int max) = 0;
-    virtual int updateDeviceInfo(char *new_path, int new_major, int new_minor) = 0;
-    virtual void revertDeviceInfo(void) = 0;
-    virtual int isDecrypted(void) = 0;
-
-    int createDeviceNode(const char *path, int major, int minor);
-
-private:
-    int initializeMbr(const char *deviceNode);
-    bool isMountpointMounted(const char *path);
-    int mountAsecExternal();
-    int doUnmount(const char *path, bool force);
-    int extractMetadata(const char* devicePath);
-};
-
-typedef android::List<Volume *> VolumeCollection;
-
-#endif
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 5296114..b61bafb 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -48,7 +48,6 @@
 #include "EmulatedVolume.h"
 #include "VolumeManager.h"
 #include "NetlinkManager.h"
-#include "DirectVolume.h"
 #include "ResponseCode.h"
 #include "Loop.h"
 #include "Ext4.h"
@@ -69,6 +68,26 @@
 
 using android::base::StringPrintf;
 
+/*
+ * Path to external storage where *only* root can access ASEC image files
+ */
+const char *VolumeManager::SEC_ASECDIR_EXT   = "/mnt/secure/asec";
+
+/*
+ * Path to internal storage where *only* root can access ASEC image files
+ */
+const char *VolumeManager::SEC_ASECDIR_INT   = "/data/app-asec";
+
+/*
+ * Path to where secure containers are mounted
+ */
+const char *VolumeManager::ASECDIR           = "/mnt/asec";
+
+/*
+ * Path to where OBBs are mounted
+ */
+const char *VolumeManager::LOOPDIR           = "/mnt/obb";
+
 static const char* kUserMountPath = "/mnt/user";
 
 static const unsigned int kMajorBlockScsi = 8;
@@ -185,18 +204,15 @@
 
 VolumeManager::VolumeManager() {
     mDebug = false;
-    mVolumes = new VolumeCollection();
     mActiveContainers = new AsecIdCollection();
     mBroadcaster = NULL;
     mUmsSharingCount = 0;
     mSavedDirtyRatio = -1;
     // set dirty ratio to 0 when UMS is active
     mUmsDirtyRatio = 0;
-    mVolManagerDisabled = 0;
 }
 
 VolumeManager::~VolumeManager() {
-    delete mVolumes;
     delete mActiveContainers;
 }
 
@@ -234,10 +250,6 @@
 
 void VolumeManager::setDebug(bool enable) {
     mDebug = enable;
-    VolumeCollection::iterator it;
-    for (it = mVolumes->begin(); it != mVolumes->end(); ++it) {
-        (*it)->setDebug(enable);
-    }
 }
 
 int VolumeManager::start() {
@@ -260,11 +272,6 @@
     return 0;
 }
 
-int VolumeManager::addVolume(Volume *v) {
-    mVolumes->push_back(v);
-    return 0;
-}
-
 void VolumeManager::handleBlockEvent(NetlinkEvent *evt) {
 #if DEBUG_NETLINK
     LOG(VERBOSE) << "handleBlockEvent with action " << (int) evt->getAction();
@@ -462,52 +469,6 @@
     return 0;
 }
 
-int VolumeManager::listVolumes(SocketClient *cli, bool broadcast) {
-    VolumeCollection::iterator i;
-    char msg[256];
-
-    for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
-        char *buffer;
-        asprintf(&buffer, "%s %s %d",
-                 (*i)->getLabel(), (*i)->getFuseMountpoint(),
-                 (*i)->getState());
-        cli->sendMsg(ResponseCode::VolumeListResult, buffer, false);
-        free(buffer);
-        if (broadcast) {
-            if((*i)->getUuid()) {
-                snprintf(msg, sizeof(msg), "%s %s \"%s\"", (*i)->getLabel(),
-                    (*i)->getFuseMountpoint(), (*i)->getUuid());
-                mBroadcaster->sendBroadcast(ResponseCode::VolumeUuidChange,
-                    msg, false);
-            }
-            if((*i)->getUserLabel()) {
-                snprintf(msg, sizeof(msg), "%s %s \"%s\"", (*i)->getLabel(),
-                    (*i)->getFuseMountpoint(), (*i)->getUserLabel());
-                mBroadcaster->sendBroadcast(ResponseCode::VolumeUserLabelChange,
-                    msg, false);
-            }
-        }
-    }
-    cli->sendMsg(ResponseCode::CommandOkay, "Volumes listed.", false);
-    return 0;
-}
-
-int VolumeManager::formatVolume(const char *label, bool wipe) {
-    Volume *v = lookupVolume(label);
-
-    if (!v) {
-        errno = ENOENT;
-        return -1;
-    }
-
-    if (mVolManagerDisabled) {
-        errno = EBUSY;
-        return -1;
-    }
-
-    return v->formatVol(wipe);
-}
-
 int VolumeManager::getObbMountPath(const char *sourceFile, char *mountPath, int mountPathLen) {
     char idHash[33];
     if (!asecHash(sourceFile, idHash, sizeof(idHash))) {
@@ -516,7 +477,7 @@
     }
 
     memset(mountPath, 0, mountPathLen);
-    int written = snprintf(mountPath, mountPathLen, "%s/%s", Volume::LOOPDIR, idHash);
+    int written = snprintf(mountPath, mountPathLen, "%s/%s", VolumeManager::LOOPDIR, idHash);
     if ((written < 0) || (written >= mountPathLen)) {
         errno = EINVAL;
         return -1;
@@ -550,7 +511,7 @@
         return -1;
     }
 
-    int written = snprintf(buffer, maxlen, "%s/%s", Volume::ASECDIR, id);
+    int written = snprintf(buffer, maxlen, "%s/%s", VolumeManager::ASECDIR, id);
     if ((written < 0) || (written >= maxlen)) {
         SLOGE("getAsecMountPath failed for %s: couldn't construct path in buffer", id);
         errno = EINVAL;
@@ -622,12 +583,6 @@
         return -1;
     }
 
-    if (lookupVolume(id)) {
-        SLOGE("ASEC id '%s' currently exists", id);
-        errno = EADDRINUSE;
-        return -1;
-    }
-
     char asecFileName[255];
 
     if (!findAsec(id, asecFileName, sizeof(asecFileName))) {
@@ -637,7 +592,7 @@
         return -1;
     }
 
-    const char *asecDir = isExternal ? Volume::SEC_ASECDIR_EXT : Volume::SEC_ASECDIR_INT;
+    const char *asecDir = isExternal ? VolumeManager::SEC_ASECDIR_EXT : VolumeManager::SEC_ASECDIR_INT;
 
     int written = snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", asecDir, id);
     if ((written < 0) || (size_t(written) >= sizeof(asecFileName))) {
@@ -713,7 +668,7 @@
         int formatStatus;
         char mountPoint[255];
 
-        int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
+        int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
         if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
             SLOGE("ASEC fs format failed: couldn't construct mountPoint");
             if (cleanupDm) {
@@ -804,7 +759,7 @@
         return -1;
     }
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
        SLOGE("ASEC resize failed for %s: couldn't construct mountpoint", id);
        return -1;
@@ -965,7 +920,7 @@
         return -1;
     }
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("ASEC finalize failed: couldn't construct mountPoint");
         return -1;
@@ -1028,7 +983,7 @@
         return -1;
     }
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("Unable remount to fix permissions for %s: couldn't construct mountpoint", id);
         return -1;
@@ -1143,7 +1098,7 @@
 
     asprintf(&asecFilename2, "%s/%s.asec", dir, id2);
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id1);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id1);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("Rename failed: couldn't construct mountpoint");
         goto out_err;
@@ -1155,7 +1110,7 @@
         goto out_err;
     }
 
-    written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id2);
+    written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id2);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("Rename failed: couldn't construct mountpoint2");
         goto out_err;
@@ -1203,7 +1158,7 @@
         return -1;
     }
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("ASEC unmount failed for %s: couldn't construct mountpoint", id);
         return -1;
@@ -1227,7 +1182,7 @@
         return -1;
     }
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::LOOPDIR, idHash);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::LOOPDIR, idHash);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("OBB unmount failed for %s: couldn't construct mountpoint", fileName);
         return -1;
@@ -1339,7 +1294,7 @@
         return -1;
     }
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("ASEC destroy failed for %s: couldn't construct mountpoint", id);
         return -1;
@@ -1430,10 +1385,10 @@
     }
 
     const char *dir;
-    if (isAsecInDirectory(Volume::SEC_ASECDIR_INT, asecName)) {
-        dir = Volume::SEC_ASECDIR_INT;
-    } else if (isAsecInDirectory(Volume::SEC_ASECDIR_EXT, asecName)) {
-        dir = Volume::SEC_ASECDIR_EXT;
+    if (isAsecInDirectory(VolumeManager::SEC_ASECDIR_INT, asecName)) {
+        dir = VolumeManager::SEC_ASECDIR_INT;
+    } else if (isAsecInDirectory(VolumeManager::SEC_ASECDIR_EXT, asecName)) {
+        dir = VolumeManager::SEC_ASECDIR_EXT;
     } else {
         free(asecName);
         return -1;
@@ -1471,7 +1426,7 @@
         return -1;
     }
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("ASEC mount failed for %s: couldn't construct mountpoint", id);
         return -1;
@@ -1558,19 +1513,6 @@
     return 0;
 }
 
-Volume* VolumeManager::getVolumeForFile(const char *fileName) {
-    VolumeCollection::iterator i;
-
-    for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
-        const char* mountPoint = (*i)->getFuseMountpoint();
-        if (!strncmp(fileName, mountPoint, strlen(mountPoint))) {
-            return *i;
-        }
-    }
-
-    return NULL;
-}
-
 /**
  * Mounts an image file <code>img</code>.
  */
@@ -1583,7 +1525,7 @@
         return -1;
     }
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::LOOPDIR, idHash);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::LOOPDIR, idHash);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("OBB mount failed for %s: couldn't construct mountpoint", img);
         return -1;
@@ -1653,17 +1595,6 @@
     return 0;
 }
 
-int VolumeManager::mountVolume(const char *label) {
-    Volume *v = lookupVolume(label);
-
-    if (!v) {
-        errno = ENOENT;
-        return -1;
-    }
-
-    return v->mountVol();
-}
-
 int VolumeManager::listMountedObbs(SocketClient* cli) {
     FILE *fp = setmntent("/proc/mounts", "r");
     if (fp == NULL) {
@@ -1672,9 +1603,9 @@
     }
 
     // Create a string to compare against that has a trailing slash
-    int loopDirLen = strlen(Volume::LOOPDIR);
+    int loopDirLen = strlen(VolumeManager::LOOPDIR);
     char loopDir[loopDirLen + 2];
-    strcpy(loopDir, Volume::LOOPDIR);
+    strcpy(loopDir, VolumeManager::LOOPDIR);
     loopDir[loopDirLen++] = '/';
     loopDir[loopDirLen] = '\0';
 
@@ -1696,266 +1627,11 @@
     return 0;
 }
 
-int VolumeManager::shareEnabled(const char *label, const char *method, bool *enabled) {
-    Volume *v = lookupVolume(label);
-
-    if (!v) {
-        errno = ENOENT;
-        return -1;
-    }
-
-    if (strcmp(method, "ums")) {
-        errno = ENOSYS;
-        return -1;
-    }
-
-    if (v->getState() != Volume::State_Shared) {
-        *enabled = false;
-    } else {
-        *enabled = true;
-    }
-    return 0;
-}
-
-int VolumeManager::shareVolume(const char *label, const char *method) {
-    Volume *v = lookupVolume(label);
-
-    if (!v) {
-        errno = ENOENT;
-        return -1;
-    }
-
-    /*
-     * Eventually, we'll want to support additional share back-ends,
-     * some of which may work while the media is mounted. For now,
-     * we just support UMS
-     */
-    if (strcmp(method, "ums")) {
-        errno = ENOSYS;
-        return -1;
-    }
-
-    if (v->getState() == Volume::State_NoMedia) {
-        errno = ENODEV;
-        return -1;
-    }
-
-    if (v->getState() != Volume::State_Idle) {
-        // You need to unmount manually befoe sharing
-        errno = EBUSY;
-        return -1;
-    }
-
-    if (mVolManagerDisabled) {
-        errno = EBUSY;
-        return -1;
-    }
-
-    dev_t d = v->getShareDevice();
-    if ((MAJOR(d) == 0) && (MINOR(d) == 0)) {
-        // This volume does not support raw disk access
-        errno = EINVAL;
-        return -1;
-    }
-
-    int fd;
-    char nodepath[255];
-    int written = snprintf(nodepath,
-             sizeof(nodepath), "/dev/block/vold/%d:%d",
-             major(d), minor(d));
-
-    if ((written < 0) || (size_t(written) >= sizeof(nodepath))) {
-        SLOGE("shareVolume failed: couldn't construct nodepath");
-        return -1;
-    }
-
-    if ((fd = open(MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) {
-        SLOGE("Unable to open ums lunfile (%s)", strerror(errno));
-        return -1;
-    }
-
-    if (write(fd, nodepath, strlen(nodepath)) < 0) {
-        SLOGE("Unable to write to ums lunfile (%s)", strerror(errno));
-        close(fd);
-        return -1;
-    }
-
-    close(fd);
-    v->handleVolumeShared();
-    if (mUmsSharingCount++ == 0) {
-        FILE* fp;
-        mSavedDirtyRatio = -1; // in case we fail
-        if ((fp = fopen("/proc/sys/vm/dirty_ratio", "r+"))) {
-            char line[16];
-            if (fgets(line, sizeof(line), fp) && sscanf(line, "%d", &mSavedDirtyRatio)) {
-                fprintf(fp, "%d\n", mUmsDirtyRatio);
-            } else {
-                SLOGE("Failed to read dirty_ratio (%s)", strerror(errno));
-            }
-            fclose(fp);
-        } else {
-            SLOGE("Failed to open /proc/sys/vm/dirty_ratio (%s)", strerror(errno));
-        }
-    }
-    return 0;
-}
-
-int VolumeManager::unshareVolume(const char *label, const char *method) {
-    Volume *v = lookupVolume(label);
-
-    if (!v) {
-        errno = ENOENT;
-        return -1;
-    }
-
-    if (strcmp(method, "ums")) {
-        errno = ENOSYS;
-        return -1;
-    }
-
-    if (v->getState() != Volume::State_Shared) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    int fd;
-    if ((fd = open(MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) {
-        SLOGE("Unable to open ums lunfile (%s)", strerror(errno));
-        return -1;
-    }
-
-    char ch = 0;
-    if (write(fd, &ch, 1) < 0) {
-        SLOGE("Unable to write to ums lunfile (%s)", strerror(errno));
-        close(fd);
-        return -1;
-    }
-
-    close(fd);
-    v->handleVolumeUnshared();
-    if (--mUmsSharingCount == 0 && mSavedDirtyRatio != -1) {
-        FILE* fp;
-        if ((fp = fopen("/proc/sys/vm/dirty_ratio", "r+"))) {
-            fprintf(fp, "%d\n", mSavedDirtyRatio);
-            fclose(fp);
-        } else {
-            SLOGE("Failed to open /proc/sys/vm/dirty_ratio (%s)", strerror(errno));
-        }
-        mSavedDirtyRatio = -1;
-    }
-    return 0;
-}
-
-int VolumeManager::getDirectVolumeList(struct volume_info *vol_list) {
-    VolumeCollection::iterator i;
-    int n=0;
-    dev_t d;
-
-    for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
-        if ((d=(*i)->getShareDevice()) != (dev_t)0) {
-            (*i)->getVolInfo(&vol_list[n]);
-            snprintf(vol_list[n].blk_dev, sizeof(vol_list[n].blk_dev),
-                     "/dev/block/vold/%d:%d", major(d), minor(d));
-            n++;
-        }
-    }
-
-    return 0;
-}
-
-int VolumeManager::unmountVolume(const char *label, bool force, bool revert) {
-    Volume *v = lookupVolume(label);
-
-    if (!v) {
-        errno = ENOENT;
-        return -1;
-    }
-
-    if (v->getState() == Volume::State_NoMedia) {
-        errno = ENODEV;
-        return -1;
-    }
-
-    if (v->getState() != Volume::State_Mounted) {
-        SLOGW("Attempt to unmount volume which isn't mounted (%d)\n",
-             v->getState());
-        errno = EBUSY;
-        return UNMOUNT_NOT_MOUNTED_ERR;
-    }
-
-    cleanupAsec(v, force);
-
-    return v->unmountVol(force, revert);
-}
-
 extern "C" int vold_unmountAll(void) {
     VolumeManager *vm = VolumeManager::Instance();
     return vm->unmountAll();
 }
 
-#define ID_BUF_LEN 256
-#define ASEC_SUFFIX ".asec"
-#define ASEC_SUFFIX_LEN (sizeof(ASEC_SUFFIX) - 1)
-int VolumeManager::unmountAllAsecsInDir(const char *directory) {
-    DIR *d = opendir(directory);
-    int rc = 0;
-
-    if (!d) {
-        SLOGE("Could not open asec dir %s", directory);
-        return -1;
-    }
-
-    size_t dirent_len = offsetof(struct dirent, d_name) +
-            fpathconf(dirfd(d), _PC_NAME_MAX) + 1;
-
-    struct dirent *dent = (struct dirent *) malloc(dirent_len);
-    if (dent == NULL) {
-        SLOGE("Failed to allocate memory for asec dir");
-        return -1;
-    }
-
-    struct dirent *result;
-    while (!readdir_r(d, dent, &result) && result != NULL) {
-        if (dent->d_name[0] == '.')
-            continue;
-        if (dent->d_type != DT_REG)
-            continue;
-        size_t name_len = strlen(dent->d_name);
-        if (name_len > 5 && name_len < (ID_BUF_LEN + ASEC_SUFFIX_LEN - 1) &&
-                !strcmp(&dent->d_name[name_len - 5], ASEC_SUFFIX)) {
-            char id[ID_BUF_LEN];
-            strlcpy(id, dent->d_name, name_len - 4);
-            if (unmountAsec(id, true)) {
-                /* Register the error, but try to unmount more asecs */
-                rc = -1;
-            }
-        }
-    }
-    closedir(d);
-
-    free(dent);
-
-    return rc;
-}
-
-/*
- * Looks up a volume by it's label or mount-point
- */
-Volume *VolumeManager::lookupVolume(const char *label) {
-    VolumeCollection::iterator i;
-
-    for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
-        if (label[0] == '/') {
-            if (!strcmp(label, (*i)->getFuseMountpoint()))
-                return (*i);
-        } else {
-            if (!strcmp(label, (*i)->getLabel()))
-                return (*i);
-        }
-    }
-    return NULL;
-}
-
 bool VolumeManager::isMountpointMounted(const char *mp)
 {
     FILE *fp = setmntent("/proc/mounts", "r");
@@ -1976,59 +1652,6 @@
     return found_mp;
 }
 
-int VolumeManager::cleanupAsec(Volume *v, bool force) {
-    int rc = 0;
-
-    char asecFileName[255];
-
-    AsecIdCollection removeAsec;
-    AsecIdCollection removeObb;
-
-    for (AsecIdCollection::iterator it = mActiveContainers->begin(); it != mActiveContainers->end();
-            ++it) {
-        ContainerData* cd = *it;
-
-        if (cd->type == ASEC) {
-            if (findAsec(cd->id, asecFileName, sizeof(asecFileName))) {
-                SLOGE("Couldn't find ASEC %s; cleaning up", cd->id);
-                removeAsec.push_back(cd);
-            } else {
-                SLOGD("Found ASEC at path %s", asecFileName);
-                if (!strncmp(asecFileName, Volume::SEC_ASECDIR_EXT,
-                        strlen(Volume::SEC_ASECDIR_EXT))) {
-                    removeAsec.push_back(cd);
-                }
-            }
-        } else if (cd->type == OBB) {
-            if (v == getVolumeForFile(cd->id)) {
-                removeObb.push_back(cd);
-            }
-        } else {
-            SLOGE("Unknown container type %d!", cd->type);
-        }
-    }
-
-    for (AsecIdCollection::iterator it = removeAsec.begin(); it != removeAsec.end(); ++it) {
-        ContainerData *cd = *it;
-        SLOGI("Unmounting ASEC %s (dependent on %s)", cd->id, v->getLabel());
-        if (unmountAsec(cd->id, force)) {
-            SLOGE("Failed to unmount ASEC %s (%s)", cd->id, strerror(errno));
-            rc = -1;
-        }
-    }
-
-    for (AsecIdCollection::iterator it = removeObb.begin(); it != removeObb.end(); ++it) {
-        ContainerData *cd = *it;
-        SLOGI("Unmounting OBB %s (dependent on %s)", cd->id, v->getLabel());
-        if (unmountObb(cd->id, force)) {
-            SLOGE("Failed to unmount OBB %s (%s)", cd->id, strerror(errno));
-            rc = -1;
-        }
-    }
-
-    return rc;
-}
-
 int VolumeManager::mkdirs(char* path) {
     // Only offer to create directories for paths managed by vold
     if (strncmp(path, "/storage/", 9) == 0) {
diff --git a/VolumeManager.h b/VolumeManager.h
index f36561c..06d0ce3 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -29,9 +29,9 @@
 #include <cutils/multiuser.h>
 #include <utils/List.h>
 #include <sysutils/SocketListener.h>
+#include <sysutils/NetlinkEvent.h>
 
 #include "Disk.h"
-#include "Volume.h"
 #include "VolumeBase.h"
 
 /* The length of an MD5 hash when encoded into ASCII hex characters */
@@ -60,12 +60,17 @@
 typedef android::List<ContainerData*> AsecIdCollection;
 
 class VolumeManager {
+public:
+    static const char *SEC_ASECDIR_EXT;
+    static const char *SEC_ASECDIR_INT;
+    static const char *ASECDIR;
+    static const char *LOOPDIR;
+
 private:
     static VolumeManager *sInstance;
 
     SocketListener        *mBroadcaster;
 
-    VolumeCollection      *mVolumes;
     AsecIdCollection      *mActiveContainers;
     bool                   mDebug;
 
@@ -73,7 +78,6 @@
     int                    mUmsSharingCount;
     int                    mSavedDirtyRatio;
     int                    mUmsDirtyRatio;
-    int                    mVolManagerDisabled;
 
 public:
     virtual ~VolumeManager();
@@ -83,8 +87,6 @@
 
     void handleBlockEvent(NetlinkEvent *evt);
 
-    int addVolume(Volume *v);
-
     class DiskSource {
     public:
         DiskSource(const std::string& sysPattern, const std::string& nickname, int flags) :
@@ -121,15 +123,6 @@
     /* Unmount all volumes, usually for encryption */
     int unmountAll();
 
-    int listVolumes(SocketClient *cli, bool broadcast);
-    int mountVolume(const char *label);
-    int unmountVolume(const char *label, bool force, bool revert);
-    int shareVolume(const char *label, const char *method);
-    int unshareVolume(const char *label, const char *method);
-    int shareEnabled(const char *path, const char *method, bool *enabled);
-    int formatVolume(const char *label, bool wipe);
-    void disableVolumeManager(void) { mVolManagerDisabled = 1; }
-
     /* ASEC */
     int findAsec(const char *id, char *asecPath = NULL, size_t asecPathLen = 0,
             const char **directory = NULL) const;
@@ -162,17 +155,12 @@
     int unmountObb(const char *fileName, bool force);
     int getObbMountPath(const char *id, char *buffer, int maxlen);
 
-    Volume* getVolumeForFile(const char *fileName);
-
     /* Shared between ASEC and Loopback images */
     int unmountLoopImage(const char *containerId, const char *loopId,
             const char *fileName, const char *mountPoint, bool force);
 
     void setDebug(bool enable);
 
-    // XXX: Post froyo this should be moved and cleaned up
-    int cleanupAsec(Volume *v, bool force);
-
     void setBroadcaster(SocketListener *sl) { mBroadcaster = sl; }
     SocketListener *getBroadcaster() { return mBroadcaster; }
 
@@ -180,11 +168,6 @@
 
     static char *asecHash(const char *id, char *buffer, size_t len);
 
-    Volume *lookupVolume(const char *label);
-    int getNumDirectVolumes(void);
-    int getDirectVolumeList(struct volume_info *vol_list);
-    int unmountAllAsecsInDir(const char *directory);
-
     /*
      * Ensure that all directories along given path exist, creating parent
      * directories as needed.  Validates that given path is absolute and that
diff --git a/cryptfs.h b/cryptfs.h
index d630479..6984944 100644
--- a/cryptfs.h
+++ b/cryptfs.h
@@ -172,21 +172,6 @@
   struct crypt_persist_entry persist_entry[0];
 };
 
-// TODO: remove this deprecated struct
-struct volume_info {
-   unsigned int size;
-   unsigned int flags;
-   struct crypt_mnt_ftr crypt_ftr;
-   char mnt_point[256];
-   char blk_dev[256];
-   char crypto_blkdev[256];
-   char label[256];
-};
-#define VOL_NONREMOVABLE   0x1
-#define VOL_ENCRYPTABLE    0x2
-#define VOL_PRIMARY        0x4
-#define VOL_PROVIDES_ASEC  0x8
-
 #define DATA_MNT_POINT "/data"
 
 /* Return values for cryptfs_crypto_complete */
diff --git a/main.cpp b/main.cpp
index 8a3f845..35e99df 100644
--- a/main.cpp
+++ b/main.cpp
@@ -14,6 +14,19 @@
  * limitations under the License.
  */
 
+#include "Disk.h"
+#include "VolumeManager.h"
+#include "CommandListener.h"
+#include "NetlinkManager.h"
+#include "cryptfs.h"
+#include "sehandle.h"
+
+#include <base/logging.h>
+#include <base/stringprintf.h>
+#include <cutils/klog.h>
+#include <cutils/properties.h>
+#include <cutils/sockets.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
@@ -21,28 +34,10 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <getopt.h>
-
 #include <fcntl.h>
 #include <dirent.h>
 #include <fs_mgr.h>
 
-#define LOG_TAG "Vold"
-
-#include <base/logging.h>
-#include <base/stringprintf.h>
-#include "cutils/klog.h"
-#include "cutils/log.h"
-#include "cutils/properties.h"
-#include "cutils/sockets.h"
-
-#include "Disk.h"
-#include "VolumeManager.h"
-#include "CommandListener.h"
-#include "NetlinkManager.h"
-#include "DirectVolume.h"
-#include "cryptfs.h"
-#include "sehandle.h"
-
 static int process_config(VolumeManager *vm);
 static void coldboot(const char *path);
 static void parse_args(int argc, char** argv);
@@ -56,11 +51,11 @@
 using android::base::StringPrintf;
 
 int main(int argc, char** argv) {
-    SLOGI("Vold 2.1 (the revenge) firing up");
-
     setenv("ANDROID_LOG_TAGS", "*:v", 1);
     android::base::InitLogging(argv);
 
+    LOG(INFO) << "Vold 3.0 (the awakening) firing up";
+
     VolumeManager *vm;
     CommandListener *cl;
     NetlinkManager *nm;
@@ -82,12 +77,12 @@
 
     /* Create our singleton managers */
     if (!(vm = VolumeManager::Instance())) {
-        SLOGE("Unable to create VolumeManager");
+        LOG(ERROR) << "Unable to create VolumeManager";
         exit(1);
     }
 
     if (!(nm = NetlinkManager::Instance())) {
-        SLOGE("Unable to create NetlinkManager");
+        LOG(ERROR) << "Unable to create NetlinkManager";
         exit(1);
     }
 
@@ -96,16 +91,16 @@
     nm->setBroadcaster((SocketListener *) cl);
 
     if (vm->start()) {
-        SLOGE("Unable to start VolumeManager (%s)", strerror(errno));
+        PLOG(ERROR) << "Unable to start VolumeManager";
         exit(1);
     }
 
     if (process_config(vm)) {
-        SLOGE("Error reading configuration (%s)... continuing anyways", strerror(errno));
+        PLOG(ERROR) << "Error reading configuration... continuing anyways";
     }
 
     if (nm->start()) {
-        SLOGE("Unable to start NetlinkManager (%s)", strerror(errno));
+        PLOG(ERROR) << "Unable to start NetlinkManager";
         exit(1);
     }
 
@@ -116,7 +111,7 @@
      * Now that we're up, we can respond to commands
      */
     if (cl->startListener()) {
-        SLOGE("Unable to start CommandListener (%s)", strerror(errno));
+        PLOG(ERROR) << "Unable to start CommandListener";
         exit(1);
     }
 
@@ -125,7 +120,7 @@
         sleep(1000);
     }
 
-    SLOGI("Vold exiting");
+    LOG(ERROR) << "Vold exiting";
     exit(0);
 }
 
