packagefs: Extend PACKAGE_FS_OPERATION_GET_PACKAGE_INFOS ioctl

Also return the package file names.
This commit is contained in:
Ingo Weinhold 2014-04-25 17:20:34 +02:00
parent ba4c67b4b0
commit 333d4efe4f
3 changed files with 30 additions and 17 deletions

View File

@ -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];
};

View File

@ -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:

View File

@ -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();
}