Skip to content

Commit

Permalink
FileSystem: Merge symlink following logic into path resolution.
Browse files Browse the repository at this point in the history
When encountering a symlink, we abandon the custody chain we've been working
on and start over with a new one (by recursing into a new resolution call.)
Caching symlinks in the custody model would be incredibly difficult to get
right with all the extra invalidation it would require, so let's just not.
  • Loading branch information
awesomekling committed May 31, 2019
1 parent 6b585f9 commit e6a8133
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 16 deletions.
29 changes: 14 additions & 15 deletions Kernel/FileSystem/VirtualFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,18 +545,6 @@ KResult VFS::rmdir(StringView path, Custody& base)
return parent_inode.remove_child(FileSystemPath(path).basename());
}

KResultOr<Retained<Custody>> VFS::resolve_symbolic_link(Custody& base, Inode& symlink_inode)
{
auto symlink_contents = symlink_inode.read_entire();
if (!symlink_contents)
return KResult(-ENOENT);
auto linkee = StringView(symlink_contents.pointer(), symlink_contents.size());
#ifdef VFS_DEBUG
kprintf("linkee (%s)(%u) from %u:%u\n", linkee.characters(), linkee.length(), base.fsid(), base.index());
#endif
return resolve_path_to_custody(linkee, base);
}

RetainPtr<Inode> VFS::get_inode(InodeIdentifier inode_id)
{
if (!inode_id.is_valid())
Expand Down Expand Up @@ -659,6 +647,7 @@ KResultOr<Retained<Custody>> VFS::resolve_path_to_custody(StringView path, Custo
return KResult(-ENOTDIR);
if (!metadata.may_execute(current->process()))
return KResult(-EACCES);
auto current_parent = custody_chain.last();
crumb_id = crumb_inode->lookup(part);
if (!crumb_id.is_valid())
return KResult(-ENOENT);
Expand All @@ -672,7 +661,9 @@ KResultOr<Retained<Custody>> VFS::resolve_path_to_custody(StringView path, Custo
}
crumb_inode = get_inode(crumb_id);
ASSERT(crumb_inode);

custody_chain.append(Custody::create(custody_chain.last().ptr(), part, *crumb_inode));

metadata = crumb_inode->metadata();
if (metadata.is_directory()) {
if (i != parts.size() - 1) {
Expand All @@ -687,10 +678,18 @@ KResultOr<Retained<Custody>> VFS::resolve_path_to_custody(StringView path, Custo
if (options & O__NOERROR)
return custody_chain.last();
}
auto result = resolve_symbolic_link(*custody_chain.last(), *crumb_inode);
if (result.is_error())
auto symlink_contents = crumb_inode->read_entire();
if (!symlink_contents)
return KResult(-ENOENT);
crumb_id = result.value()->inode().identifier();

// FIXME: We should limit the recursion here and return -ELOOP if it goes to deep.
return resolve_path_to_custody(
StringView(symlink_contents.pointer(),
symlink_contents.size()),
*current_parent,
parent_custody,
options
);
}
}
return custody_chain.last();
Expand Down
1 change: 0 additions & 1 deletion Kernel/FileSystem/VirtualFileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ class VFS {
bool is_vfs_root(InodeIdentifier) const;

void traverse_directory_inode(Inode&, Function<bool(const FS::DirectoryEntry&)>);
KResultOr<Retained<Custody>> resolve_symbolic_link(Custody& base, Inode& symlink_inode);

Mount* find_mount_for_host(InodeIdentifier);
Mount* find_mount_for_guest(InodeIdentifier);
Expand Down

0 comments on commit e6a8133

Please sign in to comment.