packagefs: Extend PACKAGE_FS_OPERATION_GET_PACKAGE_INFOS ioctl

Also return the package file names.
This commit is contained in:
Ingo Weinhold
2014-04-26 15:34:18 +02:00
parent ba4c67b4b0
commit 333d4efe4f
3 changed files with 30 additions and 17 deletions
+5 -4
View File
@@ -57,17 +57,18 @@ struct PackageFSVolumeInfo {
// PACKAGE_FS_OPERATION_GET_PACKAGE_INFOS // PACKAGE_FS_OPERATION_GET_PACKAGE_INFOS
struct PackageFSPackageInfo { 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 packageDeviceID;
dev_t directoryDeviceID; dev_t directoryDeviceID;
ino_t packageNodeID; ino_t packageNodeID;
ino_t directoryNodeID; ino_t directoryNodeID;
const char* name;
}; };
struct PackageFSGetPackageInfosRequest { struct PackageFSGetPackageInfosRequest {
// Filled in by the FS. packageCount is set to the actual package count, // Filled in by the FS. bufferSize is set to the required buffer size, even
// even if it is greater than the array, so the caller can determine whether // even if the provided buffer is smaller.
// the array was large enough. uint32 bufferSize;
uint32 packageCount; uint32 packageCount;
PackageFSPackageInfo infos[1]; PackageFSPackageInfo infos[1];
}; };
@@ -508,6 +508,10 @@ Volume::IOCtl(Node* node, uint32 operation, void* buffer, size_t size)
VolumeReadLocker volumeReadLocker(this); VolumeReadLocker volumeReadLocker(this);
addr_t bufferEnd = (addr_t)buffer + size;
uint32 packageCount = fPackages.CountElements();
char* nameBuffer = (char*)(request->infos + packageCount);
uint32 packageIndex = 0; uint32 packageIndex = 0;
for (PackageFileNameHashTable::Iterator it for (PackageFileNameHashTable::Iterator it
= fPackages.GetIterator(); it.HasNext(); = fPackages.GetIterator(); it.HasNext();
@@ -519,18 +523,29 @@ Volume::IOCtl(Node* node, uint32 operation, void* buffer, size_t size)
PackagesDirectory* directory = package->Directory(); PackagesDirectory* directory = package->Directory();
info.directoryDeviceID = directory->DeviceID(); info.directoryDeviceID = directory->DeviceID();
info.directoryNodeID = directory->NodeID(); info.directoryNodeID = directory->NodeID();
info.name = nameBuffer;
PackageFSPackageInfo* userInfo = request->infos + packageIndex; PackageFSPackageInfo* userInfo = request->infos + packageIndex;
if (addr_t(userInfo + 1) > (addr_t)buffer + size) if (addr_t(userInfo + 1) <= bufferEnd) {
break; if (user_memcpy(userInfo, &info, sizeof(info)) != B_OK)
return B_BAD_ADDRESS;
}
if (user_memcpy(userInfo, &info, sizeof(info)) != B_OK) const char* name = package->FileName();
return B_BAD_ADDRESS; 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(); PackageFSGetPackageInfosRequest header;
RETURN_ERROR(user_memcpy(&request->packageCount, &packageCount, header.bufferSize = nameBuffer - (char*)request;
sizeof(packageCount))); header.packageCount = packageCount;
size_t headerSize = (char*)&request->infos - (char*)request;
RETURN_ERROR(user_memcpy(request, &header, headerSize));
} }
case PACKAGE_FS_OPERATION_CHANGE_ACTIVATION: case PACKAGE_FS_OPERATION_CHANGE_ACTIVATION:
+3 -6
View File
@@ -962,13 +962,10 @@ status_t
Volume::_GetActivePackages(int fd) Volume::_GetActivePackages(int fd)
{ {
// TODO: Adjust for old state support! // TODO: Adjust for old state support!
uint32 maxPackageCount = 16 * 1024;
PackageFSGetPackageInfosRequest* request = NULL; PackageFSGetPackageInfosRequest* request = NULL;
MemoryDeleter requestDeleter; MemoryDeleter requestDeleter;
size_t bufferSize; size_t bufferSize = 64 * 1024;
for (;;) { for (;;) {
bufferSize = sizeof(PackageFSGetPackageInfosRequest)
+ (maxPackageCount - 1) * sizeof(PackageFSPackageInfo);
request = (PackageFSGetPackageInfosRequest*)malloc(bufferSize); request = (PackageFSGetPackageInfosRequest*)malloc(bufferSize);
if (request == NULL) if (request == NULL)
RETURN_ERROR(B_NO_MEMORY); RETURN_ERROR(B_NO_MEMORY);
@@ -981,10 +978,10 @@ Volume::_GetActivePackages(int fd)
RETURN_ERROR(errno); RETURN_ERROR(errno);
} }
if (request->packageCount <= maxPackageCount) if (request->bufferSize <= bufferSize)
break; break;
maxPackageCount = request->packageCount; bufferSize = request->bufferSize;
requestDeleter.Unset(); requestDeleter.Unset();
} }