mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 11:18:11 +00:00
FileSystem: Get rid of VFS::absolute_path() and teach Mount about custodies.
This commit is contained in:
parent
8e83aac8a3
commit
874bffc729
6 changed files with 40 additions and 97 deletions
|
@ -261,7 +261,7 @@ int FileDescriptor::close()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
KResultOr<String> FileDescriptor::absolute_path()
|
String FileDescriptor::absolute_path()
|
||||||
{
|
{
|
||||||
if (m_custody)
|
if (m_custody)
|
||||||
return m_custody->absolute_path();
|
return m_custody->absolute_path();
|
||||||
|
|
|
@ -43,7 +43,7 @@ public:
|
||||||
|
|
||||||
ByteBuffer read_entire_file();
|
ByteBuffer read_entire_file();
|
||||||
|
|
||||||
KResultOr<String> absolute_path();
|
String absolute_path();
|
||||||
|
|
||||||
bool is_directory() const;
|
bool is_directory() const;
|
||||||
|
|
||||||
|
|
|
@ -41,12 +41,11 @@ KResultOr<Region*> InodeFile::mmap(Process& process, LinearAddress preferred_lad
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
|
|
||||||
String InodeFile::absolute_path(FileDescriptor&) const
|
String InodeFile::absolute_path(FileDescriptor& descriptor) const
|
||||||
{
|
{
|
||||||
auto path_or_error = VFS::the().absolute_path(const_cast<Inode&>(inode()));
|
ASSERT_NOT_REACHED();
|
||||||
if (path_or_error.is_error())
|
ASSERT(descriptor.custody());
|
||||||
return { };
|
return descriptor.absolute_path();
|
||||||
return path_or_error.value();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KResult InodeFile::truncate(off_t size)
|
KResult InodeFile::truncate(off_t size)
|
||||||
|
|
|
@ -192,10 +192,7 @@ ByteBuffer procfs$pid_fds(InodeIdentifier identifier)
|
||||||
auto* descriptor = process.file_descriptor(i);
|
auto* descriptor = process.file_descriptor(i);
|
||||||
if (!descriptor)
|
if (!descriptor)
|
||||||
continue;
|
continue;
|
||||||
auto result = descriptor->absolute_path();
|
builder.appendf("% 3u %s\n", i, descriptor->absolute_path().characters());
|
||||||
if (result.is_error())
|
|
||||||
continue;
|
|
||||||
builder.appendf("% 3u %s\n", i, result.value().characters());
|
|
||||||
}
|
}
|
||||||
return builder.to_byte_buffer();
|
return builder.to_byte_buffer();
|
||||||
}
|
}
|
||||||
|
@ -210,10 +207,7 @@ ByteBuffer procfs$pid_fd_entry(InodeIdentifier identifier)
|
||||||
auto* descriptor = process.file_descriptor(fd);
|
auto* descriptor = process.file_descriptor(fd);
|
||||||
if (!descriptor)
|
if (!descriptor)
|
||||||
return { };
|
return { };
|
||||||
auto result = descriptor->absolute_path();
|
return descriptor->absolute_path().to_byte_buffer();
|
||||||
if (result.is_error())
|
|
||||||
return { };
|
|
||||||
return result.value().to_byte_buffer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuffer procfs$pid_vm(InodeIdentifier identifier)
|
ByteBuffer procfs$pid_vm(InodeIdentifier identifier)
|
||||||
|
@ -420,11 +414,7 @@ ByteBuffer procfs$mounts(InodeIdentifier)
|
||||||
else {
|
else {
|
||||||
builder.appendf("%u:%u", mount.host().fsid(), mount.host().index());
|
builder.appendf("%u:%u", mount.host().fsid(), mount.host().index());
|
||||||
builder.append(' ');
|
builder.append(' ');
|
||||||
auto result = VFS::the().absolute_path(mount.host());
|
builder.append(mount.absolute_path());
|
||||||
if (result.is_error())
|
|
||||||
builder.append("[error]");
|
|
||||||
else
|
|
||||||
builder.append(result.value());
|
|
||||||
}
|
}
|
||||||
builder.append('\n');
|
builder.append('\n');
|
||||||
});
|
});
|
||||||
|
@ -442,15 +432,7 @@ ByteBuffer procfs$df(InodeIdentifier)
|
||||||
builder.appendf("%u,", fs.free_block_count());
|
builder.appendf("%u,", fs.free_block_count());
|
||||||
builder.appendf("%u,", fs.total_inode_count());
|
builder.appendf("%u,", fs.total_inode_count());
|
||||||
builder.appendf("%u,", fs.free_inode_count());
|
builder.appendf("%u,", fs.free_inode_count());
|
||||||
if (!mount.host().is_valid())
|
builder.append(mount.absolute_path());
|
||||||
builder.append("/");
|
|
||||||
else {
|
|
||||||
auto result = VFS::the().absolute_path(mount.host());
|
|
||||||
if (result.is_error())
|
|
||||||
builder.append("[Error]");
|
|
||||||
else
|
|
||||||
builder.append(result.value());
|
|
||||||
}
|
|
||||||
builder.append('\n');
|
builder.append('\n');
|
||||||
});
|
});
|
||||||
return builder.to_byte_buffer();
|
return builder.to_byte_buffer();
|
||||||
|
@ -613,11 +595,7 @@ ByteBuffer procfs$inodes(InodeIdentifier)
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
for (auto it : all_inodes()) {
|
for (auto it : all_inodes()) {
|
||||||
RetainPtr<Inode> inode = *it;
|
RetainPtr<Inode> inode = *it;
|
||||||
auto result = VFS::the().absolute_path(*inode);
|
builder.appendf("Inode{K%x} %02u:%08u (%u)\n", inode.ptr(), inode->fsid(), inode->index(), inode->retain_count());
|
||||||
if (result.is_error())
|
|
||||||
continue;
|
|
||||||
auto path = result.value();
|
|
||||||
builder.appendf("Inode{K%x} %02u:%08u (%u) %s\n", inode.ptr(), inode->fsid(), inode->index(), inode->retain_count(), path.characters());
|
|
||||||
}
|
}
|
||||||
return builder.to_byte_buffer();
|
return builder.to_byte_buffer();
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,9 +36,8 @@ InodeIdentifier VFS::root_inode_id() const
|
||||||
return m_root_inode->identifier();
|
return m_root_inode->identifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VFS::mount(RetainPtr<FS>&& file_system, StringView path)
|
bool VFS::mount(Retained<FS>&& file_system, StringView path)
|
||||||
{
|
{
|
||||||
ASSERT(file_system);
|
|
||||||
auto result = resolve_path_to_custody(path, root_custody());
|
auto result = resolve_path_to_custody(path, root_custody());
|
||||||
if (result.is_error()) {
|
if (result.is_error()) {
|
||||||
kprintf("VFS: mount can't resolve mount point '%s'\n", path.characters());
|
kprintf("VFS: mount can't resolve mount point '%s'\n", path.characters());
|
||||||
|
@ -47,19 +46,19 @@ bool VFS::mount(RetainPtr<FS>&& file_system, StringView path)
|
||||||
auto& inode = result.value()->inode();
|
auto& inode = result.value()->inode();
|
||||||
kprintf("VFS: mounting %s{%p} at %s (inode: %u)\n", file_system->class_name(), file_system.ptr(), path.characters(), inode.index());
|
kprintf("VFS: mounting %s{%p} at %s (inode: %u)\n", file_system->class_name(), file_system.ptr(), path.characters(), inode.index());
|
||||||
// FIXME: check that this is not already a mount point
|
// FIXME: check that this is not already a mount point
|
||||||
auto mount = make<Mount>(inode.identifier(), move(file_system));
|
auto mount = make<Mount>(*result.value(), move(file_system));
|
||||||
m_mounts.append(move(mount));
|
m_mounts.append(move(mount));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VFS::mount_root(RetainPtr<FS>&& file_system)
|
bool VFS::mount_root(Retained<FS>&& file_system)
|
||||||
{
|
{
|
||||||
if (m_root_inode) {
|
if (m_root_inode) {
|
||||||
kprintf("VFS: mount_root can't mount another root\n");
|
kprintf("VFS: mount_root can't mount another root\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mount = make<Mount>(InodeIdentifier(), move(file_system));
|
auto mount = make<Mount>(nullptr, move(file_system));
|
||||||
|
|
||||||
auto root_inode_id = mount->guest().fs()->root_inode();
|
auto root_inode_id = mount->guest().fs()->root_inode();
|
||||||
auto root_inode = mount->guest().fs()->get_inode(root_inode_id);
|
auto root_inode = mount->guest().fs()->get_inode(root_inode_id);
|
||||||
|
@ -565,53 +564,6 @@ RetainPtr<Inode> VFS::get_inode(InodeIdentifier inode_id)
|
||||||
return inode_id.fs()->get_inode(inode_id);
|
return inode_id.fs()->get_inode(inode_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
KResultOr<String> VFS::absolute_path(InodeIdentifier inode_id)
|
|
||||||
{
|
|
||||||
auto inode = get_inode(inode_id);
|
|
||||||
if (!inode)
|
|
||||||
return KResult(-EIO);
|
|
||||||
return absolute_path(*inode);
|
|
||||||
}
|
|
||||||
|
|
||||||
KResultOr<String> VFS::absolute_path(Inode& core_inode)
|
|
||||||
{
|
|
||||||
Vector<InodeIdentifier> lineage;
|
|
||||||
RetainPtr<Inode> inode = &core_inode;
|
|
||||||
while (inode->identifier() != root_inode_id()) {
|
|
||||||
if (auto* mount = find_mount_for_guest(inode->identifier()))
|
|
||||||
lineage.append(mount->host());
|
|
||||||
else
|
|
||||||
lineage.append(inode->identifier());
|
|
||||||
|
|
||||||
InodeIdentifier parent_id;
|
|
||||||
if (inode->is_directory()) {
|
|
||||||
auto result = resolve_path("..", inode->identifier());
|
|
||||||
if (result.is_error())
|
|
||||||
return result.error();
|
|
||||||
parent_id = result.value();
|
|
||||||
} else {
|
|
||||||
parent_id = inode->parent()->identifier();
|
|
||||||
}
|
|
||||||
if (!parent_id.is_valid())
|
|
||||||
return KResult(-EIO);
|
|
||||||
inode = get_inode(parent_id);
|
|
||||||
}
|
|
||||||
if (lineage.is_empty())
|
|
||||||
return "/";
|
|
||||||
lineage.append(root_inode_id());
|
|
||||||
StringBuilder builder;
|
|
||||||
for (size_t i = lineage.size() - 1; i >= 1; --i) {
|
|
||||||
auto& child = lineage[i - 1];
|
|
||||||
auto parent = lineage[i];
|
|
||||||
if (auto* mount = find_mount_for_host(parent))
|
|
||||||
parent = mount->guest();
|
|
||||||
builder.append('/');
|
|
||||||
auto parent_inode = get_inode(parent);
|
|
||||||
builder.append(parent_inode->reverse_lookup(child));
|
|
||||||
}
|
|
||||||
return builder.to_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
KResultOr<InodeIdentifier> VFS::resolve_path(StringView path, InodeIdentifier base, int options, InodeIdentifier* parent_id)
|
KResultOr<InodeIdentifier> VFS::resolve_path(StringView path, InodeIdentifier base, int options, InodeIdentifier* parent_id)
|
||||||
{
|
{
|
||||||
if (path.is_empty())
|
if (path.is_empty())
|
||||||
|
@ -701,13 +653,27 @@ KResultOr<InodeIdentifier> VFS::resolve_path(StringView path, InodeIdentifier ba
|
||||||
return crumb_id;
|
return crumb_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
VFS::Mount::Mount(InodeIdentifier host, RetainPtr<FS>&& guest_fs)
|
VFS::Mount::Mount(RetainPtr<Custody>&& host_custody, Retained<FS>&& guest_fs)
|
||||||
: m_host(host)
|
: m_guest(guest_fs->root_inode())
|
||||||
, m_guest(guest_fs->root_inode())
|
|
||||||
, m_guest_fs(move(guest_fs))
|
, m_guest_fs(move(guest_fs))
|
||||||
|
, m_host_custody(move(host_custody))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String VFS::Mount::absolute_path() const
|
||||||
|
{
|
||||||
|
if (!m_host_custody)
|
||||||
|
return "/";
|
||||||
|
return m_host_custody->absolute_path();
|
||||||
|
}
|
||||||
|
|
||||||
|
InodeIdentifier VFS::Mount::host() const
|
||||||
|
{
|
||||||
|
if (!m_host_custody)
|
||||||
|
return { };
|
||||||
|
return m_host_custody->inode().identifier();
|
||||||
|
}
|
||||||
|
|
||||||
void VFS::register_device(Device& device)
|
void VFS::register_device(Device& device)
|
||||||
{
|
{
|
||||||
m_devices.set(encoded_device(device.major(), device.minor()), &device);
|
m_devices.set(encoded_device(device.major(), device.minor()), &device);
|
||||||
|
|
|
@ -41,17 +41,20 @@ class VFS {
|
||||||
public:
|
public:
|
||||||
class Mount {
|
class Mount {
|
||||||
public:
|
public:
|
||||||
Mount(InodeIdentifier host, RetainPtr<FS>&&);
|
Mount(RetainPtr<Custody>&&, Retained<FS>&&);
|
||||||
|
|
||||||
InodeIdentifier host() const { return m_host; }
|
InodeIdentifier host() const;
|
||||||
InodeIdentifier guest() const { return m_guest; }
|
InodeIdentifier guest() const { return m_guest; }
|
||||||
|
|
||||||
const FS& guest_fs() const { return *m_guest_fs; }
|
const FS& guest_fs() const { return *m_guest_fs; }
|
||||||
|
|
||||||
|
String absolute_path() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
InodeIdentifier m_host;
|
InodeIdentifier m_host;
|
||||||
InodeIdentifier m_guest;
|
InodeIdentifier m_guest;
|
||||||
RetainPtr<FS> m_guest_fs;
|
Retained<FS> m_guest_fs;
|
||||||
|
RetainPtr<Custody> m_host_custody;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[gnu::pure]] static VFS& the();
|
[[gnu::pure]] static VFS& the();
|
||||||
|
@ -59,8 +62,8 @@ public:
|
||||||
VFS();
|
VFS();
|
||||||
~VFS();
|
~VFS();
|
||||||
|
|
||||||
bool mount_root(RetainPtr<FS>&&);
|
bool mount_root(Retained<FS>&&);
|
||||||
bool mount(RetainPtr<FS>&&, StringView path);
|
bool mount(Retained<FS>&&, StringView path);
|
||||||
|
|
||||||
KResultOr<Retained<FileDescriptor>> open(RetainPtr<Device>&&, int options);
|
KResultOr<Retained<FileDescriptor>> open(RetainPtr<Device>&&, int options);
|
||||||
KResultOr<Retained<FileDescriptor>> open(StringView path, int options, mode_t mode, Custody& base);
|
KResultOr<Retained<FileDescriptor>> open(StringView path, int options, mode_t mode, Custody& base);
|
||||||
|
@ -86,9 +89,6 @@ public:
|
||||||
size_t mount_count() const { return m_mounts.size(); }
|
size_t mount_count() const { return m_mounts.size(); }
|
||||||
void for_each_mount(Function<void(const Mount&)>) const;
|
void for_each_mount(Function<void(const Mount&)>) const;
|
||||||
|
|
||||||
KResultOr<String> absolute_path(Inode&);
|
|
||||||
KResultOr<String> absolute_path(InodeIdentifier);
|
|
||||||
|
|
||||||
InodeIdentifier root_inode_id() const;
|
InodeIdentifier root_inode_id() const;
|
||||||
Inode* root_inode() { return m_root_inode.ptr(); }
|
Inode* root_inode() { return m_root_inode.ptr(); }
|
||||||
const Inode* root_inode() const { return m_root_inode.ptr(); }
|
const Inode* root_inode() const { return m_root_inode.ptr(); }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue