1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-28 18:35:09 +00:00

Kernel: Move Inode to its own files.

This commit is contained in:
Andreas Kling 2019-05-16 03:02:37 +02:00
parent 8aecebe8f3
commit 176f683f66
11 changed files with 240 additions and 205 deletions

View file

@ -1,9 +1,9 @@
#pragma once #pragma once
#include "DiskBackedFileSystem.h" #include <Kernel/UnixTypes.h>
#include "UnixTypes.h" #include <Kernel/FileSystem/Inode.h>
#include <AK/OwnPtr.h> #include <Kernel/FileSystem/ext2_fs.h>
#include "ext2_fs.h" #include <Kernel/FileSystem/DiskBackedFileSystem.h>
struct ext2_group_desc; struct ext2_group_desc;
struct ext2_inode; struct ext2_inode;

View file

@ -2,6 +2,7 @@
#include <Kernel/FileSystem/VirtualFileSystem.h> #include <Kernel/FileSystem/VirtualFileSystem.h>
#include <Kernel/FileSystem/InodeMetadata.h> #include <Kernel/FileSystem/InodeMetadata.h>
#include <Kernel/FileSystem/Inode.h>
#include <Kernel/FileSystem/FIFO.h> #include <Kernel/FileSystem/FIFO.h>
#include <Kernel/LinearAddress.h> #include <Kernel/LinearAddress.h>
#include <AK/ByteBuffer.h> #include <AK/ByteBuffer.h>

View file

@ -2,13 +2,13 @@
#include <AK/HashMap.h> #include <AK/HashMap.h>
#include <AK/StringBuilder.h> #include <AK/StringBuilder.h>
#include <LibC/errno_numbers.h> #include <LibC/errno_numbers.h>
#include "FileSystem.h" #include <Kernel/FileSystem/FileSystem.h>
#include <Kernel/FileSystem/Inode.h>
#include <Kernel/VM/MemoryManager.h> #include <Kernel/VM/MemoryManager.h>
#include <Kernel/Net/LocalSocket.h> #include <Kernel/Net/LocalSocket.h>
static dword s_lastFileSystemID; static dword s_lastFileSystemID;
static HashMap<dword, FS*>* s_fs_map; static HashMap<dword, FS*>* s_fs_map;
static HashTable<Inode*>* s_inode_set;
static HashMap<dword, FS*>& all_fses() static HashMap<dword, FS*>& all_fses()
{ {
@ -17,12 +17,6 @@ static HashMap<dword, FS*>& all_fses()
return *s_fs_map; return *s_fs_map;
} }
HashTable<Inode*>& all_inodes()
{
if (!s_inode_set)
s_inode_set = new HashTable<Inode*>();
return *s_inode_set;
}
FS::FS() FS::FS()
: m_fsid(++s_lastFileSystemID) : m_fsid(++s_lastFileSystemID)
@ -43,30 +37,6 @@ FS* FS::from_fsid(dword id)
return nullptr; return nullptr;
} }
ByteBuffer Inode::read_entire(FileDescriptor* descriptor) const
{
size_t initial_size = metadata().size ? metadata().size : 4096;
StringBuilder builder(initial_size);
ssize_t nread;
byte buffer[4096];
off_t offset = 0;
for (;;) {
nread = read_bytes(offset, sizeof(buffer), buffer, descriptor);
ASSERT(nread <= (ssize_t)sizeof(buffer));
if (nread <= 0)
break;
builder.append((const char*)buffer, nread);
offset += nread;
}
if (nread < 0) {
kprintf("Inode::read_entire: ERROR: %d\n", nread);
return nullptr;
}
return builder.to_byte_buffer();
}
FS::DirectoryEntry::DirectoryEntry(const char* n, InodeIdentifier i, byte ft) FS::DirectoryEntry::DirectoryEntry(const char* n, InodeIdentifier i, byte ft)
: name_length(strlen(n)) : name_length(strlen(n))
, inode(i) , inode(i)
@ -85,76 +55,9 @@ FS::DirectoryEntry::DirectoryEntry(const char* n, int nl, InodeIdentifier i, byt
name[nl] = '\0'; name[nl] = '\0';
} }
Inode::Inode(FS& fs, unsigned index)
: m_fs(fs)
, m_index(index)
{
all_inodes().set(this);
}
Inode::~Inode()
{
all_inodes().remove(this);
}
void Inode::will_be_destroyed()
{
if (m_metadata_dirty)
flush_metadata();
}
void Inode::inode_contents_changed(off_t offset, ssize_t size, const byte* data)
{
if (m_vmo)
m_vmo->inode_contents_changed(Badge<Inode>(), offset, size, data);
}
void Inode::inode_size_changed(size_t old_size, size_t new_size)
{
if (m_vmo)
m_vmo->inode_size_changed(Badge<Inode>(), old_size, new_size);
}
int Inode::set_atime(time_t)
{
return -ENOTIMPL;
}
int Inode::set_ctime(time_t)
{
return -ENOTIMPL;
}
int Inode::set_mtime(time_t)
{
return -ENOTIMPL;
}
int Inode::increment_link_count()
{
return -ENOTIMPL;
}
int Inode::decrement_link_count()
{
return -ENOTIMPL;
}
void FS::sync() void FS::sync()
{ {
Vector<Retained<Inode>, 32> inodes; Inode::sync();
{
InterruptDisabler disabler;
for (auto* inode : all_inodes()) {
if (inode->is_metadata_dirty())
inodes.append(*inode);
}
}
for (auto& inode : inodes) {
ASSERT(inode->is_metadata_dirty());
inode->flush_metadata();
}
Vector<Retained<FS>, 32> fses; Vector<Retained<FS>, 32> fses;
{ {
@ -166,22 +69,3 @@ void FS::sync()
for (auto fs : fses) for (auto fs : fses)
fs->flush_writes(); fs->flush_writes();
} }
void Inode::set_vmo(VMObject& vmo)
{
m_vmo = vmo.make_weak_ptr();
}
bool Inode::bind_socket(LocalSocket& socket)
{
ASSERT(!m_socket);
m_socket = socket;
return true;
}
bool Inode::unbind_socket()
{
ASSERT(m_socket);
m_socket = nullptr;
return true;
}

View file

@ -69,80 +69,6 @@ private:
bool m_readonly { false }; bool m_readonly { false };
}; };
class Inode : public Retainable<Inode> {
friend class VFS;
friend class FS;
public:
virtual ~Inode();
virtual void one_retain_left() { }
FS& fs() { return m_fs; }
const FS& fs() const { return m_fs; }
unsigned fsid() const;
unsigned index() const { return m_index; }
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;
ByteBuffer read_entire(FileDescriptor* = nullptr) const;
virtual ssize_t read_bytes(off_t, ssize_t, byte* buffer, FileDescriptor*) const = 0;
virtual bool traverse_as_directory(Function<bool(const FS::DirectoryEntry&)>) const = 0;
virtual InodeIdentifier lookup(const String& name) = 0;
virtual String reverse_lookup(InodeIdentifier) = 0;
virtual ssize_t write_bytes(off_t, ssize_t, const byte* data, FileDescriptor*) = 0;
virtual KResult add_child(InodeIdentifier child_id, const String& name, byte file_type) = 0;
virtual KResult remove_child(const String& name) = 0;
virtual RetainPtr<Inode> parent() const = 0;
virtual size_t directory_entry_count() const = 0;
virtual KResult chmod(mode_t) = 0;
virtual KResult chown(uid_t, gid_t) = 0;
virtual KResult truncate(off_t) { return KSuccess; }
LocalSocket* socket() { return m_socket.ptr(); }
const LocalSocket* socket() const { return m_socket.ptr(); }
bool bind_socket(LocalSocket&);
bool unbind_socket();
bool is_metadata_dirty() const { return m_metadata_dirty; }
virtual int set_atime(time_t);
virtual int set_ctime(time_t);
virtual int set_mtime(time_t);
virtual int increment_link_count();
virtual int decrement_link_count();
virtual void flush_metadata() = 0;
void will_be_destroyed();
void set_vmo(VMObject&);
VMObject* vmo() { return m_vmo.ptr(); }
const VMObject* vmo() const { return m_vmo.ptr(); }
protected:
Inode(FS& fs, unsigned index);
void set_metadata_dirty(bool b) { m_metadata_dirty = b; }
void inode_contents_changed(off_t, ssize_t, const byte*);
void inode_size_changed(size_t old_size, size_t new_size);
mutable Lock m_lock { "Inode" };
private:
FS& m_fs;
unsigned m_index { 0 };
WeakPtr<VMObject> m_vmo;
RetainPtr<LocalSocket> m_socket;
bool m_metadata_dirty { false };
};
inline FS* InodeIdentifier::fs() inline FS* InodeIdentifier::fs()
{ {
return FS::from_fsid(m_fsid); return FS::from_fsid(m_fsid);
@ -158,11 +84,6 @@ inline bool InodeIdentifier::is_root_inode() const
return (*this) == fs()->root_inode(); return (*this) == fs()->root_inode();
} }
inline unsigned Inode::fsid() const
{
return m_fs.fsid();
}
namespace AK { namespace AK {
template<> template<>

132
Kernel/FileSystem/Inode.cpp Normal file
View file

@ -0,0 +1,132 @@
#include <Kernel/FileSystem/Inode.h>
#include <AK/StringBuilder.h>
#include <Kernel/VM/VMObject.h>
#include <Kernel/Net/LocalSocket.h>
HashTable<Inode*>& all_inodes()
{
static HashTable<Inode*>* s_inode_set;
if (!s_inode_set)
s_inode_set = new HashTable<Inode*>();
return *s_inode_set;
}
void Inode::sync()
{
Vector<Retained<Inode>, 32> inodes;
{
InterruptDisabler disabler;
for (auto* inode : all_inodes()) {
if (inode->is_metadata_dirty())
inodes.append(*inode);
}
}
for (auto& inode : inodes) {
ASSERT(inode->is_metadata_dirty());
inode->flush_metadata();
}
}
ByteBuffer Inode::read_entire(FileDescriptor* descriptor) const
{
size_t initial_size = metadata().size ? metadata().size : 4096;
StringBuilder builder(initial_size);
ssize_t nread;
byte buffer[4096];
off_t offset = 0;
for (;;) {
nread = read_bytes(offset, sizeof(buffer), buffer, descriptor);
ASSERT(nread <= (ssize_t)sizeof(buffer));
if (nread <= 0)
break;
builder.append((const char*)buffer, nread);
offset += nread;
}
if (nread < 0) {
kprintf("Inode::read_entire: ERROR: %d\n", nread);
return nullptr;
}
return builder.to_byte_buffer();
}
unsigned Inode::fsid() const
{
return m_fs.fsid();
}
Inode::Inode(FS& fs, unsigned index)
: m_fs(fs)
, m_index(index)
{
all_inodes().set(this);
}
Inode::~Inode()
{
all_inodes().remove(this);
}
void Inode::will_be_destroyed()
{
if (m_metadata_dirty)
flush_metadata();
}
void Inode::inode_contents_changed(off_t offset, ssize_t size, const byte* data)
{
if (m_vmo)
m_vmo->inode_contents_changed(Badge<Inode>(), offset, size, data);
}
void Inode::inode_size_changed(size_t old_size, size_t new_size)
{
if (m_vmo)
m_vmo->inode_size_changed(Badge<Inode>(), old_size, new_size);
}
int Inode::set_atime(time_t)
{
return -ENOTIMPL;
}
int Inode::set_ctime(time_t)
{
return -ENOTIMPL;
}
int Inode::set_mtime(time_t)
{
return -ENOTIMPL;
}
int Inode::increment_link_count()
{
return -ENOTIMPL;
}
int Inode::decrement_link_count()
{
return -ENOTIMPL;
}
void Inode::set_vmo(VMObject& vmo)
{
m_vmo = vmo.make_weak_ptr();
}
bool Inode::bind_socket(LocalSocket& socket)
{
ASSERT(!m_socket);
m_socket = socket;
return true;
}
bool Inode::unbind_socket()
{
ASSERT(m_socket);
m_socket = nullptr;
return true;
}

92
Kernel/FileSystem/Inode.h Normal file
View file

@ -0,0 +1,92 @@
#pragma once
#include <AK/Retainable.h>
#include <AK/AKString.h>
#include <AK/Function.h>
#include <AK/WeakPtr.h>
#include <Kernel/FileSystem/InodeIdentifier.h>
#include <Kernel/FileSystem/InodeMetadata.h>
#include <Kernel/FileSystem/FileSystem.h>
#include <Kernel/KResult.h>
#include <Kernel/Lock.h>
class FileDescriptor;
class LocalSocket;
class VMObject;
class Inode : public Retainable<Inode> {
friend class VFS;
friend class FS;
public:
virtual ~Inode();
virtual void one_retain_left() { }
FS& fs() { return m_fs; }
const FS& fs() const { return m_fs; }
unsigned fsid() const;
unsigned index() const { return m_index; }
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;
ByteBuffer read_entire(FileDescriptor* = nullptr) const;
virtual ssize_t read_bytes(off_t, ssize_t, byte* buffer, FileDescriptor*) const = 0;
virtual bool traverse_as_directory(Function<bool(const FS::DirectoryEntry&)>) const = 0;
virtual InodeIdentifier lookup(const String& name) = 0;
virtual String reverse_lookup(InodeIdentifier) = 0;
virtual ssize_t write_bytes(off_t, ssize_t, const byte* data, FileDescriptor*) = 0;
virtual KResult add_child(InodeIdentifier child_id, const String& name, byte file_type) = 0;
virtual KResult remove_child(const String& name) = 0;
virtual RetainPtr<Inode> parent() const = 0;
virtual size_t directory_entry_count() const = 0;
virtual KResult chmod(mode_t) = 0;
virtual KResult chown(uid_t, gid_t) = 0;
virtual KResult truncate(off_t) { return KSuccess; }
LocalSocket* socket() { return m_socket.ptr(); }
const LocalSocket* socket() const { return m_socket.ptr(); }
bool bind_socket(LocalSocket&);
bool unbind_socket();
bool is_metadata_dirty() const { return m_metadata_dirty; }
virtual int set_atime(time_t);
virtual int set_ctime(time_t);
virtual int set_mtime(time_t);
virtual int increment_link_count();
virtual int decrement_link_count();
virtual void flush_metadata() = 0;
void will_be_destroyed();
void set_vmo(VMObject&);
VMObject* vmo() { return m_vmo.ptr(); }
const VMObject* vmo() const { return m_vmo.ptr(); }
static void sync();
protected:
Inode(FS& fs, unsigned index);
void set_metadata_dirty(bool b) { m_metadata_dirty = b; }
void inode_contents_changed(off_t, ssize_t, const byte*);
void inode_size_changed(size_t old_size, size_t new_size);
mutable Lock m_lock { "Inode" };
private:
FS& m_fs;
unsigned m_index { 0 };
WeakPtr<VMObject> m_vmo;
RetainPtr<LocalSocket> m_socket;
bool m_metadata_dirty { false };
};

View file

@ -3,6 +3,7 @@
#include <Kernel/Lock.h> #include <Kernel/Lock.h>
#include <AK/Types.h> #include <AK/Types.h>
#include <Kernel/FileSystem/FileSystem.h> #include <Kernel/FileSystem/FileSystem.h>
#include <Kernel/FileSystem/Inode.h>
class Process; class Process;

View file

@ -1,7 +1,8 @@
#pragma once #pragma once
#include "FileSystem.h" #include <Kernel/FileSystem/FileSystem.h>
#include "UnixTypes.h" #include <Kernel/FileSystem/Inode.h>
#include <Kernel/UnixTypes.h>
#include <AK/HashMap.h> #include <AK/HashMap.h>
class SynthFSInode; class SynthFSInode;

View file

@ -54,6 +54,7 @@ KERNEL_OBJS = \
VFS_OBJS = \ VFS_OBJS = \
FileSystem/ProcFS.o \ FileSystem/ProcFS.o \
FileSystem/Inode.o \
Devices/DiskDevice.o \ Devices/DiskDevice.o \
Devices/Device.o \ Devices/Device.o \
Devices/CharacterDevice.o \ Devices/CharacterDevice.o \

View file

@ -1,4 +1,5 @@
#include <Kernel/VM/MemoryManager.h> #include <Kernel/VM/MemoryManager.h>
#include <Kernel/FileSystem/Inode.h>
#include <AK/Assertions.h> #include <AK/Assertions.h>
#include <AK/kstdio.h> #include <AK/kstdio.h>
#include "i386.h" #include "i386.h"

View file

@ -1,6 +1,7 @@
#include <Kernel/VM/VMObject.h> #include <Kernel/VM/VMObject.h>
#include <Kernel/VM/MemoryManager.h> #include <Kernel/VM/MemoryManager.h>
#include <FileSystem/FileSystem.h> #include <Kernel/FileSystem/FileSystem.h>
#include <Kernel/FileSystem/Inode.h>
Retained<VMObject> VMObject::create_file_backed(RetainPtr<Inode>&& inode) Retained<VMObject> VMObject::create_file_backed(RetainPtr<Inode>&& inode)
{ {