From 2d91773d2e07651749bacd0b5b144366df9fdc6f Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Fri, 18 Apr 2014 23:29:59 +0200 Subject: [PATCH] Adjust packagefs ioctl interface to support old states * PackageFSVolumeInfo: Add the directories for all relevant states. * PackageFSPackageInfo: Include the package file's parent directory node ref. Package daemon and package kit still don't support old states yet. --- headers/private/package/packagefs.h | 24 ++++++++--- .../file_systems/packagefs/package/Package.h | 2 + .../file_systems/packagefs/volume/Volume.cpp | 43 ++++++++++++++++--- src/servers/package/Volume.cpp | 6 ++- 4 files changed, 60 insertions(+), 15 deletions(-) diff --git a/headers/private/package/packagefs.h b/headers/private/package/packagefs.h index fe063d371c..3fc54f74b4 100644 --- a/headers/private/package/packagefs.h +++ b/headers/private/package/packagefs.h @@ -30,26 +30,38 @@ enum { // PACKAGE_FS_OPERATION_GET_VOLUME_INFO +struct PackageFSDirectoryInfo { + // node_ref of the directory + dev_t deviceID; + ino_t nodeID; +}; + struct PackageFSVolumeInfo { PackageFSMountType mountType; // device and node id of the respective package FS root scope (e.g. "/boot" // for the three standard volumes) - dev_t rootDeviceID; - ino_t rootDirectoryID; + dev_t rootDeviceID; + ino_t rootDirectoryID; - // device and node id of the volume's packages directory - dev_t packagesDeviceID; - ino_t packagesDirectoryID; + // packageCount is set to the actual packages directory count, even if it is + // greater than the array, so the caller can determine whether the array was + // large enough. + // The directories are ordered from the most recent state (the actual + // "packages" directory) to the oldest one, the one that is actually active. + uint32 packagesDirectoryCount; + PackageFSDirectoryInfo packagesDirectoryInfos[1]; }; // PACKAGE_FS_OPERATION_GET_PACKAGE_INFOS struct PackageFSPackageInfo { - // node_ref of the package file + // node_ref of the package file and the containing directory dev_t packageDeviceID; + dev_t directoryDeviceID; ino_t packageNodeID; + ino_t directoryNodeID; }; struct PackageFSGetPackageInfosRequest { diff --git a/src/add-ons/kernel/file_systems/packagefs/package/Package.h b/src/add-ons/kernel/file_systems/packagefs/package/Package.h index b597b509bf..e9def7503e 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/Package.h +++ b/src/add-ons/kernel/file_systems/packagefs/package/Package.h @@ -58,6 +58,8 @@ public: { return fDeviceID; } ino_t NodeID() const { return fNodeID; } + PackagesDirectory* Directory() const + { return fPackagesDirectory; } void SetInstallPath(const String& installPath); const String& InstallPath() const { return fInstallPath; } 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 92972f13ae..6c8cc67234 100644 --- a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp @@ -461,16 +461,41 @@ Volume::IOCtl(Node* node, uint32 operation, void* buffer, size_t size) if (size != sizeof(PackageFSVolumeInfo)) RETURN_ERROR(B_BAD_VALUE); + PackageFSVolumeInfo* userVolumeInfo + = (PackageFSVolumeInfo*)buffer; + VolumeReadLocker volumeReadLocker(this); - PackageFSVolumeInfo info; - info.mountType = fMountType; - info.rootDeviceID = fPackageFSRoot->DeviceID(); - info.rootDirectoryID = fPackageFSRoot->NodeID(); - info.packagesDeviceID = fPackagesDirectory->DeviceID(); - info.packagesDirectoryID = fPackagesDirectory->NodeID(); + PackageFSVolumeInfo volumeInfo; + volumeInfo.mountType = fMountType; + volumeInfo.rootDeviceID = fPackageFSRoot->DeviceID(); + volumeInfo.rootDirectoryID = fPackageFSRoot->NodeID(); + volumeInfo.packagesDirectoryCount = fPackagesDirectories.Count(); - RETURN_ERROR(user_memcpy(buffer, &info, sizeof(info))); + status_t error = user_memcpy(userVolumeInfo, &volumeInfo, + sizeof(volumeInfo)); + if (error != B_OK) + RETURN_ERROR(error); + + uint32 directoryIndex = 0; + for (PackagesDirectoryList::Iterator it + = fPackagesDirectories.GetIterator(); + PackagesDirectory* directory = it.Next(); + directoryIndex++) { + PackageFSDirectoryInfo info; + info.deviceID = directory->DeviceID(); + info.nodeID = directory->NodeID(); + + PackageFSDirectoryInfo* userInfo + = userVolumeInfo->packagesDirectoryInfos + directoryIndex; + if (addr_t(userInfo + 1) > (addr_t)buffer + size) + break; + + if (user_memcpy(userInfo, &info, sizeof(info)) != B_OK) + return B_BAD_ADDRESS; + } + + return B_OK; } case PACKAGE_FS_OPERATION_GET_PACKAGE_INFOS: @@ -491,6 +516,10 @@ Volume::IOCtl(Node* node, uint32 operation, void* buffer, size_t size) PackageFSPackageInfo info; info.packageDeviceID = package->DeviceID(); info.packageNodeID = package->NodeID(); + PackagesDirectory* directory = package->Directory(); + info.directoryDeviceID = directory->DeviceID(); + info.directoryNodeID = directory->NodeID(); + PackageFSPackageInfo* userInfo = request->infos + packageIndex; if (addr_t(userInfo + 1) > (addr_t)buffer + size) break; diff --git a/src/servers/package/Volume.cpp b/src/servers/package/Volume.cpp index 5f0708471f..ad5df11453 100644 --- a/src/servers/package/Volume.cpp +++ b/src/servers/package/Volume.cpp @@ -1556,8 +1556,9 @@ Volume::Init(const node_ref& rootDirectoryRef, node_ref& _packageRootRef) } fMountType = info.mountType; - fPackagesDirectoryRef.device = info.packagesDeviceID; - fPackagesDirectoryRef.node = info.packagesDirectoryID; + fPackagesDirectoryRef.device = info.packagesDirectoryInfos[0].deviceID; + fPackagesDirectoryRef.node = info.packagesDirectoryInfos[0].nodeID; +// TODO: Adjust for old state support! _packageRootRef.device = info.rootDeviceID; _packageRootRef.node = info.rootDirectoryID; @@ -2293,6 +2294,7 @@ Volume::_ReadPackagesDirectory() status_t Volume::_GetActivePackages(int fd) { +// TODO: Adjust for old state support! uint32 maxPackageCount = 16 * 1024; PackageFSGetPackageInfosRequest* request = NULL; MemoryDeleter requestDeleter;