packagefs: Extend PACKAGE_FS_OPERATION_GET_PACKAGE_INFOS ioctl
Also return the package file names.
This commit is contained in:
parent
ba4c67b4b0
commit
333d4efe4f
@ -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];
|
||||
};
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user