From 333d4efe4f2356d9898e1749f49eef5c3931af11 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Fri, 25 Apr 2014 17:20:34 +0200 Subject: [PATCH] packagefs: Extend PACKAGE_FS_OPERATION_GET_PACKAGE_INFOS ioctl Also return the package file names. --- headers/private/package/packagefs.h | 9 +++--- .../file_systems/packagefs/volume/Volume.cpp | 29 ++++++++++++++----- src/servers/package/Volume.cpp | 9 ++---- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/headers/private/package/packagefs.h b/headers/private/package/packagefs.h index 3fc54f74b4..9b766dcd2a 100644 --- a/headers/private/package/packagefs.h +++ b/headers/private/package/packagefs.h @@ -57,17 +57,18 @@ struct PackageFSVolumeInfo { // PACKAGE_FS_OPERATION_GET_PACKAGE_INFOS struct PackageFSPackageInfo { - // node_ref of the package file and the containing directory + // node_ref and entry_ref of the package file dev_t packageDeviceID; dev_t directoryDeviceID; ino_t packageNodeID; ino_t directoryNodeID; + const char* name; }; struct PackageFSGetPackageInfosRequest { - // Filled in by the FS. packageCount is set to the actual package count, - // even if it is greater than the array, so the caller can determine whether - // the array was large enough. + // Filled in by the FS. bufferSize is set to the required buffer size, even + // even if the provided buffer is smaller. + uint32 bufferSize; uint32 packageCount; PackageFSPackageInfo infos[1]; }; diff --git a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp index f58c1bca04..7007d007ef 100644 --- a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp @@ -508,6 +508,10 @@ Volume::IOCtl(Node* node, uint32 operation, void* buffer, size_t size) VolumeReadLocker volumeReadLocker(this); + addr_t bufferEnd = (addr_t)buffer + size; + uint32 packageCount = fPackages.CountElements(); + char* nameBuffer = (char*)(request->infos + packageCount); + uint32 packageIndex = 0; for (PackageFileNameHashTable::Iterator it = fPackages.GetIterator(); it.HasNext(); @@ -519,18 +523,29 @@ Volume::IOCtl(Node* node, uint32 operation, void* buffer, size_t size) PackagesDirectory* directory = package->Directory(); info.directoryDeviceID = directory->DeviceID(); info.directoryNodeID = directory->NodeID(); + info.name = nameBuffer; PackageFSPackageInfo* userInfo = request->infos + packageIndex; - if (addr_t(userInfo + 1) > (addr_t)buffer + size) - break; + if (addr_t(userInfo + 1) <= bufferEnd) { + if (user_memcpy(userInfo, &info, sizeof(info)) != B_OK) + return B_BAD_ADDRESS; + } - if (user_memcpy(userInfo, &info, sizeof(info)) != B_OK) - return B_BAD_ADDRESS; + const char* name = package->FileName(); + size_t nameSize = strlen(name) + 1; + char* nameEnd = nameBuffer + nameSize; + if ((addr_t)nameEnd <= bufferEnd) { + if (user_memcpy(nameBuffer, name, nameSize) != B_OK) + return B_BAD_ADDRESS; + } + nameBuffer = nameEnd; } - uint32 packageCount = fPackages.CountElements(); - RETURN_ERROR(user_memcpy(&request->packageCount, &packageCount, - sizeof(packageCount))); + PackageFSGetPackageInfosRequest header; + header.bufferSize = nameBuffer - (char*)request; + header.packageCount = packageCount; + size_t headerSize = (char*)&request->infos - (char*)request; + RETURN_ERROR(user_memcpy(request, &header, headerSize)); } case PACKAGE_FS_OPERATION_CHANGE_ACTIVATION: diff --git a/src/servers/package/Volume.cpp b/src/servers/package/Volume.cpp index 1ebffe6919..17541bc742 100644 --- a/src/servers/package/Volume.cpp +++ b/src/servers/package/Volume.cpp @@ -962,13 +962,10 @@ status_t Volume::_GetActivePackages(int fd) { // TODO: Adjust for old state support! - uint32 maxPackageCount = 16 * 1024; PackageFSGetPackageInfosRequest* request = NULL; MemoryDeleter requestDeleter; - size_t bufferSize; + size_t bufferSize = 64 * 1024; for (;;) { - bufferSize = sizeof(PackageFSGetPackageInfosRequest) - + (maxPackageCount - 1) * sizeof(PackageFSPackageInfo); request = (PackageFSGetPackageInfosRequest*)malloc(bufferSize); if (request == NULL) RETURN_ERROR(B_NO_MEMORY); @@ -981,10 +978,10 @@ Volume::_GetActivePackages(int fd) RETURN_ERROR(errno); } - if (request->packageCount <= maxPackageCount) + if (request->bufferSize <= bufferSize) break; - maxPackageCount = request->packageCount; + bufferSize = request->bufferSize; requestDeleter.Unset(); }