summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorSergey Bugaev <bugaevc@serenityos.org>2020-05-28 21:12:13 +0300
committerAndreas Kling <kling@serenityos.org>2020-05-29 07:53:30 +0200
commit3847d007271a58b33658f400d092e72e7e087db6 (patch)
treee75b5c94ba39f25a6e188f2652d5287efa947abc /Kernel
parentd395b93b150ab1819f4480d966169e6ef12b636b (diff)
downloadserenity-3847d007271a58b33658f400d092e72e7e087db6.zip
Kernel+Userland: Support remounting filesystems :^)
This makes it possible to change flags of a mount after the fact, with the caveats outlined in the man page.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/FileSystem/VirtualFileSystem.cpp14
-rw-r--r--Kernel/FileSystem/VirtualFileSystem.h2
-rw-r--r--Kernel/Process.cpp5
-rw-r--r--Kernel/UnixTypes.h1
4 files changed, 22 insertions, 0 deletions
diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp
index df3000e38e..29766e3557 100644
--- a/Kernel/FileSystem/VirtualFileSystem.cpp
+++ b/Kernel/FileSystem/VirtualFileSystem.cpp
@@ -91,6 +91,20 @@ KResult VFS::bind_mount(Custody& source, Custody& mount_point, int flags)
return KSuccess;
}
+KResult VFS::remount(Custody& mount_point, int new_flags)
+{
+ LOCKER(m_lock);
+
+ dbg() << "VFS: Remounting " << mount_point.absolute_path();
+
+ Mount* mount = find_mount_for_guest(mount_point.inode().identifier());
+ if (!mount)
+ return KResult(-ENODEV);
+
+ mount->set_flags(new_flags);
+ return KSuccess;
+}
+
KResult VFS::unmount(InodeIdentifier guest_inode_id)
{
LOCKER(m_lock);
diff --git a/Kernel/FileSystem/VirtualFileSystem.h b/Kernel/FileSystem/VirtualFileSystem.h
index 4ea33b3d58..ad7cfa5d85 100644
--- a/Kernel/FileSystem/VirtualFileSystem.h
+++ b/Kernel/FileSystem/VirtualFileSystem.h
@@ -66,6 +66,7 @@ public:
String absolute_path() const;
int flags() const { return m_flags; }
+ void set_flags(int flags) { m_flags = flags; }
private:
InodeIdentifier m_host;
@@ -83,6 +84,7 @@ public:
bool mount_root(FS&);
KResult mount(FS&, Custody& mount_point, int flags);
KResult bind_mount(Custody& source, Custody& mount_point, int flags);
+ KResult remount(Custody& mount_point, int new_flags);
KResult unmount(InodeIdentifier guest_inode_id);
KResultOr<NonnullRefPtr<FileDescription>> open(StringView path, int options, mode_t mode, Custody& base, Optional<UidAndGid> = {});
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index cd11dd1767..bb9404df05 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -4103,6 +4103,11 @@ int Process::sys$mount(const Syscall::SC_mount_params* user_params)
auto& target_custody = custody_or_error.value();
+ if (params.flags & MS_REMOUNT) {
+ // We're not creating a new mount, we're updating an existing one!
+ return VFS::the().remount(target_custody, params.flags & ~MS_REMOUNT);
+ }
+
if (params.flags & MS_BIND) {
// We're doing a bind mount.
if (description.is_null())
diff --git a/Kernel/UnixTypes.h b/Kernel/UnixTypes.h
index 6f57ec83b8..f74c28e402 100644
--- a/Kernel/UnixTypes.h
+++ b/Kernel/UnixTypes.h
@@ -53,6 +53,7 @@
#define MS_NOSUID (1 << 2)
#define MS_BIND (1 << 3)
#define MS_RDONLY (1 << 4)
+#define MS_REMOUNT (1 << 5)
#define PERF_EVENT_MALLOC 1
#define PERF_EVENT_FREE 2