Serenity Operating System
at hosted 113 lines 4.3 kB view raw
1/* 2 * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@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/HashMap.h> 30#include <AK/Optional.h> 31#include <Kernel/FileSystem/FileSystem.h> 32#include <Kernel/FileSystem/Inode.h> 33#include <Kernel/KBuffer.h> 34 35namespace Kernel { 36 37class TmpFSInode; 38 39class TmpFS final : public FS { 40 friend class TmpFSInode; 41 42public: 43 virtual ~TmpFS() override; 44 static NonnullRefPtr<TmpFS> create(); 45 virtual bool initialize() override; 46 47 virtual const char* class_name() const override { return "TmpFS"; } 48 49 virtual bool supports_watchers() const override { return true; } 50 51 virtual InodeIdentifier root_inode() const override; 52 virtual RefPtr<Inode> get_inode(InodeIdentifier) const override; 53 54 virtual KResultOr<NonnullRefPtr<Inode>> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t) override; 55 virtual KResult create_directory(InodeIdentifier parent_id, const String& name, mode_t, uid_t, gid_t) override; 56 57private: 58 TmpFS(); 59 60 RefPtr<TmpFSInode> m_root_inode; 61 62 HashMap<unsigned, NonnullRefPtr<TmpFSInode>> m_inodes; 63 void register_inode(TmpFSInode&); 64 void unregister_inode(InodeIdentifier); 65 66 unsigned m_next_inode_index { 1 }; 67 unsigned next_inode_index(); 68}; 69 70class TmpFSInode final : public Inode { 71 friend class TmpFS; 72 73public: 74 virtual ~TmpFSInode() override; 75 76 TmpFS& fs() { return static_cast<TmpFS&>(Inode::fs()); } 77 const TmpFS& fs() const { return static_cast<const TmpFS&>(Inode::fs()); } 78 79 // ^Inode 80 virtual ssize_t read_bytes(off_t, ssize_t, u8* buffer, FileDescription*) const override; 81 virtual InodeMetadata metadata() const override; 82 virtual bool traverse_as_directory(Function<bool(const FS::DirectoryEntry&)>) const override; 83 virtual RefPtr<Inode> lookup(StringView name) override; 84 virtual void flush_metadata() override; 85 virtual ssize_t write_bytes(off_t, ssize_t, const u8* buffer, FileDescription*) override; 86 virtual KResult add_child(InodeIdentifier child_id, const StringView& name, mode_t) override; 87 virtual KResult remove_child(const StringView& name) override; 88 virtual size_t directory_entry_count() const override; 89 virtual KResult chmod(mode_t) override; 90 virtual KResult chown(uid_t, gid_t) override; 91 virtual KResult truncate(u64) override; 92 virtual int set_atime(time_t) override; 93 virtual int set_ctime(time_t) override; 94 virtual int set_mtime(time_t) override; 95 virtual void one_ref_left() override; 96 97private: 98 TmpFSInode(TmpFS& fs, InodeMetadata metadata, InodeIdentifier parent); 99 static NonnullRefPtr<TmpFSInode> create(TmpFS&, InodeMetadata metadata, InodeIdentifier parent); 100 static NonnullRefPtr<TmpFSInode> create_root(TmpFS&); 101 102 InodeMetadata m_metadata; 103 InodeIdentifier m_parent; 104 105 Optional<KBuffer> m_content; 106 struct Child { 107 FS::DirectoryEntry entry; 108 NonnullRefPtr<TmpFSInode> inode; 109 }; 110 HashMap<String, Child> m_children; 111}; 112 113}