diff --git a/Loop.cpp b/Loop.cpp index 064e553..1b3879a 100644 --- a/Loop.cpp +++ b/Loop.cpp @@ -20,6 +20,9 @@ #include #include +#include +#include + #define LOG_TAG "Vold" #include @@ -69,29 +72,41 @@ int Loop::lookupActive(const char *loopFile, char *buffer, size_t len) { return 0; } -int Loop::getNextAvailable(char *buffer, size_t len) { +int Loop::create(const char *loopFile, char *loopDeviceBuffer, size_t len) { int i; int fd; char filename[256]; - memset(buffer, 0, len); - for (i = 0; i < LOOP_MAX; i++) { struct loop_info li; int rc; sprintf(filename, "/dev/block/loop%d", i); + /* + * The kernel starts us off with 8 loop nodes, but more + * are created on-demand if needed. + */ + mode_t mode = 0660 | S_IFBLK; + dev_t dev = (7 << 8) | i; + if (mknod(filename, mode, dev) < 0) { + if (errno != EEXIST) { + LOGE("Error creating loop device node (%s)", strerror(errno)); + return -1; + } + } + if ((fd = open(filename, O_RDWR)) < 0) { LOGE("Unable to open %s (%s)", filename, strerror(errno)); return -1; } rc = ioctl(fd, LOOP_GET_STATUS, &li); - close(fd); if (rc < 0 && errno == ENXIO) break; + close(fd); + if (rc < 0) { LOGE("Unable to get loop status for %s (%s)", filename, strerror(errno)); @@ -104,22 +119,11 @@ int Loop::getNextAvailable(char *buffer, size_t len) { errno = ENOSPC; return -1; } - strncpy(buffer, filename, len -1); - return 0; -} -int Loop::create(const char *loopDevice, const char *loopFile) { - int fd; + strncpy(loopDeviceBuffer, filename, len -1); + int file_fd; - LOGD("Creating loop for file '%s' into loop device '%s'", loopFile, - loopDevice); - if ((fd = open(loopDevice, O_RDWR)) < 0) { - LOGE("Unable to open loop device %s (%s)", loopDevice, - strerror(errno)); - return -1; - } - if ((file_fd = open(loopFile, O_RDWR)) < 0) { LOGE("Unable to open %s (%s)", loopFile, strerror(errno)); close(fd); diff --git a/Loop.h b/Loop.h index 540db8b..1ade4f9 100644 --- a/Loop.h +++ b/Loop.h @@ -22,12 +22,10 @@ class Loop { public: - static const int LOOP_MAX = 8; + static const int LOOP_MAX = 255; public: - static int getNextAvailable(char *buffer, size_t len); static int lookupActive(const char *loopFile, char *buffer, size_t len); - - static int create(const char *loopDevice, const char *loopFile); + static int create(const char *loopFile, char *loopDeviceBuffer, size_t len); static int destroyByDevice(const char *loopDevice); static int destroyByFile(const char *loopFile); static int createImageFile(const char *file, size_t sizeMb); diff --git a/VolumeManager.cpp b/VolumeManager.cpp index 1e1f15f..a462196 100644 --- a/VolumeManager.cpp +++ b/VolumeManager.cpp @@ -198,12 +198,7 @@ int VolumeManager::createAsec(const char *id, int sizeMb, } char loopDevice[255]; - if (Loop::getNextAvailable(loopDevice, sizeof(loopDevice))) { - unlink(asecFileName); - return -1; - } - - if (Loop::create(loopDevice, asecFileName)) { + if (Loop::create(asecFileName, loopDevice, sizeof(loopDevice))) { LOGE("ASEC loop device creation failed (%s)", strerror(errno)); unlink(asecFileName); return -1; @@ -327,12 +322,7 @@ int VolumeManager::mountAsec(const char *id, const char *key, int ownerUid) { char loopDevice[255]; if (Loop::lookupActive(asecFileName, loopDevice, sizeof(loopDevice))) { - if (Loop::getNextAvailable(loopDevice, sizeof(loopDevice))) { - LOGE("Unable to find loop device for ASEC mount"); - return -1; - } - - if (Loop::create(loopDevice, asecFileName)) { + if (Loop::create(asecFileName, loopDevice, sizeof(loopDevice))) { LOGE("ASEC loop device creation failed (%s)", strerror(errno)); return -1; }