1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 15:28:11 +00:00

Kernel: Make AnonymousVMObject::clone() API OOM safe

Propagate allocation failure of m_shared_committed_cow_pages,
and uncommit previously committed COW pages on failure.

This method needs a closer look in terms of error handling, as we
will eventually need to rollback all changes on allocation failure.
Alternatively we could allocate the anonymous object much earlier
and only initialize it once the other steps have succeeded.
This commit is contained in:
Brian Gianforcaro 2021-05-28 03:52:30 -07:00 committed by Andreas Kling
parent 65d5f81afc
commit cb45b2c001

View file

@ -33,18 +33,25 @@ RefPtr<VMObject> AnonymousVMObject::clone()
if (!MM.commit_user_physical_pages(need_cow_pages))
return {};
// Create or replace the committed cow pages. When cloning a previously
// cloned vmobject, we want to essentially "fork", leaving us and the
// new clone with one set of shared committed cow pages, and the original
// one would keep the one it still has. This ensures that the original
// one and this one, as well as the clone have sufficient resources
// to cow all pages as needed
m_shared_committed_cow_pages = adopt_ref(*new CommittedCowPages(need_cow_pages));
m_shared_committed_cow_pages = adopt_ref_if_nonnull(new CommittedCowPages(need_cow_pages));
if (!m_shared_committed_cow_pages) {
MM.uncommit_user_physical_pages(need_cow_pages);
return {};
}
// Both original and clone become COW. So create a COW map for ourselves
// or reset all pages to be copied again if we were previously cloned
ensure_or_reset_cow_map();
// FIXME: If this allocation fails, we need to rollback all changes.
return adopt_ref_if_nonnull(new AnonymousVMObject(*this));
}