summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2020-01-03 15:40:03 +0100
committerAndreas Kling <awesomekling@gmail.com>2020-01-03 15:40:03 +0100
commitaba782972440cea5d95df9401fb27baef4bbfdec (patch)
treefd5fc861f80d9f4be4810bfc01b6263bce2928d1
parent1dc64ec0641ac5a6cd9d6a774602bb0ebcde9cde (diff)
downloadserenity-aba782972440cea5d95df9401fb27baef4bbfdec.zip
Kernel: InodeVMObject can't call Inode::size() with interrupts disabled
Inode::size() may try to take a lock, so we can't be calling it with interrupts disabled. This fixes a kernel hang when trying to execute a binary in a TmpFS.
-rw-r--r--Kernel/VM/InodeVMObject.cpp7
-rw-r--r--Kernel/VM/InodeVMObject.h2
2 files changed, 5 insertions, 4 deletions
diff --git a/Kernel/VM/InodeVMObject.cpp b/Kernel/VM/InodeVMObject.cpp
index 6eee62c629..55c7eed6b5 100644
--- a/Kernel/VM/InodeVMObject.cpp
+++ b/Kernel/VM/InodeVMObject.cpp
@@ -5,10 +5,11 @@
NonnullRefPtr<InodeVMObject> InodeVMObject::create_with_inode(Inode& inode)
{
+ size_t size = inode.size();
InterruptDisabler disabler;
if (inode.vmobject())
return *inode.vmobject();
- auto vmobject = adopt(*new InodeVMObject(inode));
+ auto vmobject = adopt(*new InodeVMObject(inode, size));
vmobject->inode().set_vmobject(*vmobject);
return vmobject;
}
@@ -18,8 +19,8 @@ NonnullRefPtr<VMObject> InodeVMObject::clone()
return adopt(*new InodeVMObject(*this));
}
-InodeVMObject::InodeVMObject(Inode& inode)
- : VMObject(inode.size())
+InodeVMObject::InodeVMObject(Inode& inode, size_t size)
+ : VMObject(size)
, m_inode(inode)
, m_dirty_pages(page_count(), false)
{
diff --git a/Kernel/VM/InodeVMObject.h b/Kernel/VM/InodeVMObject.h
index 876cdf20ae..a974c16f49 100644
--- a/Kernel/VM/InodeVMObject.h
+++ b/Kernel/VM/InodeVMObject.h
@@ -22,7 +22,7 @@ public:
int release_all_clean_pages();
private:
- explicit InodeVMObject(Inode&);
+ explicit InodeVMObject(Inode&, size_t);
explicit InodeVMObject(const InodeVMObject&);
InodeVMObject& operator=(const InodeVMObject&) = delete;