mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-23 17:52:26 -05:00
Kernel+LibC: Add support for mount flags
At the moment, the actual flags are ignored, but we correctly propagate them all the way from the original mount() syscall to each custody that resides on the mounted FS.
This commit is contained in:
parent
1e6ab0ed22
commit
4566c2d811
Notes:
sideshowbarker
2024-07-19 10:11:57 +09:00
Author: https://github.com/bugaevc Commit: https://github.com/SerenityOS/serenity/commit/4566c2d811c Pull-request: https://github.com/SerenityOS/serenity/pull/1053
10 changed files with 54 additions and 34 deletions
|
@ -26,7 +26,7 @@ Custody* Custody::get_if_cached(Custody* parent, const StringView& name)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<Custody> Custody::get_or_create(Custody* parent, const StringView& name, Inode& inode)
|
NonnullRefPtr<Custody> Custody::get_or_create(Custody* parent, const StringView& name, Inode& inode, int mount_flags)
|
||||||
{
|
{
|
||||||
if (RefPtr<Custody> cached_custody = get_if_cached(parent, name)) {
|
if (RefPtr<Custody> cached_custody = get_if_cached(parent, name)) {
|
||||||
if (&cached_custody->inode() != &inode) {
|
if (&cached_custody->inode() != &inode) {
|
||||||
|
@ -35,13 +35,14 @@ NonnullRefPtr<Custody> Custody::get_or_create(Custody* parent, const StringView&
|
||||||
ASSERT(&cached_custody->inode() == &inode);
|
ASSERT(&cached_custody->inode() == &inode);
|
||||||
return *cached_custody;
|
return *cached_custody;
|
||||||
}
|
}
|
||||||
return create(parent, name, inode);
|
return create(parent, name, inode, mount_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
Custody::Custody(Custody* parent, const StringView& name, Inode& inode)
|
Custody::Custody(Custody* parent, const StringView& name, Inode& inode, int mount_flags)
|
||||||
: m_parent(parent)
|
: m_parent(parent)
|
||||||
, m_name(name)
|
, m_name(name)
|
||||||
, m_inode(inode)
|
, m_inode(inode)
|
||||||
|
, m_mount_flags(mount_flags)
|
||||||
{
|
{
|
||||||
LOCKER(all_custodies().lock());
|
LOCKER(all_custodies().lock());
|
||||||
all_custodies().resource().append(this);
|
all_custodies().resource().append(this);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/String.h>
|
|
||||||
#include <AK/Badge.h>
|
#include <AK/Badge.h>
|
||||||
#include <AK/InlineLinkedList.h>
|
#include <AK/InlineLinkedList.h>
|
||||||
#include <AK/RefCounted.h>
|
#include <AK/RefCounted.h>
|
||||||
#include <AK/RefPtr.h>
|
#include <AK/RefPtr.h>
|
||||||
|
#include <AK/String.h>
|
||||||
|
|
||||||
class Inode;
|
class Inode;
|
||||||
class VFS;
|
class VFS;
|
||||||
|
@ -15,10 +15,10 @@ class Custody : public RefCounted<Custody>
|
||||||
, public InlineLinkedListNode<Custody> {
|
, public InlineLinkedListNode<Custody> {
|
||||||
public:
|
public:
|
||||||
static Custody* get_if_cached(Custody* parent, const StringView& name);
|
static Custody* get_if_cached(Custody* parent, const StringView& name);
|
||||||
static NonnullRefPtr<Custody> get_or_create(Custody* parent, const StringView& name, Inode&);
|
static NonnullRefPtr<Custody> get_or_create(Custody* parent, const StringView& name, Inode&, int mount_flags);
|
||||||
static NonnullRefPtr<Custody> create(Custody* parent, const StringView& name, Inode& inode)
|
static NonnullRefPtr<Custody> create(Custody* parent, const StringView& name, Inode& inode, int mount_flags)
|
||||||
{
|
{
|
||||||
return adopt(*new Custody(parent, name, inode));
|
return adopt(*new Custody(parent, name, inode, mount_flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
~Custody();
|
~Custody();
|
||||||
|
@ -33,6 +33,8 @@ public:
|
||||||
bool is_deleted() const { return m_deleted; }
|
bool is_deleted() const { return m_deleted; }
|
||||||
bool is_mounted_on() const { return m_mounted_on; }
|
bool is_mounted_on() const { return m_mounted_on; }
|
||||||
|
|
||||||
|
int mount_flags() const { return m_mount_flags; }
|
||||||
|
|
||||||
void did_delete(Badge<VFS>);
|
void did_delete(Badge<VFS>);
|
||||||
void did_mount_on(Badge<VFS>);
|
void did_mount_on(Badge<VFS>);
|
||||||
void did_rename(Badge<VFS>, const String& name);
|
void did_rename(Badge<VFS>, const String& name);
|
||||||
|
@ -42,11 +44,12 @@ public:
|
||||||
Custody* m_prev { nullptr };
|
Custody* m_prev { nullptr };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Custody(Custody* parent, const StringView& name, Inode&);
|
Custody(Custody* parent, const StringView& name, Inode&, int mount_flags);
|
||||||
|
|
||||||
RefPtr<Custody> m_parent;
|
RefPtr<Custody> m_parent;
|
||||||
String m_name;
|
String m_name;
|
||||||
NonnullRefPtr<Inode> m_inode;
|
NonnullRefPtr<Inode> m_inode;
|
||||||
bool m_deleted { false };
|
bool m_deleted { false };
|
||||||
bool m_mounted_on { false };
|
bool m_mounted_on { false };
|
||||||
|
int m_mount_flags { 0 };
|
||||||
};
|
};
|
||||||
|
|
|
@ -78,10 +78,10 @@ enum ProcFileType {
|
||||||
FI_PID_stack,
|
FI_PID_stack,
|
||||||
FI_PID_regs,
|
FI_PID_regs,
|
||||||
FI_PID_fds,
|
FI_PID_fds,
|
||||||
FI_PID_exe, // symlink
|
FI_PID_exe, // symlink
|
||||||
FI_PID_cwd, // symlink
|
FI_PID_cwd, // symlink
|
||||||
FI_PID_root, // symlink
|
FI_PID_root, // symlink
|
||||||
FI_PID_fd, // directory
|
FI_PID_fd, // directory
|
||||||
__FI_PID_End,
|
__FI_PID_End,
|
||||||
|
|
||||||
FI_MaxStaticFileIndex,
|
FI_MaxStaticFileIndex,
|
||||||
|
@ -651,6 +651,7 @@ Optional<KBuffer> procfs$df(InodeIdentifier)
|
||||||
fs_object.add("mount_point", mount.absolute_path());
|
fs_object.add("mount_point", mount.absolute_path());
|
||||||
fs_object.add("block_size", fs.block_size());
|
fs_object.add("block_size", fs.block_size());
|
||||||
fs_object.add("readonly", fs.is_readonly());
|
fs_object.add("readonly", fs.is_readonly());
|
||||||
|
fs_object.add("mount_flags", mount.flags());
|
||||||
|
|
||||||
if (fs.is_disk_backed())
|
if (fs.is_disk_backed())
|
||||||
fs_object.add("device", static_cast<const DiskBackedFS&>(fs).device().absolute_path());
|
fs_object.add("device", static_cast<const DiskBackedFS&>(fs).device().absolute_path());
|
||||||
|
|
|
@ -38,12 +38,12 @@ InodeIdentifier VFS::root_inode_id() const
|
||||||
return m_root_inode->identifier();
|
return m_root_inode->identifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
KResult VFS::mount(FS& file_system, Custody& mount_point)
|
KResult VFS::mount(FS& file_system, Custody& mount_point, int flags)
|
||||||
{
|
{
|
||||||
auto& inode = mount_point.inode();
|
auto& inode = mount_point.inode();
|
||||||
dbg() << "VFS: Mounting " << file_system.class_name() << " at " << mount_point.absolute_path() << " (inode: " << inode.identifier() << ")";
|
dbg() << "VFS: Mounting " << file_system.class_name() << " at " << mount_point.absolute_path() << " (inode: " << inode.identifier() << ") with flags " << flags;
|
||||||
// FIXME: check that this is not already a mount point
|
// FIXME: check that this is not already a mount point
|
||||||
Mount mount { file_system, &mount_point };
|
Mount mount { file_system, &mount_point, flags };
|
||||||
m_mounts.append(move(mount));
|
m_mounts.append(move(mount));
|
||||||
mount_point.did_mount_on({});
|
mount_point.did_mount_on({});
|
||||||
return KSuccess;
|
return KSuccess;
|
||||||
|
@ -79,7 +79,7 @@ bool VFS::mount_root(FS& file_system)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mount mount { file_system, nullptr };
|
Mount mount { file_system, nullptr, 0 };
|
||||||
|
|
||||||
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);
|
||||||
|
@ -283,7 +283,7 @@ KResultOr<NonnullRefPtr<FileDescription>> VFS::create(StringView path, int optio
|
||||||
if (!new_file)
|
if (!new_file)
|
||||||
return KResult(error);
|
return KResult(error);
|
||||||
|
|
||||||
auto new_custody = Custody::create(&parent_custody, p.basename(), *new_file);
|
auto new_custody = Custody::create(&parent_custody, p.basename(), *new_file, parent_custody.mount_flags());
|
||||||
return FileDescription::create(*new_custody);
|
return FileDescription::create(*new_custody);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -603,10 +603,11 @@ RefPtr<Inode> VFS::get_inode(InodeIdentifier inode_id)
|
||||||
return inode_id.fs()->get_inode(inode_id);
|
return inode_id.fs()->get_inode(inode_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
VFS::Mount::Mount(FS& guest_fs, Custody* host_custody)
|
VFS::Mount::Mount(FS& guest_fs, Custody* host_custody, int flags)
|
||||||
: m_guest(guest_fs.root_inode())
|
: m_guest(guest_fs.root_inode())
|
||||||
, m_guest_fs(guest_fs)
|
, m_guest_fs(guest_fs)
|
||||||
, m_host_custody(host_custody)
|
, m_host_custody(host_custody)
|
||||||
|
, m_flags(flags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -639,7 +640,7 @@ void VFS::sync()
|
||||||
Custody& VFS::root_custody()
|
Custody& VFS::root_custody()
|
||||||
{
|
{
|
||||||
if (!m_root_custody)
|
if (!m_root_custody)
|
||||||
m_root_custody = Custody::create(nullptr, "", *m_root_inode);
|
m_root_custody = Custody::create(nullptr, "", *m_root_inode, 0);
|
||||||
return *m_root_custody;
|
return *m_root_custody;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -674,6 +675,8 @@ KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path(StringView path, Custody& ba
|
||||||
if (parent_custody)
|
if (parent_custody)
|
||||||
*parent_custody = custody_chain.last();
|
*parent_custody = custody_chain.last();
|
||||||
|
|
||||||
|
int mount_flags = custody_chain.last().mount_flags();
|
||||||
|
|
||||||
for (int i = 0; i < parts.size(); ++i) {
|
for (int i = 0; i < parts.size(); ++i) {
|
||||||
bool inode_was_root_at_head_of_loop = current_root.inode().identifier() == crumb_id;
|
bool inode_was_root_at_head_of_loop = current_root.inode().identifier() == crumb_id;
|
||||||
auto crumb_inode = get_inode(crumb_id);
|
auto crumb_inode = get_inode(crumb_id);
|
||||||
|
@ -704,8 +707,10 @@ KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path(StringView path, Custody& ba
|
||||||
}
|
}
|
||||||
return KResult(-ENOENT);
|
return KResult(-ENOENT);
|
||||||
}
|
}
|
||||||
if (auto mount = find_mount_for_host(crumb_id))
|
if (auto mount = find_mount_for_host(crumb_id)) {
|
||||||
crumb_id = mount->guest();
|
crumb_id = mount->guest();
|
||||||
|
mount_flags = mount->flags();
|
||||||
|
}
|
||||||
if (inode_was_root_at_head_of_loop && crumb_id.is_root_inode() && crumb_id != current_root.inode().identifier() && part == "..") {
|
if (inode_was_root_at_head_of_loop && crumb_id.is_root_inode() && crumb_id != current_root.inode().identifier() && part == "..") {
|
||||||
auto mount = find_mount_for_guest(crumb_id);
|
auto mount = find_mount_for_guest(crumb_id);
|
||||||
auto dir_inode = get_inode(mount->host());
|
auto dir_inode = get_inode(mount->host());
|
||||||
|
@ -715,7 +720,7 @@ KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path(StringView path, Custody& ba
|
||||||
crumb_inode = get_inode(crumb_id);
|
crumb_inode = get_inode(crumb_id);
|
||||||
ASSERT(crumb_inode);
|
ASSERT(crumb_inode);
|
||||||
|
|
||||||
custody_chain.append(Custody::create(&custody_chain.last(), part, *crumb_inode));
|
custody_chain.append(Custody::create(&custody_chain.last(), part, *crumb_inode, mount_flags));
|
||||||
|
|
||||||
metadata = crumb_inode->metadata();
|
metadata = crumb_inode->metadata();
|
||||||
if (metadata.is_directory()) {
|
if (metadata.is_directory()) {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/String.h>
|
|
||||||
#include <AK/Badge.h>
|
#include <AK/Badge.h>
|
||||||
#include <AK/Function.h>
|
#include <AK/Function.h>
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
#include <AK/NonnullOwnPtrVector.h>
|
#include <AK/NonnullOwnPtrVector.h>
|
||||||
#include <AK/OwnPtr.h>
|
#include <AK/OwnPtr.h>
|
||||||
#include <AK/RefPtr.h>
|
#include <AK/RefPtr.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <Kernel/FileSystem/FileSystem.h>
|
#include <Kernel/FileSystem/FileSystem.h>
|
||||||
#include <Kernel/FileSystem/InodeIdentifier.h>
|
#include <Kernel/FileSystem/InodeIdentifier.h>
|
||||||
#include <Kernel/FileSystem/InodeMetadata.h>
|
#include <Kernel/FileSystem/InodeMetadata.h>
|
||||||
|
@ -41,7 +41,7 @@ class VFS {
|
||||||
public:
|
public:
|
||||||
class Mount {
|
class Mount {
|
||||||
public:
|
public:
|
||||||
Mount(FS&, Custody* host_custody);
|
Mount(FS&, Custody* host_custody, int flags);
|
||||||
|
|
||||||
InodeIdentifier host() const;
|
InodeIdentifier host() const;
|
||||||
InodeIdentifier guest() const { return m_guest; }
|
InodeIdentifier guest() const { return m_guest; }
|
||||||
|
@ -50,11 +50,14 @@ public:
|
||||||
|
|
||||||
String absolute_path() const;
|
String absolute_path() const;
|
||||||
|
|
||||||
|
int flags() const { return m_flags; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
InodeIdentifier m_host;
|
InodeIdentifier m_host;
|
||||||
InodeIdentifier m_guest;
|
InodeIdentifier m_guest;
|
||||||
NonnullRefPtr<FS> m_guest_fs;
|
NonnullRefPtr<FS> m_guest_fs;
|
||||||
RefPtr<Custody> m_host_custody;
|
RefPtr<Custody> m_host_custody;
|
||||||
|
int m_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
static VFS& the();
|
static VFS& the();
|
||||||
|
@ -63,7 +66,7 @@ public:
|
||||||
~VFS();
|
~VFS();
|
||||||
|
|
||||||
bool mount_root(FS&);
|
bool mount_root(FS&);
|
||||||
KResult mount(FS&, Custody& mount_point);
|
KResult mount(FS&, Custody& mount_point, int flags);
|
||||||
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> = {});
|
||||||
|
|
|
@ -3642,7 +3642,7 @@ int Process::sys$mount(const Syscall::SC_mount_params* user_params)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = VFS::the().mount(fs.release_nonnull(), target_custody);
|
auto result = VFS::the().mount(fs.release_nonnull(), target_custody, params.flags);
|
||||||
dbg() << "mount: successfully mounted " << source << " on " << target;
|
dbg() << "mount: successfully mounted " << source << " on " << target;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -4170,8 +4170,9 @@ int Process::sys$chroot(const char* user_path, size_t path_length)
|
||||||
auto directory_or_error = VFS::the().open_directory(path.value(), current_directory());
|
auto directory_or_error = VFS::the().open_directory(path.value(), current_directory());
|
||||||
if (directory_or_error.is_error())
|
if (directory_or_error.is_error())
|
||||||
return directory_or_error.error();
|
return directory_or_error.error();
|
||||||
m_root_directory_for_procfs = directory_or_error.value();
|
auto directory = directory_or_error.value();
|
||||||
set_root_directory(Custody::create(nullptr, "", directory_or_error.value()->inode()));
|
m_root_directory_for_procfs = directory;
|
||||||
|
set_root_directory(Custody::create(nullptr, "", directory->inode(), directory->mount_flags()));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -332,9 +332,9 @@ struct SC_link_params {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SC_chown_params {
|
struct SC_chown_params {
|
||||||
StringArgument path;
|
StringArgument path;
|
||||||
u32 uid;
|
u32 uid;
|
||||||
u32 gid;
|
u32 gid;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SC_mknod_params {
|
struct SC_mknod_params {
|
||||||
|
@ -357,6 +357,7 @@ struct SC_mount_params {
|
||||||
StringArgument source;
|
StringArgument source;
|
||||||
StringArgument target;
|
StringArgument target;
|
||||||
StringArgument fs_type;
|
StringArgument fs_type;
|
||||||
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
|
@ -610,13 +610,18 @@ int reboot()
|
||||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mount(const char* source, const char* target, const char* fs_type)
|
int mount(const char* source, const char* target, const char* fs_type, int flags)
|
||||||
{
|
{
|
||||||
if (!source || !target || !fs_type) {
|
if (!source || !target || !fs_type) {
|
||||||
errno = EFAULT;
|
errno = EFAULT;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
Syscall::SC_mount_params params { { source, strlen(source) }, { target, strlen(target) }, { fs_type, strlen(fs_type) } };
|
Syscall::SC_mount_params params {
|
||||||
|
{ source, strlen(source) },
|
||||||
|
{ target, strlen(target) },
|
||||||
|
{ fs_type, strlen(fs_type) },
|
||||||
|
flags
|
||||||
|
};
|
||||||
int rc = syscall(SC_mount, ¶ms);
|
int rc = syscall(SC_mount, ¶ms);
|
||||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ int fchown(int fd, uid_t, gid_t);
|
||||||
int ftruncate(int fd, off_t length);
|
int ftruncate(int fd, off_t length);
|
||||||
int halt();
|
int halt();
|
||||||
int reboot();
|
int reboot();
|
||||||
int mount(const char* source, const char* target, const char* fs_type);
|
int mount(const char* source, const char* target, const char* fs_type, int flags);
|
||||||
int umount(const char* mountpoint);
|
int umount(const char* mountpoint);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
|
@ -45,7 +45,7 @@ bool mount_all()
|
||||||
|
|
||||||
dbg() << "Mounting " << devname << "(" << fstype << ")"
|
dbg() << "Mounting " << devname << "(" << fstype << ")"
|
||||||
<< " on " << mountpoint;
|
<< " on " << mountpoint;
|
||||||
int rc = mount(devname, mountpoint, fstype);
|
int rc = mount(devname, mountpoint, fstype, 0);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
fprintf(stderr, "Failed to mount %s (%s) on %s: %s\n", devname, fstype, mountpoint, strerror(errno));
|
fprintf(stderr, "Failed to mount %s (%s) on %s: %s\n", devname, fstype, mountpoint, strerror(errno));
|
||||||
all_ok = false;
|
all_ok = false;
|
||||||
|
@ -101,7 +101,7 @@ int main(int argc, char** argv)
|
||||||
String mountpoint = args.get_single_values()[1];
|
String mountpoint = args.get_single_values()[1];
|
||||||
String fstype = args.is_present("t") ? args.get("t") : "ext2";
|
String fstype = args.is_present("t") ? args.get("t") : "ext2";
|
||||||
|
|
||||||
if (mount(devname.characters(), mountpoint.characters(), fstype.characters()) < 0) {
|
if (mount(devname.characters(), mountpoint.characters(), fstype.characters(), 0) < 0) {
|
||||||
perror("mount");
|
perror("mount");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue