fat.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #pragma once
  2. #include <vector>
  3. #include <stdint.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <types/size.h>
  7. #include <types/hash_map.hpp>
  8. #include <kernel/mem.h>
  9. #include <kernel/vfs.hpp>
  10. namespace fs::fat {
  11. using cluster_t = uint32_t;
  12. // for FAT32
  13. struct PACKED old_boot_sector {
  14. uint8_t jmp_instruction[3];
  15. char oem_name[8];
  16. // usually 512
  17. uint16_t bytes_per_sector;
  18. uint8_t sectors_per_cluster;
  19. // 32 for FAT32
  20. uint16_t reserved_sectors;
  21. // usually 2
  22. uint8_t fat_copies;
  23. // 0 for FAT32
  24. uint16_t root_directory_entries;
  25. // valid before FAT32
  26. uint16_t _sectors_cnt;
  27. // 0xf8 for hard disk
  28. uint8_t type;
  29. // valid before FAT32
  30. uint16_t _sectors_per_fat;
  31. // 12
  32. uint16_t sectors_per_track;
  33. // 2
  34. uint16_t heads;
  35. // 0
  36. uint16_t hidden_sectors;
  37. };
  38. // for FAT32
  39. struct PACKED ext_boot_sector {
  40. struct old_boot_sector old;
  41. // 0
  42. uint16_t hidden_sector_ext;
  43. uint32_t sectors_cnt;
  44. uint32_t sectors_per_fat;
  45. uint16_t mirror_flags;
  46. uint16_t fs_version;
  47. // 2
  48. cluster_t root_directory;
  49. // 1
  50. uint16_t fs_info_sector;
  51. // usually at 6, 0x0000 or 0xffff if none
  52. uint16_t backup_boot_sector;
  53. uint8_t _reserved[12];
  54. // for int $0x13
  55. uint8_t drive_number;
  56. uint8_t _reserved_for_current_head;
  57. // 0x29
  58. uint8_t ext_signature;
  59. uint32_t serial_number;
  60. char label[11];
  61. char fs_type[8];
  62. uint8_t _reserved_blank[420];
  63. // 0x55, 0xaa
  64. uint16_t magic;
  65. };
  66. struct PACKED fs_info_sector {
  67. // 0x41615252
  68. uint32_t signature_one;
  69. uint8_t _reserved[480];
  70. // 0x61417272
  71. uint32_t signature_two;
  72. // may be incorrect
  73. uint32_t free_clusters;
  74. // hint only
  75. uint32_t next_free_cluster;
  76. uint8_t _reserved_two[12];
  77. // 0xaa550000
  78. uint32_t sector_signature;
  79. };
  80. struct PACKED directory_entry {
  81. char filename[8];
  82. char extension[3];
  83. struct PACKED {
  84. uint8_t ro : 1;
  85. uint8_t hidden : 1;
  86. uint8_t system : 1;
  87. uint8_t volume_label : 1;
  88. uint8_t subdir : 1;
  89. uint8_t archive : 1;
  90. uint8_t _reserved : 2;
  91. } attributes;
  92. uint8_t _reserved;
  93. uint8_t c_time_date[5];
  94. uint16_t access_date;
  95. uint16_t cluster_hi;
  96. uint8_t m_time_date[4];
  97. uint16_t cluster_lo;
  98. uint32_t size;
  99. };
  100. // TODO: deallocate inodes when dentry is destroyed
  101. class fat32 : public virtual fs::vfs {
  102. private:
  103. constexpr static size_t SECTOR_SIZE = 512;
  104. constexpr static cluster_t EOC = 0xffffff8;
  105. private:
  106. uint32_t sector_cnt;
  107. uint32_t sectors_per_fat;
  108. uint32_t serial_number;
  109. uint32_t free_clusters;
  110. uint32_t next_free_cluster_hint;
  111. cluster_t root_dir;
  112. cluster_t data_region_offset;
  113. dev_t device;
  114. uint16_t reserved_sectors;
  115. uint8_t fat_copies;
  116. uint8_t sectors_per_cluster;
  117. char label[12];
  118. std::vector<cluster_t> fat;
  119. struct buf_object {
  120. char* data;
  121. int ref;
  122. // bool dirty;
  123. };
  124. types::hash_map<cluster_t, buf_object> buf;
  125. // buf MUST be larger than 512 bytes
  126. void _raw_read_sector(void* buf, uint32_t sector_no);
  127. // buf MUST be larger than 4096 bytes
  128. void _raw_read_cluster(void* buf, cluster_t no);
  129. ssize_t _read_sector_range(void* buf, size_t buf_size, uint32_t sector_offset, size_t sector_cnt);
  130. // buffered version, release_cluster(cluster_no) after used
  131. char* read_cluster(cluster_t no);
  132. void release_cluster(cluster_t no);
  133. static constexpr cluster_t cl(const inode* ind)
  134. {
  135. return ind->ino;
  136. }
  137. static inline cluster_t _rearrange(directory_entry* d)
  138. {
  139. return (((cluster_t)d->cluster_hi) << 16) + d->cluster_lo;
  140. }
  141. static inline size_t _write_buf_n(char* buf, size_t buf_size, const char* src, size_t n)
  142. {
  143. if (n <= buf_size) {
  144. memcpy(buf, src, n);
  145. return n;
  146. } else {
  147. memcpy(buf, src, buf_size);
  148. return buf_size;
  149. }
  150. }
  151. public:
  152. fat32(const fat32&) = delete;
  153. explicit fat32(dev_t device);
  154. virtual size_t read(inode* file, char* buf, size_t buf_size, size_t offset, size_t n) override;
  155. virtual int readdir(fs::inode* dir, size_t offset, const fs::vfs::filldir_func& callback) override;
  156. virtual int inode_statx(dentry* ent, statx* st, unsigned int mask) override;
  157. virtual int inode_stat(dentry* ent, struct stat* st) override;
  158. };
  159. }; // namespace fs::fat