mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 20:52:45 +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
	
	 Andreas Kling
						Andreas Kling