From 69a1f1f53f7167363b17eeba6141b92bd8dfd4d3 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Tue, 21 May 2013 00:41:31 +0200 Subject: [PATCH] packagefs: Fix attribute indexing Since the package nodes' attributes are indexed before the VFS has accessed any of its nodes, the package wasn't open and reading the attribute data would fail. We do now open the package explicitly in UnpackingAttributeCookie::IndexAttribute(). Moreover, as an optimization, we also open the package in Volume::_AddPackageContent(), so the package file isn't repeatedly opened and closed as its nodes are being registered. --- .../packagefs/nodes/UnpackingAttributeCookie.cpp | 9 +++++++++ .../kernel/file_systems/packagefs/volume/Volume.cpp | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeCookie.cpp b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeCookie.cpp index 81ec8cbc18..867380f58c 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeCookie.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeCookie.cpp @@ -163,6 +163,15 @@ UnpackingAttributeCookie::IndexAttribute(PackageNode* packageNode, // read the attribute if (toRead > 0) { + // The package must be open or otherwise reading the attribute data + // may fail. + int fd = packageNode->GetPackage()->Open(); + if (fd < 0) { + indexer->DeleteCookie(); + return fd; + } + PackageCloser packageCloser(packageNode->GetPackage()); + error = ReadAttribute(packageNode, attribute, 0, data, &toRead); if (error != B_OK) { indexer->DeleteCookie(); 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 4a53765061..fc24afe94a 100644 --- a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp @@ -949,6 +949,16 @@ Volume::_FindPackage(const char* fileName) const status_t Volume::_AddPackageContent(Package* package, bool notify) { + // Open the package. We don't need the FD here, but this is an optimization. + // The attribute indices may want to read the package nodes' attributes and + // the package file would be opened and closed for each attribute instance. + // Since Package keeps and shares the FD as long as at least one party has + // the package open, we prevent that. + int fd = package->Open(); + if (fd < 0) + RETURN_ERROR(fd); + PackageCloser packageCloser(package); + status_t error = fPackageFSRoot->AddPackage(package); if (error != B_OK) RETURN_ERROR(error);