diff --git a/Kernel/FileSystem/Custody.cpp b/Kernel/FileSystem/Custody.cpp index 6dbdbbec5a..4c301af71c 100644 --- a/Kernel/FileSystem/Custody.cpp +++ b/Kernel/FileSystem/Custody.cpp @@ -26,7 +26,7 @@ Custody* Custody::get_if_cached(Custody* parent, const StringView& name) return nullptr; } -NonnullRefPtr Custody::get_or_create(Custody* parent, const StringView& name, Inode& inode) +NonnullRefPtr Custody::get_or_create(Custody* parent, const StringView& name, Inode& inode, int mount_flags) { if (RefPtr cached_custody = get_if_cached(parent, name)) { if (&cached_custody->inode() != &inode) { @@ -35,13 +35,14 @@ NonnullRefPtr Custody::get_or_create(Custody* parent, const StringView& ASSERT(&cached_custody->inode() == &inode); 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_name(name) , m_inode(inode) + , m_mount_flags(mount_flags) { LOCKER(all_custodies().lock()); all_custodies().resource().append(this); diff --git a/Kernel/FileSystem/Custody.h b/Kernel/FileSystem/Custody.h index 8df1c746a7..3b5b31e098 100644 --- a/Kernel/FileSystem/Custody.h +++ b/Kernel/FileSystem/Custody.h @@ -1,10 +1,10 @@ #pragma once -#include #include #include #include #include +#include class Inode; class VFS; @@ -15,10 +15,10 @@ class Custody : public RefCounted , public InlineLinkedListNode { public: static Custody* get_if_cached(Custody* parent, const StringView& name); - static NonnullRefPtr get_or_create(Custody* parent, const StringView& name, Inode&); - static NonnullRefPtr create(Custody* parent, const StringView& name, Inode& inode) + static NonnullRefPtr get_or_create(Custody* parent, const StringView& name, Inode&, int mount_flags); + static NonnullRefPtr 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(); @@ -33,6 +33,8 @@ public: bool is_deleted() const { return m_deleted; } bool is_mounted_on() const { return m_mounted_on; } + int mount_flags() const { return m_mount_flags; } + void did_delete(Badge); void did_mount_on(Badge); void did_rename(Badge, const String& name); @@ -42,11 +44,12 @@ public: Custody* m_prev { nullptr }; private: - Custody(Custody* parent, const StringView& name, Inode&); + Custody(Custody* parent, const StringView& name, Inode&, int mount_flags); RefPtr m_parent; String m_name; NonnullRefPtr m_inode; bool m_deleted { false }; bool m_mounted_on { false }; + int m_mount_flags { 0 }; }; diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index 4a5c2c7130..48ad237893 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -78,10 +78,10 @@ enum ProcFileType { FI_PID_stack, FI_PID_regs, FI_PID_fds, - FI_PID_exe, // symlink - FI_PID_cwd, // symlink + FI_PID_exe, // symlink + FI_PID_cwd, // symlink FI_PID_root, // symlink - FI_PID_fd, // directory + FI_PID_fd, // directory __FI_PID_End, FI_MaxStaticFileIndex, @@ -651,6 +651,7 @@ Optional procfs$df(InodeIdentifier) fs_object.add("mount_point", mount.absolute_path()); fs_object.add("block_size", fs.block_size()); fs_object.add("readonly", fs.is_readonly()); + fs_object.add("mount_flags", mount.flags()); if (fs.is_disk_backed()) fs_object.add("device", static_cast(fs).device().absolute_path()); diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp index a1ab0af591..293959f8fb 100644 --- a/Kernel/FileSystem/VirtualFileSystem.cpp +++ b/Kernel/FileSystem/VirtualFileSystem.cpp @@ -38,12 +38,12 @@ InodeIdentifier VFS::root_inode_id() const 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(); - 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 - Mount mount { file_system, &mount_point }; + Mount mount { file_system, &mount_point, flags }; m_mounts.append(move(mount)); mount_point.did_mount_on({}); return KSuccess; @@ -79,7 +79,7 @@ bool VFS::mount_root(FS& file_system) 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 = mount.guest().fs()->get_inode(root_inode_id); @@ -283,7 +283,7 @@ KResultOr> VFS::create(StringView path, int optio if (!new_file) 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); } @@ -603,10 +603,11 @@ RefPtr VFS::get_inode(InodeIdentifier 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_fs(guest_fs) , m_host_custody(host_custody) + , m_flags(flags) { } @@ -639,7 +640,7 @@ void VFS::sync() Custody& VFS::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; } @@ -674,6 +675,8 @@ KResultOr> VFS::resolve_path(StringView path, Custody& ba if (parent_custody) *parent_custody = custody_chain.last(); + int mount_flags = custody_chain.last().mount_flags(); + for (int i = 0; i < parts.size(); ++i) { bool inode_was_root_at_head_of_loop = current_root.inode().identifier() == crumb_id; auto crumb_inode = get_inode(crumb_id); @@ -704,8 +707,10 @@ KResultOr> VFS::resolve_path(StringView path, Custody& ba } 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(); + mount_flags = mount->flags(); + } 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 dir_inode = get_inode(mount->host()); @@ -715,7 +720,7 @@ KResultOr> VFS::resolve_path(StringView path, Custody& ba crumb_inode = get_inode(crumb_id); 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(); if (metadata.is_directory()) { diff --git a/Kernel/FileSystem/VirtualFileSystem.h b/Kernel/FileSystem/VirtualFileSystem.h index 38b5b54b4b..05997e362a 100644 --- a/Kernel/FileSystem/VirtualFileSystem.h +++ b/Kernel/FileSystem/VirtualFileSystem.h @@ -1,12 +1,12 @@ #pragma once -#include #include #include #include #include #include #include +#include #include #include #include @@ -41,7 +41,7 @@ class VFS { public: class Mount { public: - Mount(FS&, Custody* host_custody); + Mount(FS&, Custody* host_custody, int flags); InodeIdentifier host() const; InodeIdentifier guest() const { return m_guest; } @@ -50,11 +50,14 @@ public: String absolute_path() const; + int flags() const { return m_flags; } + private: InodeIdentifier m_host; InodeIdentifier m_guest; NonnullRefPtr m_guest_fs; RefPtr m_host_custody; + int m_flags; }; static VFS& the(); @@ -63,7 +66,7 @@ public: ~VFS(); bool mount_root(FS&); - KResult mount(FS&, Custody& mount_point); + KResult mount(FS&, Custody& mount_point, int flags); KResult unmount(InodeIdentifier guest_inode_id); KResultOr> open(StringView path, int options, mode_t mode, Custody& base, Optional = {}); diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index efb3c39e33..8ab6f731a2 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -3642,7 +3642,7 @@ int Process::sys$mount(const Syscall::SC_mount_params* user_params) 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; 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()); if (directory_or_error.is_error()) return directory_or_error.error(); - m_root_directory_for_procfs = directory_or_error.value(); - set_root_directory(Custody::create(nullptr, "", directory_or_error.value()->inode())); + auto directory = directory_or_error.value(); + m_root_directory_for_procfs = directory; + set_root_directory(Custody::create(nullptr, "", directory->inode(), directory->mount_flags())); return 0; } diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index bad2bc1092..70d056f993 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -332,9 +332,9 @@ struct SC_link_params { }; struct SC_chown_params { - StringArgument path; - u32 uid; - u32 gid; + StringArgument path; + u32 uid; + u32 gid; }; struct SC_mknod_params { @@ -357,6 +357,7 @@ struct SC_mount_params { StringArgument source; StringArgument target; StringArgument fs_type; + int flags; }; void initialize(); diff --git a/Libraries/LibC/unistd.cpp b/Libraries/LibC/unistd.cpp index 30e1bf13cf..f6a5fad173 100644 --- a/Libraries/LibC/unistd.cpp +++ b/Libraries/LibC/unistd.cpp @@ -610,13 +610,18 @@ int reboot() __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) { errno = EFAULT; 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); __RETURN_WITH_ERRNO(rc, rc, -1); } diff --git a/Libraries/LibC/unistd.h b/Libraries/LibC/unistd.h index feafa57f3b..bfecbbfbdf 100644 --- a/Libraries/LibC/unistd.h +++ b/Libraries/LibC/unistd.h @@ -111,7 +111,7 @@ int fchown(int fd, uid_t, gid_t); int ftruncate(int fd, off_t length); int halt(); 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); enum { diff --git a/Userland/mount.cpp b/Userland/mount.cpp index ec99287ae1..c1d422195d 100644 --- a/Userland/mount.cpp +++ b/Userland/mount.cpp @@ -45,7 +45,7 @@ bool mount_all() dbg() << "Mounting " << devname << "(" << fstype << ")" << " on " << mountpoint; - int rc = mount(devname, mountpoint, fstype); + int rc = mount(devname, mountpoint, fstype, 0); if (rc != 0) { fprintf(stderr, "Failed to mount %s (%s) on %s: %s\n", devname, fstype, mountpoint, strerror(errno)); all_ok = false; @@ -101,7 +101,7 @@ int main(int argc, char** argv) String mountpoint = args.get_single_values()[1]; 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"); return 1; }