FileSystem.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #pragma once
  2. #include "DiskDevice.h"
  3. #include "InodeIdentifier.h"
  4. #include "InodeMetadata.h"
  5. #include "Limits.h"
  6. #include "UnixTypes.h"
  7. #include <AK/ByteBuffer.h>
  8. #include <AK/HashMap.h>
  9. #include <AK/OwnPtr.h>
  10. #include <AK/Retainable.h>
  11. #include <AK/RetainPtr.h>
  12. #include <AK/AKString.h>
  13. #include <AK/Function.h>
  14. #include <AK/kstdio.h>
  15. #include <AK/Lock.h>
  16. #include <AK/WeakPtr.h>
  17. #include <Kernel/KResult.h>
  18. static const dword mepoch = 476763780;
  19. class Inode;
  20. class FileDescriptor;
  21. class LocalSocket;
  22. class VMObject;
  23. class FS : public Retainable<FS> {
  24. public:
  25. virtual ~FS();
  26. unsigned fsid() const { return m_fsid; }
  27. static FS* from_fsid(dword);
  28. static void sync();
  29. virtual bool initialize() = 0;
  30. virtual const char* class_name() const = 0;
  31. virtual InodeIdentifier root_inode() const = 0;
  32. bool is_readonly() const { return m_readonly; }
  33. virtual unsigned total_block_count() const { return 0; }
  34. virtual unsigned free_block_count() const { return 0; }
  35. virtual unsigned total_inode_count() const { return 0; }
  36. virtual unsigned free_inode_count() const { return 0; }
  37. struct DirectoryEntry {
  38. DirectoryEntry(const char* name, InodeIdentifier, byte file_type);
  39. DirectoryEntry(const char* name, size_t name_length, InodeIdentifier, byte file_type);
  40. char name[256];
  41. int name_length { 0 };
  42. InodeIdentifier inode;
  43. byte file_type { 0 };
  44. };
  45. virtual RetainPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, unsigned size, int& error) = 0;
  46. virtual RetainPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) = 0;
  47. virtual RetainPtr<Inode> get_inode(InodeIdentifier) const = 0;
  48. protected:
  49. FS();
  50. private:
  51. unsigned m_fsid { 0 };
  52. bool m_readonly { false };
  53. };
  54. class Inode : public Retainable<Inode> {
  55. friend class VFS;
  56. public:
  57. virtual ~Inode();
  58. virtual void one_retain_left() { }
  59. FS& fs() { return m_fs; }
  60. const FS& fs() const { return m_fs; }
  61. unsigned fsid() const;
  62. unsigned index() const { return m_index; }
  63. size_t size() const { return metadata().size; }
  64. bool is_symlink() const { return metadata().is_symlink(); }
  65. bool is_directory() const { return metadata().is_directory(); }
  66. bool is_character_device() const { return metadata().is_character_device(); }
  67. mode_t mode() const { return metadata().mode; }
  68. InodeIdentifier identifier() const { return { fsid(), index() }; }
  69. virtual InodeMetadata metadata() const = 0;
  70. ByteBuffer read_entire(FileDescriptor* = nullptr) const;
  71. virtual ssize_t read_bytes(off_t, ssize_t, byte* buffer, FileDescriptor*) const = 0;
  72. virtual bool traverse_as_directory(Function<bool(const FS::DirectoryEntry&)>) const = 0;
  73. virtual InodeIdentifier lookup(const String& name) = 0;
  74. virtual String reverse_lookup(InodeIdentifier) = 0;
  75. virtual ssize_t write_bytes(off_t, ssize_t, const byte* data, FileDescriptor*) = 0;
  76. virtual bool add_child(InodeIdentifier child_id, const String& name, byte file_type, int& error) = 0;
  77. virtual KResult remove_child(const String& name) = 0;
  78. virtual RetainPtr<Inode> parent() const = 0;
  79. virtual size_t directory_entry_count() const = 0;
  80. virtual KResult chmod(mode_t) = 0;
  81. virtual KResult chown(uid_t, gid_t) = 0;
  82. LocalSocket* socket() { return m_socket.ptr(); }
  83. const LocalSocket* socket() const { return m_socket.ptr(); }
  84. bool bind_socket(LocalSocket&);
  85. bool unbind_socket();
  86. bool is_metadata_dirty() const { return m_metadata_dirty; }
  87. virtual int set_atime(time_t);
  88. virtual int set_ctime(time_t);
  89. virtual int set_mtime(time_t);
  90. virtual int increment_link_count();
  91. virtual int decrement_link_count();
  92. virtual void flush_metadata() = 0;
  93. void will_be_destroyed();
  94. void set_vmo(VMObject&);
  95. VMObject* vmo() { return m_vmo.ptr(); }
  96. const VMObject* vmo() const { return m_vmo.ptr(); }
  97. protected:
  98. Inode(FS& fs, unsigned index);
  99. void set_metadata_dirty(bool b) { m_metadata_dirty = b; }
  100. void inode_contents_changed(off_t, ssize_t, const byte*);
  101. void inode_size_changed(size_t old_size, size_t new_size);
  102. mutable Lock m_lock;
  103. private:
  104. FS& m_fs;
  105. unsigned m_index { 0 };
  106. WeakPtr<VMObject> m_vmo;
  107. RetainPtr<LocalSocket> m_socket;
  108. bool m_metadata_dirty { false };
  109. };
  110. inline FS* InodeIdentifier::fs()
  111. {
  112. return FS::from_fsid(m_fsid);
  113. }
  114. inline const FS* InodeIdentifier::fs() const
  115. {
  116. return FS::from_fsid(m_fsid);
  117. }
  118. inline bool InodeIdentifier::is_root_inode() const
  119. {
  120. return (*this) == fs()->root_inode();
  121. }
  122. inline unsigned Inode::fsid() const
  123. {
  124. return m_fs.fsid();
  125. }
  126. namespace AK {
  127. template<>
  128. struct Traits<InodeIdentifier> {
  129. static unsigned hash(const InodeIdentifier& inode) { return pair_int_hash(inode.fsid(), inode.index()); }
  130. static void dump(const InodeIdentifier& inode) { kprintf("%02u:%08u", inode.fsid(), inode.index()); }
  131. };
  132. }