mirror of
https://github.com/RGBCube/serenity
synced 2025-05-30 23:48:11 +00:00
Kernel: Move Inode to its own files.
This commit is contained in:
parent
8aecebe8f3
commit
176f683f66
11 changed files with 240 additions and 205 deletions
|
@ -1,9 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "DiskBackedFileSystem.h"
|
||||
#include "UnixTypes.h"
|
||||
#include <AK/OwnPtr.h>
|
||||
#include "ext2_fs.h"
|
||||
#include <Kernel/UnixTypes.h>
|
||||
#include <Kernel/FileSystem/Inode.h>
|
||||
#include <Kernel/FileSystem/ext2_fs.h>
|
||||
#include <Kernel/FileSystem/DiskBackedFileSystem.h>
|
||||
|
||||
struct ext2_group_desc;
|
||||
struct ext2_inode;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
||||
#include <Kernel/FileSystem/InodeMetadata.h>
|
||||
#include <Kernel/FileSystem/Inode.h>
|
||||
#include <Kernel/FileSystem/FIFO.h>
|
||||
#include <Kernel/LinearAddress.h>
|
||||
#include <AK/ByteBuffer.h>
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
#include <AK/HashMap.h>
|
||||
#include <AK/StringBuilder.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/Net/LocalSocket.h>
|
||||
|
||||
static dword s_lastFileSystemID;
|
||||
static HashMap<dword, FS*>* s_fs_map;
|
||||
static HashTable<Inode*>* s_inode_set;
|
||||
|
||||
static HashMap<dword, FS*>& all_fses()
|
||||
{
|
||||
|
@ -17,12 +17,6 @@ static HashMap<dword, FS*>& all_fses()
|
|||
return *s_fs_map;
|
||||
}
|
||||
|
||||
HashTable<Inode*>& all_inodes()
|
||||
{
|
||||
if (!s_inode_set)
|
||||
s_inode_set = new HashTable<Inode*>();
|
||||
return *s_inode_set;
|
||||
}
|
||||
|
||||
FS::FS()
|
||||
: m_fsid(++s_lastFileSystemID)
|
||||
|
@ -43,30 +37,6 @@ FS* FS::from_fsid(dword id)
|
|||
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)
|
||||
: name_length(strlen(n))
|
||||
, inode(i)
|
||||
|
@ -85,76 +55,9 @@ FS::DirectoryEntry::DirectoryEntry(const char* n, int nl, InodeIdentifier i, byt
|
|||
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()
|
||||
{
|
||||
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();
|
||||
}
|
||||
Inode::sync();
|
||||
|
||||
Vector<Retained<FS>, 32> fses;
|
||||
{
|
||||
|
@ -166,22 +69,3 @@ void FS::sync()
|
|||
for (auto fs : fses)
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -69,80 +69,6 @@ private:
|
|||
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()
|
||||
{
|
||||
return FS::from_fsid(m_fsid);
|
||||
|
@ -158,11 +84,6 @@ inline bool InodeIdentifier::is_root_inode() const
|
|||
return (*this) == fs()->root_inode();
|
||||
}
|
||||
|
||||
inline unsigned Inode::fsid() const
|
||||
{
|
||||
return m_fs.fsid();
|
||||
}
|
||||
|
||||
namespace AK {
|
||||
|
||||
template<>
|
||||
|
|
132
Kernel/FileSystem/Inode.cpp
Normal file
132
Kernel/FileSystem/Inode.cpp
Normal 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
92
Kernel/FileSystem/Inode.h
Normal 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 };
|
||||
};
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
#include <Kernel/Lock.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/FileSystem/FileSystem.h>
|
||||
#include <Kernel/FileSystem/Inode.h>
|
||||
|
||||
class Process;
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "FileSystem.h"
|
||||
#include "UnixTypes.h"
|
||||
#include <Kernel/FileSystem/FileSystem.h>
|
||||
#include <Kernel/FileSystem/Inode.h>
|
||||
#include <Kernel/UnixTypes.h>
|
||||
#include <AK/HashMap.h>
|
||||
|
||||
class SynthFSInode;
|
||||
|
|
|
@ -54,6 +54,7 @@ KERNEL_OBJS = \
|
|||
|
||||
VFS_OBJS = \
|
||||
FileSystem/ProcFS.o \
|
||||
FileSystem/Inode.o \
|
||||
Devices/DiskDevice.o \
|
||||
Devices/Device.o \
|
||||
Devices/CharacterDevice.o \
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <Kernel/VM/MemoryManager.h>
|
||||
#include <Kernel/FileSystem/Inode.h>
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/kstdio.h>
|
||||
#include "i386.h"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <Kernel/VM/VMObject.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)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue