2020-01-18 09:38:21 +01:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
2021-05-12 19:17:51 +00:00
|
|
|
* Copyright (c) 2021, sin-ack <sin-ack@protonmail.com>
|
2020-01-18 09:38:21 +01:00
|
|
|
*
|
2021-04-22 01:24:48 -07:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-01-18 09:38:21 +01:00
|
|
|
*/
|
|
|
|
|
|
2019-05-16 03:02:37 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <AK/Function.h>
|
2020-02-18 10:19:32 +01:00
|
|
|
#include <AK/HashTable.h>
|
2021-05-26 02:18:23 -07:00
|
|
|
#include <AK/IntrusiveList.h>
|
2019-06-21 18:58:45 +02:00
|
|
|
#include <AK/RefCounted.h>
|
2020-02-16 01:27:42 +01:00
|
|
|
#include <AK/String.h>
|
2019-05-16 03:02:37 +02:00
|
|
|
#include <AK/WeakPtr.h>
|
2020-07-16 15:23:03 -06:00
|
|
|
#include <Kernel/FileSystem/FIFO.h>
|
2019-05-28 11:53:16 +02:00
|
|
|
#include <Kernel/FileSystem/FileSystem.h>
|
2019-05-16 03:02:37 +02:00
|
|
|
#include <Kernel/FileSystem/InodeIdentifier.h>
|
|
|
|
|
#include <Kernel/FileSystem/InodeMetadata.h>
|
2020-02-16 01:50:16 +01:00
|
|
|
#include <Kernel/Forward.h>
|
2019-05-16 03:02:37 +02:00
|
|
|
#include <Kernel/KResult.h>
|
|
|
|
|
#include <Kernel/Lock.h>
|
|
|
|
|
|
2020-02-16 01:27:42 +01:00
|
|
|
namespace Kernel {
|
|
|
|
|
|
2019-08-08 11:08:27 +02:00
|
|
|
class Inode : public RefCounted<Inode>
|
2021-05-26 02:18:23 -07:00
|
|
|
, public Weakable<Inode> {
|
2019-05-16 03:02:37 +02:00
|
|
|
friend class VFS;
|
|
|
|
|
friend class FS;
|
2019-05-28 11:53:16 +02:00
|
|
|
|
2019-05-16 03:02:37 +02:00
|
|
|
public:
|
|
|
|
|
virtual ~Inode();
|
|
|
|
|
|
2020-05-26 00:35:11 -07:00
|
|
|
virtual void one_ref_left() { }
|
2019-05-16 03:02:37 +02:00
|
|
|
|
|
|
|
|
FS& fs() { return m_fs; }
|
|
|
|
|
const FS& fs() const { return m_fs; }
|
2020-05-18 21:46:02 +03:00
|
|
|
unsigned fsid() const { return m_fs.fsid(); }
|
2021-02-12 09:18:47 +01:00
|
|
|
InodeIndex index() const { return m_index; }
|
2019-05-16 03:02:37 +02:00
|
|
|
|
|
|
|
|
size_t size() const { return metadata().size; }
|
|
|
|
|
bool is_symlink() const { return metadata().is_symlink(); }
|
|
|
|
|
bool is_directory() const { return metadata().is_directory(); }
|
|
|
|
|
bool is_character_device() const { return metadata().is_character_device(); }
|
|
|
|
|
mode_t mode() const { return metadata().mode; }
|
|
|
|
|
|
|
|
|
|
InodeIdentifier identifier() const { return { fsid(), index() }; }
|
|
|
|
|
virtual InodeMetadata metadata() const = 0;
|
|
|
|
|
|
2020-12-18 14:10:10 +01:00
|
|
|
KResultOr<NonnullOwnPtr<KBuffer>> read_entire(FileDescription* = nullptr) const;
|
2019-05-16 03:02:37 +02:00
|
|
|
|
2020-09-17 13:51:09 -06:00
|
|
|
virtual KResult attach(FileDescription&) { return KSuccess; }
|
|
|
|
|
virtual void detach(FileDescription&) { }
|
|
|
|
|
virtual void did_seek(FileDescription&, off_t) { }
|
2021-05-01 14:29:39 -07:00
|
|
|
virtual KResultOr<ssize_t> read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const = 0;
|
2020-08-18 12:41:27 +02:00
|
|
|
virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const = 0;
|
2020-02-01 09:23:46 +01:00
|
|
|
virtual RefPtr<Inode> lookup(StringView name) = 0;
|
2021-05-01 14:29:39 -07:00
|
|
|
virtual KResultOr<ssize_t> write_bytes(off_t, ssize_t, const UserOrKernelBuffer& data, FileDescription*) = 0;
|
2020-06-24 23:35:56 +03:00
|
|
|
virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) = 0;
|
|
|
|
|
virtual KResult add_child(Inode&, const StringView& name, mode_t) = 0;
|
2019-06-09 10:25:19 +02:00
|
|
|
virtual KResult remove_child(const StringView& name) = 0;
|
2020-08-05 01:00:18 -07:00
|
|
|
virtual KResultOr<size_t> directory_entry_count() const = 0;
|
2019-05-16 03:02:37 +02:00
|
|
|
virtual KResult chmod(mode_t) = 0;
|
|
|
|
|
virtual KResult chown(uid_t, gid_t) = 0;
|
2020-02-08 12:07:04 +01:00
|
|
|
virtual KResult truncate(u64) { return KSuccess; }
|
2021-02-12 09:06:03 +01:00
|
|
|
virtual KResultOr<NonnullRefPtr<Custody>> resolve_as_link(Custody& base, RefPtr<Custody>* out_parent, int options, int symlink_recursion_level) const;
|
2019-05-16 03:02:37 +02:00
|
|
|
|
2021-03-15 09:04:04 +01:00
|
|
|
virtual KResultOr<int> get_block_address(int) { return ENOTSUP; }
|
2021-01-30 13:12:49 -07:00
|
|
|
|
2019-05-16 03:02:37 +02:00
|
|
|
LocalSocket* socket() { return m_socket.ptr(); }
|
|
|
|
|
const LocalSocket* socket() const { return m_socket.ptr(); }
|
|
|
|
|
bool bind_socket(LocalSocket&);
|
|
|
|
|
bool unbind_socket();
|
|
|
|
|
|
2020-01-15 14:03:14 +03:00
|
|
|
virtual FileDescription* preopen_fd() { return nullptr; };
|
|
|
|
|
|
2019-05-16 03:02:37 +02:00
|
|
|
bool is_metadata_dirty() const { return m_metadata_dirty; }
|
|
|
|
|
|
2021-04-30 15:51:06 +02:00
|
|
|
virtual KResult set_atime(time_t);
|
|
|
|
|
virtual KResult set_ctime(time_t);
|
|
|
|
|
virtual KResult set_mtime(time_t);
|
2020-02-08 02:26:33 +01:00
|
|
|
virtual KResult increment_link_count();
|
|
|
|
|
virtual KResult decrement_link_count();
|
2019-05-16 03:02:37 +02:00
|
|
|
|
|
|
|
|
virtual void flush_metadata() = 0;
|
|
|
|
|
|
|
|
|
|
void will_be_destroyed();
|
|
|
|
|
|
2020-02-28 20:07:51 +01:00
|
|
|
void set_shared_vmobject(SharedInodeVMObject&);
|
AK: Make RefPtr, NonnullRefPtr, WeakPtr thread safe
This makes most operations thread safe, especially so that they
can safely be used in the Kernel. This includes obtaining a strong
reference from a weak reference, which now requires an explicit
call to WeakPtr::strong_ref(). Another major change is that
Weakable::make_weak_ref() may require the explicit target type.
Previously we used reinterpret_cast in WeakPtr, assuming that it
can be properly converted. But WeakPtr does not necessarily have
the knowledge to be able to do this. Instead, we now ask the class
itself to deliver a WeakPtr to the type that we want.
Also, WeakLink is no longer specific to a target type. The reason
for this is that we want to be able to safely convert e.g. WeakPtr<T>
to WeakPtr<U>, and before this we just reinterpret_cast the internal
WeakLink<T> to WeakLink<U>, which is a bold assumption that it would
actually produce the correct code. Instead, WeakLink now operates
on just a raw pointer and we only make those constructors/operators
available if we can verify that it can be safely cast.
In order to guarantee thread safety, we now use the least significant
bit in the pointer for locking purposes. This also means that only
properly aligned pointers can be used.
2020-09-29 16:26:13 -06:00
|
|
|
RefPtr<SharedInodeVMObject> shared_vmobject() const;
|
|
|
|
|
bool is_shared_vmobject(const SharedInodeVMObject&) const;
|
2019-05-16 03:02:37 +02:00
|
|
|
|
|
|
|
|
static void sync();
|
|
|
|
|
|
2019-11-04 16:31:46 +01:00
|
|
|
bool has_watchers() const { return !m_watchers.is_empty(); }
|
|
|
|
|
|
2019-07-22 20:01:11 +02:00
|
|
|
void register_watcher(Badge<InodeWatcher>, InodeWatcher&);
|
|
|
|
|
void unregister_watcher(Badge<InodeWatcher>, InodeWatcher&);
|
|
|
|
|
|
2020-12-31 02:10:31 +01:00
|
|
|
NonnullRefPtr<FIFO> fifo();
|
2020-07-16 15:23:03 -06:00
|
|
|
|
2019-05-16 03:02:37 +02:00
|
|
|
protected:
|
2021-02-12 09:18:47 +01:00
|
|
|
Inode(FS& fs, InodeIndex);
|
2019-07-22 20:01:11 +02:00
|
|
|
void set_metadata_dirty(bool);
|
2020-04-04 19:46:55 +02:00
|
|
|
KResult prepare_to_write_data();
|
2019-05-16 03:02:37 +02:00
|
|
|
|
2021-05-12 19:17:51 +00:00
|
|
|
void did_add_child(InodeIdentifier const& child_id, String const& name);
|
|
|
|
|
void did_remove_child(InodeIdentifier const& child_id, String const& name);
|
|
|
|
|
void did_modify_contents();
|
|
|
|
|
void did_delete_self();
|
2020-07-04 13:36:55 +02:00
|
|
|
|
2019-05-16 03:02:37 +02:00
|
|
|
mutable Lock m_lock { "Inode" };
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
FS& m_fs;
|
2021-02-12 09:18:47 +01:00
|
|
|
InodeIndex m_index { 0 };
|
2020-02-28 20:07:51 +01:00
|
|
|
WeakPtr<SharedInodeVMObject> m_shared_vmobject;
|
2019-06-21 18:37:47 +02:00
|
|
|
RefPtr<LocalSocket> m_socket;
|
2019-07-22 20:01:11 +02:00
|
|
|
HashTable<InodeWatcher*> m_watchers;
|
2019-05-16 03:02:37 +02:00
|
|
|
bool m_metadata_dirty { false };
|
2020-07-16 15:23:03 -06:00
|
|
|
RefPtr<FIFO> m_fifo;
|
2021-05-26 02:18:23 -07:00
|
|
|
IntrusiveListNode<Inode> m_inode_list_node;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
using List = IntrusiveList<Inode, RawPtr<Inode>, &Inode::m_inode_list_node>;
|
2019-05-16 03:02:37 +02:00
|
|
|
};
|
2020-02-16 01:27:42 +01:00
|
|
|
|
|
|
|
|
}
|