mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-11 10:18:15 +09:00
Kernel: Implement bind mounts
You can now bind-mount files and directories. This essentially exposes an existing part of the file system in another place, and can be used as an alternative to symlinks or hardlinks. Here's an example of doing this: # mkdir /tmp/foo # mount /home/anon/myfile.txt /tmp/foo -o bind # cat /tmp/foo This is anon's file.
This commit is contained in:
parent
71f1d3f819
commit
0cb0f54783
Notes:
sideshowbarker
2024-07-19 10:11:16 +09:00
Author: https://github.com/bugaevc
Commit: 0cb0f54783
Pull-request: https://github.com/SerenityOS/serenity/pull/1053
3 changed files with 29 additions and 0 deletions
|
@ -49,6 +49,16 @@ KResult VFS::mount(FS& file_system, Custody& mount_point, int flags)
|
||||||
return KSuccess;
|
return KSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KResult VFS::bind_mount(Custody& source, Custody& mount_point)
|
||||||
|
{
|
||||||
|
dbg() << "VFS: Bind-mounting " << source.absolute_path() << " at " << mount_point.absolute_path();
|
||||||
|
// FIXME: check that this is not already a mount point
|
||||||
|
Mount mount { source.inode(), mount_point };
|
||||||
|
m_mounts.append(move(mount));
|
||||||
|
mount_point.did_mount_on({});
|
||||||
|
return KSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
KResult VFS::unmount(InodeIdentifier guest_inode_id)
|
KResult VFS::unmount(InodeIdentifier guest_inode_id)
|
||||||
{
|
{
|
||||||
LOCKER(m_lock);
|
LOCKER(m_lock);
|
||||||
|
@ -617,6 +627,14 @@ VFS::Mount::Mount(FS& guest_fs, Custody* host_custody, int flags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VFS::Mount::Mount(Inode& source, Custody& host_custody)
|
||||||
|
: m_guest(source.identifier())
|
||||||
|
, m_guest_fs(source.fs())
|
||||||
|
, m_host_custody(host_custody)
|
||||||
|
, m_flags(MS_BIND)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
String VFS::Mount::absolute_path() const
|
String VFS::Mount::absolute_path() const
|
||||||
{
|
{
|
||||||
if (!m_host_custody)
|
if (!m_host_custody)
|
||||||
|
|
|
@ -48,6 +48,7 @@ public:
|
||||||
class Mount {
|
class Mount {
|
||||||
public:
|
public:
|
||||||
Mount(FS&, Custody* host_custody, int flags);
|
Mount(FS&, Custody* host_custody, int flags);
|
||||||
|
Mount(Inode& source, Custody& host_custody);
|
||||||
|
|
||||||
InodeIdentifier host() const;
|
InodeIdentifier host() const;
|
||||||
InodeIdentifier guest() const { return m_guest; }
|
InodeIdentifier guest() const { return m_guest; }
|
||||||
|
@ -73,6 +74,7 @@ public:
|
||||||
|
|
||||||
bool mount_root(FS&);
|
bool mount_root(FS&);
|
||||||
KResult mount(FS&, Custody& mount_point, int flags);
|
KResult mount(FS&, Custody& mount_point, int flags);
|
||||||
|
KResult bind_mount(Custody& source, Custody& mount_point);
|
||||||
KResult unmount(InodeIdentifier guest_inode_id);
|
KResult unmount(InodeIdentifier guest_inode_id);
|
||||||
|
|
||||||
KResultOr<NonnullRefPtr<FileDescription>> open(StringView path, int options, mode_t mode, Custody& base, Optional<UidAndGid> = {});
|
KResultOr<NonnullRefPtr<FileDescription>> open(StringView path, int options, mode_t mode, Custody& base, Optional<UidAndGid> = {});
|
||||||
|
|
|
@ -3602,6 +3602,15 @@ int Process::sys$mount(const Syscall::SC_mount_params* user_params)
|
||||||
|
|
||||||
RefPtr<FS> fs;
|
RefPtr<FS> fs;
|
||||||
|
|
||||||
|
if (params.flags & MS_BIND) {
|
||||||
|
// We're doing a bind mount.
|
||||||
|
auto source_or_error = VFS::the().resolve_path(source, current_directory());
|
||||||
|
if (source_or_error.is_error())
|
||||||
|
return source_or_error.error();
|
||||||
|
auto& source_custody = source_or_error.value();
|
||||||
|
return VFS::the().bind_mount(source_custody, target_custody);
|
||||||
|
}
|
||||||
|
|
||||||
if (fs_type == "ext2" || fs_type == "Ext2FS") {
|
if (fs_type == "ext2" || fs_type == "Ext2FS") {
|
||||||
auto metadata_or_error = VFS::the().lookup_metadata(source, current_directory());
|
auto metadata_or_error = VFS::the().lookup_metadata(source, current_directory());
|
||||||
if (metadata_or_error.is_error())
|
if (metadata_or_error.is_error())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue