mirror of
https://github.com/fergalmoran/ladybird.git
synced 2025-12-25 19:04:58 +00:00
Add a VFS::absolutePath(InodeIdentifier).
This is pretty inefficient for ext2fs. We walk the entire block group containing the inode, searching through every directory for an entry referencing this inode. It might be a good idea to cache this information somehow. I'm not sure how often we'll be searching for it. Obviously there are multiple caching layers missing in the file system.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "VirtualFileSystem.h"
|
||||
#include "FileHandle.h"
|
||||
#include "FileSystem.h"
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <AK/kmalloc.h>
|
||||
#include <AK/kstdio.h>
|
||||
#include <AK/ktime.h>
|
||||
@@ -169,7 +170,7 @@ void VirtualFileSystem::freeNode(Node* node)
|
||||
m_nodeFreeList.append(move(node));
|
||||
}
|
||||
|
||||
bool VirtualFileSystem::isDirectory(const String& path, Node* base)
|
||||
bool VirtualFileSystem::isDirectory(const String& path, InodeIdentifier base)
|
||||
{
|
||||
auto inode = resolvePath(path, base);
|
||||
if (!inode.isValid())
|
||||
@@ -356,7 +357,7 @@ bool VirtualFileSystem::touch(const String& path)
|
||||
return inode.fileSystem()->setModificationTime(inode, ktime(nullptr));
|
||||
}
|
||||
|
||||
OwnPtr<FileHandle> VirtualFileSystem::open(const String& path, Node* base)
|
||||
OwnPtr<FileHandle> VirtualFileSystem::open(const String& path, InodeIdentifier base)
|
||||
{
|
||||
Locker locker(VirtualFileSystem::lock());
|
||||
|
||||
@@ -369,7 +370,7 @@ OwnPtr<FileHandle> VirtualFileSystem::open(const String& path, Node* base)
|
||||
return make<FileHandle>(move(vnode));
|
||||
}
|
||||
|
||||
OwnPtr<FileHandle> VirtualFileSystem::create(const String& path, Node* base)
|
||||
OwnPtr<FileHandle> VirtualFileSystem::create(const String& path, InodeIdentifier base)
|
||||
{
|
||||
Locker locker(VirtualFileSystem::lock());
|
||||
|
||||
@@ -379,7 +380,7 @@ OwnPtr<FileHandle> VirtualFileSystem::create(const String& path, Node* base)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OwnPtr<FileHandle> VirtualFileSystem::mkdir(const String& path, Node* base)
|
||||
OwnPtr<FileHandle> VirtualFileSystem::mkdir(const String& path, InodeIdentifier base)
|
||||
{
|
||||
Locker locker(VirtualFileSystem::lock());
|
||||
|
||||
@@ -399,7 +400,41 @@ InodeIdentifier VirtualFileSystem::resolveSymbolicLink(const String& basePath, I
|
||||
return resolvePath(buf);
|
||||
}
|
||||
|
||||
InodeIdentifier VirtualFileSystem::resolvePath(const String& path, Node* base)
|
||||
String VirtualFileSystem::absolutePath(InodeIdentifier inode)
|
||||
{
|
||||
Locker locker(VirtualFileSystem::lock());
|
||||
|
||||
if (!inode.isValid())
|
||||
return String();
|
||||
|
||||
Vector<InodeIdentifier> lineage;
|
||||
while (inode != m_rootNode->inode) {
|
||||
if (auto* mount = findMountForGuest(inode))
|
||||
lineage.append(mount->host());
|
||||
else
|
||||
lineage.append(inode);
|
||||
if (inode.metadata().isDirectory()) {
|
||||
inode = resolvePath("..", inode);
|
||||
} else
|
||||
inode = inode.fileSystem()->findParentOfInode(inode);
|
||||
ASSERT(inode.isValid());
|
||||
}
|
||||
if (lineage.isEmpty())
|
||||
return "/";
|
||||
lineage.append(m_rootNode->inode);
|
||||
StringBuilder builder;
|
||||
for (size_t i = lineage.size() - 1; i >= 1; --i) {
|
||||
auto& child = lineage[i - 1];
|
||||
auto parent = lineage[i];
|
||||
if (auto* mount = findMountForHost(parent))
|
||||
parent = mount->guest();
|
||||
builder.append('/');
|
||||
builder.append(parent.fileSystem()->nameOfChildInDirectory(parent, child));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
InodeIdentifier VirtualFileSystem::resolvePath(const String& path, InodeIdentifier base)
|
||||
{
|
||||
if (path.isEmpty())
|
||||
return { };
|
||||
@@ -410,7 +445,7 @@ InodeIdentifier VirtualFileSystem::resolvePath(const String& path, Node* base)
|
||||
if (path[0] == '/')
|
||||
inode = m_rootNode->inode;
|
||||
else
|
||||
inode = base ? base->inode : m_rootNode->inode;
|
||||
inode = base.isValid() ? base : m_rootNode->inode;
|
||||
|
||||
for (unsigned i = 0; i < parts.size(); ++i) {
|
||||
bool wasRootInodeAtHeadOfLoop = inode.isRootInode();
|
||||
|
||||
Reference in New Issue
Block a user