Loading services/incremental/IncrementalService.cpp +33 −11 Original line number Diff line number Diff line Loading @@ -1086,9 +1086,7 @@ int IncrementalService::makeFile(StorageId storage, std::string_view path, int m return err; } if (params.size > 0) { // Only v2+ incfs supports automatically trimming file over-reserved sizes if (mIncFs->features() & incfs::Features::v2) { if (auto err = mIncFs->reserveSpace(ifs->control, normPath, params.size)) { if (auto err = mIncFs->reserveSpace(ifs->control, id, params.size)) { if (err != -EOPNOTSUPP) { LOG(ERROR) << "Failed to reserve space for a new file: " << err; (void)mIncFs->unlink(ifs->control, normPath); Loading @@ -1098,7 +1096,6 @@ int IncrementalService::makeFile(StorageId storage, std::string_view path, int m "may run out of disk later"; } } } if (!data.empty()) { if (auto err = setFileContent(ifs, id, path, data); err) { (void)mIncFs->unlink(ifs->control, normPath); Loading Loading @@ -1680,6 +1677,15 @@ void IncrementalService::runCmdLooper() { } } void IncrementalService::trimReservedSpaceV1(const IncFsMount& ifs) { mIncFs->forEachFile(ifs.control, [this](auto&& control, auto&& fileId) { if (mIncFs->isFileFullyLoaded(control, fileId) == incfs::LoadingState::Full) { mIncFs->reserveSpace(control, fileId, -1); } return true; }); } void IncrementalService::prepareDataLoaderLocked(IncFsMount& ifs, DataLoaderParamsParcel&& params, DataLoaderStatusListener&& statusListener, const StorageHealthCheckParams& healthCheckParams, Loading @@ -1699,6 +1705,22 @@ void IncrementalService::prepareDataLoaderLocked(IncFsMount& ifs, DataLoaderPara std::move(statusListener), healthCheckParams, std::move(healthListener), path::join(ifs.root, constants().mount)); // pre-v2 IncFS doesn't do automatic reserved space trimming - need to run it manually if (!(mIncFs->features() & incfs::Features::v2)) { addIfsStateCallback(ifs.mountId, [this](StorageId storageId, IfsState state) -> bool { if (!state.fullyLoaded) { return true; } const auto ifs = getIfs(storageId); if (!ifs) { return false; } trimReservedSpaceV1(*ifs); return false; }); } addIfsStateCallback(ifs.mountId, [this](StorageId storageId, IfsState state) -> bool { if (!state.fullyLoaded || state.readLogsEnabled) { return true; Loading services/incremental/IncrementalService.h +2 −0 Original line number Diff line number Diff line Loading @@ -452,6 +452,8 @@ private: StorageLoadingProgressListener&& progressListener); long getMillsSinceOldestPendingRead(StorageId storage); void trimReservedSpaceV1(const IncFsMount& ifs); private: const std::unique_ptr<VoldServiceWrapper> mVold; const std::unique_ptr<DataLoaderManagerWrapper> mDataLoaderManager; Loading services/incremental/ServiceWrappers.cpp +16 −7 Original line number Diff line number Diff line Loading @@ -212,6 +212,9 @@ public: std::string_view path) const final { return incfs::isFullyLoaded(control, path); } incfs::LoadingState isFileFullyLoaded(const Control& control, FileId id) const final { return incfs::isFullyLoaded(control, id); } incfs::LoadingState isEverythingFullyLoaded(const Control& control) const final { return incfs::isEverythingFullyLoaded(control); } Loading @@ -227,9 +230,8 @@ public: ErrorCode writeBlocks(std::span<const incfs::DataBlock> blocks) const final { return incfs::writeBlocks({blocks.data(), size_t(blocks.size())}); } ErrorCode reserveSpace(const Control& control, std::string_view path, IncFsSize size) const final { return incfs::reserveSpace(control, path, size); ErrorCode reserveSpace(const Control& control, FileId id, IncFsSize size) const final { return incfs::reserveSpace(control, id, size); } WaitResult waitForPendingReads(const Control& control, std::chrono::milliseconds timeout, std::vector<incfs::ReadInfo>* pendingReadsBuffer) const final { Loading @@ -238,19 +240,26 @@ public: ErrorCode setUidReadTimeouts(const Control& control, const std::vector<android::os::incremental::PerUidReadTimeouts>& perUidReadTimeouts) const final { std::vector<incfs::UidReadTimeouts> timeouts; timeouts.resize(perUidReadTimeouts.size()); std::vector<incfs::UidReadTimeouts> timeouts(perUidReadTimeouts.size()); for (int i = 0, size = perUidReadTimeouts.size(); i < size; ++i) { auto&& timeout = timeouts[i]; auto& timeout = timeouts[i]; const auto& perUidTimeout = perUidReadTimeouts[i]; timeout.uid = perUidTimeout.uid; timeout.minTimeUs = perUidTimeout.minTimeUs; timeout.minPendingTimeUs = perUidTimeout.minPendingTimeUs; timeout.maxPendingTimeUs = perUidTimeout.maxPendingTimeUs; } return incfs::setUidReadTimeouts(control, timeouts); } ErrorCode forEachFile(const Control& control, FileCallback cb) const final { return incfs::forEachFile(control, [&](auto& control, FileId id) { return cb(control, id); }); } ErrorCode forEachIncompleteFile(const Control& control, FileCallback cb) const final { return incfs::forEachIncompleteFile(control, [&](auto& control, FileId id) { return cb(control, id); }); } }; static JNIEnv* getOrAttachJniEnv(JavaVM* jvm); Loading services/incremental/ServiceWrappers.h +6 −2 Original line number Diff line number Diff line Loading @@ -84,6 +84,8 @@ public: void(std::string_view root, std::string_view backingDir, std::span<std::pair<std::string_view, std::string_view>> binds)>; using FileCallback = android::base::function_ref<bool(const Control& control, FileId fileId)>; static std::string toString(FileId fileId); virtual ~IncFsWrapper() = default; Loading @@ -105,14 +107,14 @@ public: const Control& control, std::string_view path) const = 0; virtual incfs::LoadingState isFileFullyLoaded(const Control& control, std::string_view path) const = 0; virtual incfs::LoadingState isFileFullyLoaded(const Control& control, FileId id) const = 0; virtual incfs::LoadingState isEverythingFullyLoaded(const Control& control) const = 0; virtual ErrorCode link(const Control& control, std::string_view from, std::string_view to) const = 0; virtual ErrorCode unlink(const Control& control, std::string_view path) const = 0; virtual UniqueFd openForSpecialOps(const Control& control, FileId id) const = 0; virtual ErrorCode writeBlocks(std::span<const incfs::DataBlock> blocks) const = 0; virtual ErrorCode reserveSpace(const Control& control, std::string_view path, IncFsSize size) const = 0; virtual ErrorCode reserveSpace(const Control& control, FileId id, IncFsSize size) const = 0; virtual WaitResult waitForPendingReads( const Control& control, std::chrono::milliseconds timeout, std::vector<incfs::ReadInfo>* pendingReadsBuffer) const = 0; Loading @@ -120,6 +122,8 @@ public: const Control& control, const std::vector<::android::os::incremental::PerUidReadTimeouts>& perUidReadTimeouts) const = 0; virtual ErrorCode forEachFile(const Control& control, FileCallback cb) const = 0; virtual ErrorCode forEachIncompleteFile(const Control& control, FileCallback cb) const = 0; }; class AppOpsManagerWrapper { Loading services/incremental/test/IncrementalServiceTest.cpp +7 −5 Original line number Diff line number Diff line Loading @@ -379,6 +379,7 @@ public: std::string_view path)); MOCK_CONST_METHOD2(isFileFullyLoaded, incfs::LoadingState(const Control& control, std::string_view path)); MOCK_CONST_METHOD2(isFileFullyLoaded, incfs::LoadingState(const Control& control, FileId id)); MOCK_CONST_METHOD1(isEverythingFullyLoaded, incfs::LoadingState(const Control& control)); MOCK_CONST_METHOD3(link, ErrorCode(const Control& control, std::string_view from, Loading @@ -386,14 +387,15 @@ public: MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path)); MOCK_CONST_METHOD2(openForSpecialOps, UniqueFd(const Control& control, FileId id)); MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks)); MOCK_CONST_METHOD3(reserveSpace, ErrorCode(const Control& control, std::string_view path, IncFsSize size)); MOCK_CONST_METHOD3(reserveSpace, ErrorCode(const Control& control, FileId id, IncFsSize size)); MOCK_CONST_METHOD3(waitForPendingReads, WaitResult(const Control& control, std::chrono::milliseconds timeout, std::vector<incfs::ReadInfo>* pendingReadsBuffer)); MOCK_CONST_METHOD2(setUidReadTimeouts, ErrorCode(const Control& control, const std::vector<PerUidReadTimeouts>& perUidReadTimeouts)); MOCK_CONST_METHOD2(forEachFile, ErrorCode(const Control& control, FileCallback cb)); MOCK_CONST_METHOD2(forEachIncompleteFile, ErrorCode(const Control& control, FileCallback cb)); MockIncFs() { ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return()); Loading Loading @@ -1594,7 +1596,7 @@ TEST_F(IncrementalServiceTest, testIsFileFullyLoadedNoData) { int storageId = mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, IncrementalService::CreateOptions::CreateNew); EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, _)) EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, An<std::string_view>())) .Times(1) .WillOnce(Return(incfs::LoadingState::MissingBlocks)); ASSERT_GT((int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk"), 0); Loading @@ -1605,7 +1607,7 @@ TEST_F(IncrementalServiceTest, testIsFileFullyLoadedError) { int storageId = mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, IncrementalService::CreateOptions::CreateNew); EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, _)) EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, An<std::string_view>())) .Times(1) .WillOnce(Return(incfs::LoadingState(-1))); ASSERT_LT((int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk"), 0); Loading @@ -1616,7 +1618,7 @@ TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccess) { int storageId = mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, IncrementalService::CreateOptions::CreateNew); EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, _)) EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, An<std::string_view>())) .Times(1) .WillOnce(Return(incfs::LoadingState::Full)); ASSERT_EQ(0, (int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk")); Loading Loading
services/incremental/IncrementalService.cpp +33 −11 Original line number Diff line number Diff line Loading @@ -1086,9 +1086,7 @@ int IncrementalService::makeFile(StorageId storage, std::string_view path, int m return err; } if (params.size > 0) { // Only v2+ incfs supports automatically trimming file over-reserved sizes if (mIncFs->features() & incfs::Features::v2) { if (auto err = mIncFs->reserveSpace(ifs->control, normPath, params.size)) { if (auto err = mIncFs->reserveSpace(ifs->control, id, params.size)) { if (err != -EOPNOTSUPP) { LOG(ERROR) << "Failed to reserve space for a new file: " << err; (void)mIncFs->unlink(ifs->control, normPath); Loading @@ -1098,7 +1096,6 @@ int IncrementalService::makeFile(StorageId storage, std::string_view path, int m "may run out of disk later"; } } } if (!data.empty()) { if (auto err = setFileContent(ifs, id, path, data); err) { (void)mIncFs->unlink(ifs->control, normPath); Loading Loading @@ -1680,6 +1677,15 @@ void IncrementalService::runCmdLooper() { } } void IncrementalService::trimReservedSpaceV1(const IncFsMount& ifs) { mIncFs->forEachFile(ifs.control, [this](auto&& control, auto&& fileId) { if (mIncFs->isFileFullyLoaded(control, fileId) == incfs::LoadingState::Full) { mIncFs->reserveSpace(control, fileId, -1); } return true; }); } void IncrementalService::prepareDataLoaderLocked(IncFsMount& ifs, DataLoaderParamsParcel&& params, DataLoaderStatusListener&& statusListener, const StorageHealthCheckParams& healthCheckParams, Loading @@ -1699,6 +1705,22 @@ void IncrementalService::prepareDataLoaderLocked(IncFsMount& ifs, DataLoaderPara std::move(statusListener), healthCheckParams, std::move(healthListener), path::join(ifs.root, constants().mount)); // pre-v2 IncFS doesn't do automatic reserved space trimming - need to run it manually if (!(mIncFs->features() & incfs::Features::v2)) { addIfsStateCallback(ifs.mountId, [this](StorageId storageId, IfsState state) -> bool { if (!state.fullyLoaded) { return true; } const auto ifs = getIfs(storageId); if (!ifs) { return false; } trimReservedSpaceV1(*ifs); return false; }); } addIfsStateCallback(ifs.mountId, [this](StorageId storageId, IfsState state) -> bool { if (!state.fullyLoaded || state.readLogsEnabled) { return true; Loading
services/incremental/IncrementalService.h +2 −0 Original line number Diff line number Diff line Loading @@ -452,6 +452,8 @@ private: StorageLoadingProgressListener&& progressListener); long getMillsSinceOldestPendingRead(StorageId storage); void trimReservedSpaceV1(const IncFsMount& ifs); private: const std::unique_ptr<VoldServiceWrapper> mVold; const std::unique_ptr<DataLoaderManagerWrapper> mDataLoaderManager; Loading
services/incremental/ServiceWrappers.cpp +16 −7 Original line number Diff line number Diff line Loading @@ -212,6 +212,9 @@ public: std::string_view path) const final { return incfs::isFullyLoaded(control, path); } incfs::LoadingState isFileFullyLoaded(const Control& control, FileId id) const final { return incfs::isFullyLoaded(control, id); } incfs::LoadingState isEverythingFullyLoaded(const Control& control) const final { return incfs::isEverythingFullyLoaded(control); } Loading @@ -227,9 +230,8 @@ public: ErrorCode writeBlocks(std::span<const incfs::DataBlock> blocks) const final { return incfs::writeBlocks({blocks.data(), size_t(blocks.size())}); } ErrorCode reserveSpace(const Control& control, std::string_view path, IncFsSize size) const final { return incfs::reserveSpace(control, path, size); ErrorCode reserveSpace(const Control& control, FileId id, IncFsSize size) const final { return incfs::reserveSpace(control, id, size); } WaitResult waitForPendingReads(const Control& control, std::chrono::milliseconds timeout, std::vector<incfs::ReadInfo>* pendingReadsBuffer) const final { Loading @@ -238,19 +240,26 @@ public: ErrorCode setUidReadTimeouts(const Control& control, const std::vector<android::os::incremental::PerUidReadTimeouts>& perUidReadTimeouts) const final { std::vector<incfs::UidReadTimeouts> timeouts; timeouts.resize(perUidReadTimeouts.size()); std::vector<incfs::UidReadTimeouts> timeouts(perUidReadTimeouts.size()); for (int i = 0, size = perUidReadTimeouts.size(); i < size; ++i) { auto&& timeout = timeouts[i]; auto& timeout = timeouts[i]; const auto& perUidTimeout = perUidReadTimeouts[i]; timeout.uid = perUidTimeout.uid; timeout.minTimeUs = perUidTimeout.minTimeUs; timeout.minPendingTimeUs = perUidTimeout.minPendingTimeUs; timeout.maxPendingTimeUs = perUidTimeout.maxPendingTimeUs; } return incfs::setUidReadTimeouts(control, timeouts); } ErrorCode forEachFile(const Control& control, FileCallback cb) const final { return incfs::forEachFile(control, [&](auto& control, FileId id) { return cb(control, id); }); } ErrorCode forEachIncompleteFile(const Control& control, FileCallback cb) const final { return incfs::forEachIncompleteFile(control, [&](auto& control, FileId id) { return cb(control, id); }); } }; static JNIEnv* getOrAttachJniEnv(JavaVM* jvm); Loading
services/incremental/ServiceWrappers.h +6 −2 Original line number Diff line number Diff line Loading @@ -84,6 +84,8 @@ public: void(std::string_view root, std::string_view backingDir, std::span<std::pair<std::string_view, std::string_view>> binds)>; using FileCallback = android::base::function_ref<bool(const Control& control, FileId fileId)>; static std::string toString(FileId fileId); virtual ~IncFsWrapper() = default; Loading @@ -105,14 +107,14 @@ public: const Control& control, std::string_view path) const = 0; virtual incfs::LoadingState isFileFullyLoaded(const Control& control, std::string_view path) const = 0; virtual incfs::LoadingState isFileFullyLoaded(const Control& control, FileId id) const = 0; virtual incfs::LoadingState isEverythingFullyLoaded(const Control& control) const = 0; virtual ErrorCode link(const Control& control, std::string_view from, std::string_view to) const = 0; virtual ErrorCode unlink(const Control& control, std::string_view path) const = 0; virtual UniqueFd openForSpecialOps(const Control& control, FileId id) const = 0; virtual ErrorCode writeBlocks(std::span<const incfs::DataBlock> blocks) const = 0; virtual ErrorCode reserveSpace(const Control& control, std::string_view path, IncFsSize size) const = 0; virtual ErrorCode reserveSpace(const Control& control, FileId id, IncFsSize size) const = 0; virtual WaitResult waitForPendingReads( const Control& control, std::chrono::milliseconds timeout, std::vector<incfs::ReadInfo>* pendingReadsBuffer) const = 0; Loading @@ -120,6 +122,8 @@ public: const Control& control, const std::vector<::android::os::incremental::PerUidReadTimeouts>& perUidReadTimeouts) const = 0; virtual ErrorCode forEachFile(const Control& control, FileCallback cb) const = 0; virtual ErrorCode forEachIncompleteFile(const Control& control, FileCallback cb) const = 0; }; class AppOpsManagerWrapper { Loading
services/incremental/test/IncrementalServiceTest.cpp +7 −5 Original line number Diff line number Diff line Loading @@ -379,6 +379,7 @@ public: std::string_view path)); MOCK_CONST_METHOD2(isFileFullyLoaded, incfs::LoadingState(const Control& control, std::string_view path)); MOCK_CONST_METHOD2(isFileFullyLoaded, incfs::LoadingState(const Control& control, FileId id)); MOCK_CONST_METHOD1(isEverythingFullyLoaded, incfs::LoadingState(const Control& control)); MOCK_CONST_METHOD3(link, ErrorCode(const Control& control, std::string_view from, Loading @@ -386,14 +387,15 @@ public: MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path)); MOCK_CONST_METHOD2(openForSpecialOps, UniqueFd(const Control& control, FileId id)); MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks)); MOCK_CONST_METHOD3(reserveSpace, ErrorCode(const Control& control, std::string_view path, IncFsSize size)); MOCK_CONST_METHOD3(reserveSpace, ErrorCode(const Control& control, FileId id, IncFsSize size)); MOCK_CONST_METHOD3(waitForPendingReads, WaitResult(const Control& control, std::chrono::milliseconds timeout, std::vector<incfs::ReadInfo>* pendingReadsBuffer)); MOCK_CONST_METHOD2(setUidReadTimeouts, ErrorCode(const Control& control, const std::vector<PerUidReadTimeouts>& perUidReadTimeouts)); MOCK_CONST_METHOD2(forEachFile, ErrorCode(const Control& control, FileCallback cb)); MOCK_CONST_METHOD2(forEachIncompleteFile, ErrorCode(const Control& control, FileCallback cb)); MockIncFs() { ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return()); Loading Loading @@ -1594,7 +1596,7 @@ TEST_F(IncrementalServiceTest, testIsFileFullyLoadedNoData) { int storageId = mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, IncrementalService::CreateOptions::CreateNew); EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, _)) EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, An<std::string_view>())) .Times(1) .WillOnce(Return(incfs::LoadingState::MissingBlocks)); ASSERT_GT((int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk"), 0); Loading @@ -1605,7 +1607,7 @@ TEST_F(IncrementalServiceTest, testIsFileFullyLoadedError) { int storageId = mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, IncrementalService::CreateOptions::CreateNew); EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, _)) EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, An<std::string_view>())) .Times(1) .WillOnce(Return(incfs::LoadingState(-1))); ASSERT_LT((int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk"), 0); Loading @@ -1616,7 +1618,7 @@ TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccess) { int storageId = mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, IncrementalService::CreateOptions::CreateNew); EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, _)) EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, An<std::string_view>())) .Times(1) .WillOnce(Return(incfs::LoadingState::Full)); ASSERT_EQ(0, (int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk")); Loading