packagefs: Extend PACKAGE_FS_OPERATION_GET_PACKAGE_INFOS ioctl
Also return the package file names.
This commit is contained in:
@@ -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)
|
if (user_memcpy(userInfo, &info, sizeof(info)) != B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 packageCount = fPackages.CountElements();
|
const char* name = package->FileName();
|
||||||
RETURN_ERROR(user_memcpy(&request->packageCount, &packageCount,
|
size_t nameSize = strlen(name) + 1;
|
||||||
sizeof(packageCount)));
|
char* nameEnd = nameBuffer + nameSize;
|
||||||
|
if ((addr_t)nameEnd <= bufferEnd) {
|
||||||
|
if (user_memcpy(nameBuffer, name, nameSize) != B_OK)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
}
|
||||||
|
nameBuffer = nameEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
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:
|
case PACKAGE_FS_OPERATION_CHANGE_ACTIVATION:
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user