summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Base/etc/fstab6
-rw-r--r--Base/usr/share/man/man2/mount.md28
-rw-r--r--Base/usr/share/man/man8/mount.md32
-rw-r--r--Kernel/Process.cpp43
-rw-r--r--Kernel/Syscall.h2
-rw-r--r--Libraries/LibC/unistd.cpp7
-rw-r--r--Libraries/LibC/unistd.h2
-rw-r--r--Userland/mount.cpp38
8 files changed, 54 insertions, 104 deletions
diff --git a/Base/etc/fstab b/Base/etc/fstab
index a80aefc78a..08b414ddec 100644
--- a/Base/etc/fstab
+++ b/Base/etc/fstab
@@ -5,6 +5,6 @@
/dev /dev bind bind,nosuid
/bin /bin bind bind,nodev
-none /proc proc nosuid
-none /dev/pts devpts noexec,nosuid
-none /tmp tmp nodev,nosuid
+proc /proc proc nosuid
+devpts /dev/pts devpts noexec,nosuid
+tmp /tmp tmp nodev,nosuid
diff --git a/Base/usr/share/man/man2/mount.md b/Base/usr/share/man/man2/mount.md
index 5f69543802..1d54e6be2c 100644
--- a/Base/usr/share/man/man2/mount.md
+++ b/Base/usr/share/man/man2/mount.md
@@ -7,13 +7,12 @@ mount - mount a filesystem
```**c++
#include <unistd.h>
-int mount(int source_fd, const char* target, const char* fs_type, int flags);
+int mount(const char* source, const char* target, const char* fs_type, int flags);
```
## Description
-`mount()` mounts a filesystem stored at `source_fd` by overlaying its contents
-over `target`.
+`mount()` mounts a filesystem stored at `source` by overlaying its contents over `target`.
`fs_type` must be one of the following supported filesystems:
@@ -22,10 +21,9 @@ over `target`.
* `DevPtsFS` (or `devpts`): The pseudoterminal pseudo-filesystem (normally mounted at `/dev/pts`).
* `TmpFS` (or `tmp`): A non-persistent filesystem that stores all its data in RAM. An instance of this filesystem is normally mounted at `/tmp`.
-For Ext2FS, `source_fd` must refer to an open file descriptor to a file containing
-the filesystem image. This may be a device file or any other seekable file. All
-the other filesystems ignore the `source_fd` — you can even pass an invalid file
-descriptor such as -1.
+For Ext2FS, `source` must be a path to a block device storing the filesystem contents. All
+the other filesystems ignore the `source` argument (by convention, it should have the same
+value as `fs_type`).
The following `flags` are supported:
@@ -39,22 +37,14 @@ mounted file system.
### Bind mounts
-If `MS_BIND` is specified in `flags`, `fs_type` is ignored and a bind mount is
-performed instead. In this case, the file or directory specified by `source_fd`
-is overlayed over `target` — the target appears to be replaced by a copy of the
-source. This can be used as an alternative to symlinks or hardlinks.
+If `MS_BIND` is specified in `flags`, `fs_type` is ignored and a bind mount is performed
+instead. In this case `source` is treated as a path to a file or directory whose contents
+are overlayed over `target`. This can be used as an alternative to symlinks or hardlinks.
## Errors
-* `EFAULT`: The `fs_type` or `target` are invalid strings.
* `EPERM`: The current process does not have superuser privileges.
-* `ENODEV`: The `fs_type` is unrecognized, or the file descriptor to source is
- not found, or the source doesn't contain a valid filesystem image. Also, this
- error occurs if `fs_type` is valid, but the file descriptor from `source_fd`
- is not seekable.
-* `EBADF`: If the `source_fd` is not valid, and either `fs_type` specifies a
- file-backed filesystem (and not a pseudo filesystem), or `MS_BIND` is
- specified in flags.
+* `ENODEV`: The `fs_type` is unrecognized, or the device is not found, or the device doesn't contain a valid filesystem image.
All of the usual path resolution errors may also occur.
diff --git a/Base/usr/share/man/man8/mount.md b/Base/usr/share/man/man8/mount.md
index f63d45cf23..7f0b9c2c4b 100644
--- a/Base/usr/share/man/man8/mount.md
+++ b/Base/usr/share/man/man8/mount.md
@@ -12,26 +12,18 @@ $ mount
## Description
-If invoked without any arguments, `mount` prints a list of all currently mounted
-filesystems.
-
-If invoked as `mount -a`, `mount` mounts all the filesystems configured in
-`/etc/fstab`. This is normally done on system startup by
-[`SystemServer`(7)](../man7/SystemServer.md).
-
-Otherwise, `mount` performs a single filesystem mount. Source should be a path
-to a file containing the filesystem image. Target, and fstype have the same
-meaning as in the [`mount`(2)](../man2/mount.md) syscall (if not specified,
-fstype defaults to `ext2`).
-
-A special source value "none" is recognized, in which case
-[`mount`(8)](mount.md) will not attempt to open the source as a file, and will
-pass an invalid file descriptor to [`mount`(2)](../man2/mount.md). This is
-useful for mounting pseudo filesystems.
-
-Options correspond to the mount flags, and should be specified as a
-comma-separated list of flag names (lowercase and without the `MS_` prefix).
-Additionally, the name `defaults` is accepted and ignored.
+If invoked without any arguments, `mount` prints a list of all currently mounted filesystems.
+
+If invoked as `mount -a`, `mount` mounts all the filesystems configured in `/etc/fstab`. This
+is normally done on system startup by [`SystemServer`(7)](../man7/SystemServer.md).
+
+Otherwise, `mount` performs a single filesystem mount. Source, target, and fstype have the
+same meaning as in the [`mount`(2)](../man2/mount.md) syscall (if not specified, fstype
+defaults to `ext2`).
+
+Options correspond to the mount flags, and should be specified as a comma-separated list of
+flag names (lowercase and without the `MS_` prefix). Additionally, the name `defaults` is
+accepted and ignored.
## Files
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index 28aca99bcb..054b987e50 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -4011,18 +4011,14 @@ int Process::sys$mount(const Syscall::SC_mount_params* user_params)
if (!validate_read_and_copy_typed(&params, user_params))
return -EFAULT;
- auto source_fd = params.source_fd;
+ auto source = validate_and_copy_string_from_user(params.source);
auto target = validate_and_copy_string_from_user(params.target);
auto fs_type = validate_and_copy_string_from_user(params.fs_type);
- if (target.is_null() || fs_type.is_null())
+ if (source.is_null() || target.is_null() || fs_type.is_null())
return -EFAULT;
- auto description = file_description(source_fd);
- if (!description.is_null())
- dbg() << "mount " << fs_type << ": source fd " << source_fd << " @ " << target;
- else
- dbg() << "mount " << fs_type << " @ " << target;
+ dbg() << "mount " << fs_type << ": source " << source << " @ " << target;
auto custody_or_error = VFS::the().resolve_path(target, current_directory());
if (custody_or_error.is_error())
@@ -4034,24 +4030,28 @@ int Process::sys$mount(const Syscall::SC_mount_params* user_params)
if (params.flags & MS_BIND) {
// We're doing a bind mount.
- if (description.is_null())
- return -EBADF;
- ASSERT(description->custody());
- return VFS::the().bind_mount(*description->custody(), target_custody, params.flags);
+ 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, params.flags);
}
if (fs_type == "ext2" || fs_type == "Ext2FS") {
- if (description.is_null())
- return -EBADF;
- ASSERT(description->custody());
- if (!description->file().is_seekable()) {
- dbg() << "mount: this is not a seekable file";
+ auto source_or_error = VFS::the().open(source, O_RDWR, 0, current_directory());
+ if (source_or_error.is_error())
+ return source_or_error.error();
+
+ auto* device = source_or_error.value()->device();
+ if (!device || !device->is_block_device()) {
+ dbg() << "mount: this is not a BlockDevice";
return -ENODEV;
}
+ auto& block_device = static_cast<BlockDevice&>(*device);
- dbg() << "mount: attempting to mount " << description->absolute_path() << " on " << target;
+ dbg() << "mount: attempting to mount " << block_device.absolute_path() << " on " << target;
- fs = Ext2FS::create(*description);
+ fs = Ext2FS::create(block_device);
} else if (fs_type == "proc" || fs_type == "ProcFS") {
fs = ProcFS::create();
} else if (fs_type == "devpts" || fs_type == "DevPtsFS") {
@@ -4063,15 +4063,12 @@ int Process::sys$mount(const Syscall::SC_mount_params* user_params)
}
if (!fs->initialize()) {
- dbg() << "mount: failed to initialize " << fs_type << " filesystem, fd - " << source_fd;
+ dbg() << "mount: failed to initialize " << fs_type << " filesystem on " << source;
return -ENODEV;
}
auto result = VFS::the().mount(fs.release_nonnull(), target_custody, params.flags);
- if (!description.is_null())
- dbg() << "mount: successfully mounted " << description->absolute_path() << " on " << target;
- else
- dbg() << "mount: successfully mounted " << target;
+ dbg() << "mount: successfully mounted " << source << " on " << target;
return result;
}
diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h
index d3167bff87..cfb072c650 100644
--- a/Kernel/Syscall.h
+++ b/Kernel/Syscall.h
@@ -395,7 +395,7 @@ struct SC_rename_params {
};
struct SC_mount_params {
- int source_fd;
+ StringArgument source;
StringArgument target;
StringArgument fs_type;
int flags;
diff --git a/Libraries/LibC/unistd.cpp b/Libraries/LibC/unistd.cpp
index 10fffdd1a1..cd17c7ae83 100644
--- a/Libraries/LibC/unistd.cpp
+++ b/Libraries/LibC/unistd.cpp
@@ -582,15 +582,14 @@ int reboot()
__RETURN_WITH_ERRNO(rc, rc, -1);
}
-int mount(int source_fd, const char* target, const char* fs_type, int flags)
+int mount(const char* source, const char* target, const char* fs_type, int flags)
{
- if (!target || !fs_type) {
+ if (!source || !target || !fs_type) {
errno = EFAULT;
return -1;
}
-
Syscall::SC_mount_params params {
- source_fd,
+ { source, strlen(source) },
{ target, strlen(target) },
{ fs_type, strlen(fs_type) },
flags
diff --git a/Libraries/LibC/unistd.h b/Libraries/LibC/unistd.h
index bf8e80068c..2566abfdfd 100644
--- a/Libraries/LibC/unistd.h
+++ b/Libraries/LibC/unistd.h
@@ -129,7 +129,7 @@ int fchown(int fd, uid_t, gid_t);
int ftruncate(int fd, off_t length);
int halt();
int reboot();
-int mount(int source_fd, const char* target, const char* fs_type, int flags);
+int mount(const char* source, const char* target, const char* fs_type, int flags);
int umount(const char* mountpoint);
int pledge(const char* promises, const char* execpromises);
int unveil(const char* path, const char* permissions);
diff --git a/Userland/mount.cpp b/Userland/mount.cpp
index 195d744056..314588a197 100644
--- a/Userland/mount.cpp
+++ b/Userland/mount.cpp
@@ -27,10 +27,8 @@
#include <AK/JsonArray.h>
#include <AK/JsonObject.h>
#include <AK/JsonValue.h>
-#include <AK/Optional.h>
#include <LibCore/ArgsParser.h>
#include <LibCore/File.h>
-#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -56,27 +54,6 @@ int parse_options(const StringView& options)
return flags;
}
-bool is_source_none(const char* source)
-{
- return !strcmp("none", source);
-}
-
-int get_source_fd(const char* source)
-{
- if (is_source_none(source))
- return -1;
- int fd = open(source, O_RDWR);
- if (fd < 0)
- fd = open(source, O_RDONLY);
- if (fd < 0) {
- int saved_errno = errno;
- auto message = String::format("Failed to open: %s\n", source);
- errno = saved_errno;
- perror(message.characters());
- }
- return fd;
-}
-
bool mount_all()
{
// Mount all filesystems listed in /etc/fstab.
@@ -109,6 +86,7 @@ bool mount_all()
continue;
}
+ const char* devname = parts[0].characters();
const char* mountpoint = parts[1].characters();
const char* fstype = parts[2].characters();
int flags = parts.size() >= 4 ? parse_options(parts[3]) : 0;
@@ -118,15 +96,11 @@ bool mount_all()
continue;
}
- const char* filename = parts[0].characters();
-
- int fd = get_source_fd(filename);
-
- dbg() << "Mounting " << filename << "(" << fstype << ")"
+ dbg() << "Mounting " << devname << "(" << fstype << ")"
<< " on " << mountpoint;
- int rc = mount(fd, mountpoint, fstype, flags);
+ int rc = mount(devname, mountpoint, fstype, flags);
if (rc != 0) {
- fprintf(stderr, "Failed to mount %s (FD: %d) (%s) on %s: %s\n", filename, fd, fstype, mountpoint, strerror(errno));
+ fprintf(stderr, "Failed to mount %s (%s) on %s: %s\n", devname, fstype, mountpoint, strerror(errno));
all_ok = false;
continue;
}
@@ -205,9 +179,7 @@ int main(int argc, char** argv)
fs_type = "ext2";
int flags = options ? parse_options(options) : 0;
- int fd = get_source_fd(source);
-
- if (mount(fd, mountpoint, fs_type, flags) < 0) {
+ if (mount(source, mountpoint, fs_type, flags) < 0) {
perror("mount");
return 1;
}