Serenity Operating System
at hosted 165 lines 5.8 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#pragma once 28 29#include <AK/Badge.h> 30#include <AK/Function.h> 31#include <AK/HashMap.h> 32#include <AK/NonnullOwnPtrVector.h> 33#include <AK/OwnPtr.h> 34#include <AK/RefPtr.h> 35#include <AK/String.h> 36#include <Kernel/FileSystem/FileSystem.h> 37#include <Kernel/FileSystem/InodeIdentifier.h> 38#include <Kernel/FileSystem/InodeMetadata.h> 39#include <Kernel/KResult.h> 40 41namespace Kernel { 42 43#define O_RDONLY (1 << 0) 44#define O_WRONLY (1 << 1) 45#define O_RDWR (O_RDONLY | O_WRONLY) 46#define O_ACCMODE (O_RDONLY | O_WRONLY) 47#define O_EXEC (1 << 2) 48#define O_CREAT (1 << 3) 49#define O_EXCL (1 << 4) 50#define O_NOCTTY (1 << 5) 51#define O_TRUNC (1 << 6) 52#define O_APPEND (1 << 7) 53#define O_NONBLOCK (1 << 8) 54#define O_DIRECTORY (1 << 9) 55#define O_NOFOLLOW (1 << 10) 56#define O_CLOEXEC (1 << 11) 57#define O_DIRECT (1 << 12) 58 59// Kernel internal options 60#define O_NOFOLLOW_NOERROR (1 << 29) 61#define O_UNLINK_INTERNAL (1 << 30) 62 63#define MS_NODEV 1 64#define MS_NOEXEC 2 65#define MS_NOSUID 4 66#define MS_BIND 8 67 68class Custody; 69class Device; 70class FileDescription; 71class UnveiledPath; 72 73struct UidAndGid { 74 uid_t uid; 75 gid_t gid; 76}; 77 78class VFS { 79 AK_MAKE_ETERNAL 80public: 81 class Mount { 82 public: 83 Mount(FS&, Custody* host_custody, int flags); 84 Mount(Inode& source, Custody& host_custody, int flags); 85 86 InodeIdentifier host() const; 87 InodeIdentifier guest() const { return m_guest; } 88 89 const FS& guest_fs() const { return *m_guest_fs; } 90 91 String absolute_path() const; 92 93 int flags() const { return m_flags; } 94 95 private: 96 InodeIdentifier m_host; 97 InodeIdentifier m_guest; 98 NonnullRefPtr<FS> m_guest_fs; 99 RefPtr<Custody> m_host_custody; 100 int m_flags; 101 }; 102 103 static VFS& the(); 104 105 VFS(); 106 ~VFS(); 107 108 bool mount_root(FS&); 109 KResult mount(FS&, Custody& mount_point, int flags); 110 KResult bind_mount(Custody& source, Custody& mount_point, int flags); 111 KResult unmount(InodeIdentifier guest_inode_id); 112 113 KResultOr<NonnullRefPtr<FileDescription>> open(StringView path, int options, mode_t mode, Custody& base, Optional<UidAndGid> = {}); 114 KResultOr<NonnullRefPtr<FileDescription>> create(StringView path, int options, mode_t mode, Custody& parent_custody, Optional<UidAndGid> = {}); 115 KResult mkdir(StringView path, mode_t mode, Custody& base); 116 KResult link(StringView old_path, StringView new_path, Custody& base); 117 KResult unlink(StringView path, Custody& base); 118 KResult symlink(StringView target, StringView linkpath, Custody& base); 119 KResult rmdir(StringView path, Custody& base); 120 KResult chmod(StringView path, mode_t, Custody& base); 121 KResult chmod(Inode&, mode_t); 122 KResult chown(StringView path, uid_t, gid_t, Custody& base); 123 KResult chown(Inode&, uid_t, gid_t); 124 KResult access(StringView path, int mode, Custody& base); 125 KResultOr<InodeMetadata> lookup_metadata(StringView path, Custody& base, int options = 0); 126 KResult utime(StringView path, Custody& base, time_t atime, time_t mtime); 127 KResult rename(StringView oldpath, StringView newpath, Custody& base); 128 KResult mknod(StringView path, mode_t, dev_t, Custody& base); 129 KResultOr<NonnullRefPtr<Custody>> open_directory(StringView path, Custody& base); 130 131 size_t mount_count() const { return m_mounts.size(); } 132 void for_each_mount(Function<void(const Mount&)>) const; 133 134 InodeIdentifier root_inode_id() const; 135 136 void sync(); 137 138 Custody& root_custody(); 139 KResultOr<NonnullRefPtr<Custody>> resolve_path(StringView path, Custody& base, RefPtr<Custody>* out_parent = nullptr, int options = 0, int symlink_recursion_level = 0); 140 KResultOr<NonnullRefPtr<Custody>> resolve_path_without_veil(StringView path, Custody& base, RefPtr<Custody>* out_parent = nullptr, int options = 0, int symlink_recursion_level = 0); 141 142private: 143 friend class FileDescription; 144 145 const UnveiledPath* find_matching_unveiled_path(StringView path); 146 KResult validate_path_against_process_veil(StringView path, int options); 147 148 RefPtr<Inode> get_inode(InodeIdentifier); 149 150 bool is_vfs_root(InodeIdentifier) const; 151 152 void traverse_directory_inode(Inode&, Function<bool(const FS::DirectoryEntry&)>); 153 154 Mount* find_mount_for_host(InodeIdentifier); 155 Mount* find_mount_for_guest(InodeIdentifier); 156 157 Lock m_lock { "VFSLock" }; 158 159 RefPtr<Inode> m_root_inode; 160 Vector<Mount> m_mounts; 161 162 RefPtr<Custody> m_root_custody; 163}; 164 165}