mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 21:57:35 +00:00
Kernel: Fix ProcFS returning Inodes that are being deleted
There is a window between dropping the last reference and removing a ProcFSInode from the lookup map. So, when looking up we need to check if that Inode is being destructed.
This commit is contained in:
parent
5cbcb35d34
commit
c943ca95c4
1 changed files with 16 additions and 6 deletions
|
@ -1101,12 +1101,20 @@ RefPtr<Inode> ProcFS::get_inode(InodeIdentifier inode_id) const
|
||||||
|
|
||||||
LOCKER(m_inodes_lock);
|
LOCKER(m_inodes_lock);
|
||||||
auto it = m_inodes.find(inode_id.index());
|
auto it = m_inodes.find(inode_id.index());
|
||||||
if (it == m_inodes.end()) {
|
if (it != m_inodes.end()) {
|
||||||
auto inode = adopt(*new ProcFSInode(const_cast<ProcFS&>(*this), inode_id.index()));
|
// It's possible that the ProcFSInode ref count was dropped to 0 or
|
||||||
m_inodes.set(inode_id.index(), inode.ptr());
|
// the ~ProcFSInode destructor is even running already, but blocked
|
||||||
return inode;
|
// from removing it from this map. So we need to *try* to ref it,
|
||||||
|
// and if that fails we cannot return this instance anymore and just
|
||||||
|
// create a new one.
|
||||||
|
if (it->value->try_ref())
|
||||||
|
return adopt(*it->value);
|
||||||
|
// We couldn't ref it, so just create a new one and replace the entry
|
||||||
}
|
}
|
||||||
return (*it).value;
|
auto inode = adopt(*new ProcFSInode(const_cast<ProcFS&>(*this), inode_id.index()));
|
||||||
|
auto result = m_inodes.set(inode_id.index(), inode.ptr());
|
||||||
|
ASSERT(result == ((it == m_inodes.end()) ? AK::HashSetResult::InsertedNewEntry : AK::HashSetResult::ReplacedExistingEntry));
|
||||||
|
return inode;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcFSInode::ProcFSInode(ProcFS& fs, unsigned index)
|
ProcFSInode::ProcFSInode(ProcFS& fs, unsigned index)
|
||||||
|
@ -1117,7 +1125,9 @@ ProcFSInode::ProcFSInode(ProcFS& fs, unsigned index)
|
||||||
ProcFSInode::~ProcFSInode()
|
ProcFSInode::~ProcFSInode()
|
||||||
{
|
{
|
||||||
LOCKER(fs().m_inodes_lock);
|
LOCKER(fs().m_inodes_lock);
|
||||||
fs().m_inodes.remove(index());
|
auto it = fs().m_inodes.find(index());
|
||||||
|
if (it != fs().m_inodes.end() && it->value == this)
|
||||||
|
fs().m_inodes.remove(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
InodeMetadata ProcFSInode::metadata() const
|
InodeMetadata ProcFSInode::metadata() const
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue