fat.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. #include <assert.h>
  2. #include <ctype.h>
  3. #include <fs/fat.hpp>
  4. #include <kernel/mem.h>
  5. #include <kernel/mm.hpp>
  6. #include <kernel/vfs.hpp>
  7. #include <stdint.h>
  8. #include <stdio.h>
  9. #include <types/allocator.hpp>
  10. #include <types/hash_map.hpp>
  11. #include <types/status.h>
  12. #define VFAT_FILENAME_LOWERCASE (0x08)
  13. #define VFAT_EXTENSION_LOWERCASE (0x10)
  14. namespace fs::fat {
  15. // buf MUST be larger than 512 bytes
  16. inline void fat32::_raw_read_sector(void* buf, uint32_t sector_no)
  17. {
  18. size_t n = fs::block_device_read(
  19. device,
  20. (char*)buf,
  21. SECTOR_SIZE,
  22. sector_no * SECTOR_SIZE,
  23. SECTOR_SIZE);
  24. assert(n == SECTOR_SIZE);
  25. }
  26. // buf MUST be larger than 4096 bytes
  27. inline void fat32::_raw_read_cluster(void* buf, cluster_t no)
  28. {
  29. // data cluster start from cluster #2
  30. no -= 2;
  31. for (int i = 0; i < sectors_per_cluster; ++i) {
  32. // skip reserved sectors
  33. _raw_read_sector((char*)buf + SECTOR_SIZE * i, data_region_offset + no * sectors_per_cluster + i);
  34. }
  35. }
  36. char* fat32::read_cluster(cluster_t no)
  37. {
  38. auto iter = buf.find(no);
  39. if (iter) {
  40. auto [ idx, buf ] = *iter;
  41. ++buf.ref;
  42. return buf.data;
  43. }
  44. auto* data = new char[sectors_per_cluster * SECTOR_SIZE];
  45. _raw_read_cluster(data, no);
  46. buf.emplace(no,
  47. buf_object {
  48. data,
  49. 1,
  50. // false,
  51. });
  52. return data;
  53. }
  54. void fat32::release_cluster(cluster_t no)
  55. {
  56. auto iter = buf.find(no);
  57. if (iter)
  58. --iter->second.ref;
  59. }
  60. int fat32::inode_readdir(fs::inode* dir, size_t offset, const fs::vfs::filldir_func& filldir)
  61. {
  62. cluster_t next = cl(dir);
  63. for (size_t i = 0; i < (offset / (sectors_per_cluster * SECTOR_SIZE)); ++i) {
  64. if (next >= EOC)
  65. return 0;
  66. next = fat[next];
  67. }
  68. size_t nread = 0;
  69. do {
  70. char* buf = read_cluster(next);
  71. auto* d = reinterpret_cast<directory_entry*>(buf) + (offset % (sectors_per_cluster * SECTOR_SIZE)) / sizeof(directory_entry);
  72. offset = 0;
  73. auto* end = d + (sectors_per_cluster * SECTOR_SIZE / sizeof(directory_entry));
  74. for (; d < end && d->filename[0]; ++d) {
  75. if (d->attributes.volume_label) {
  76. nread += sizeof(directory_entry);
  77. continue;
  78. }
  79. ino_t ino = _rearrange(d);
  80. auto* ind = get_inode(ino);
  81. if (!ind) {
  82. mode_t mode = 0777;
  83. if (d->attributes.subdir)
  84. mode |= S_IFDIR;
  85. else
  86. mode |= S_IFREG;
  87. ind = cache_inode(d->size, ino, mode, 0, 0);
  88. ind->nlink = d->attributes.subdir ? 2 : 1;
  89. }
  90. types::string<> fname;
  91. for (int i = 0; i < 8; ++i) {
  92. if (d->filename[i] == ' ')
  93. break;
  94. if (d->_reserved & VFAT_FILENAME_LOWERCASE)
  95. fname += tolower(d->filename[i]);
  96. else
  97. fname += toupper(d->filename[i]);
  98. }
  99. if (d->extension[0] != ' ')
  100. fname += '.';
  101. for (int i = 1; i < 3; ++i) {
  102. if (d->extension[i] == ' ')
  103. break;
  104. if (d->_reserved & VFAT_EXTENSION_LOWERCASE)
  105. fname += tolower(d->extension[i]);
  106. else
  107. fname += toupper(d->extension[i]);
  108. }
  109. auto ret = filldir(fname.c_str(), 0, ind->ino, ind->mode & S_IFMT);
  110. if (ret != GB_OK) {
  111. release_cluster(next);
  112. return nread;
  113. }
  114. nread += sizeof(directory_entry);
  115. }
  116. release_cluster(next);
  117. next = fat[next];
  118. } while (next < EOC);
  119. return nread;
  120. }
  121. fat32::fat32(inode* _device)
  122. : device(_device->fs->inode_devid(_device))
  123. , label { 0 }
  124. {
  125. auto* buf = new char[SECTOR_SIZE];
  126. _raw_read_sector(buf, 0);
  127. auto* info = reinterpret_cast<ext_boot_sector*>(buf);
  128. sector_cnt = info->sectors_cnt;
  129. sectors_per_fat = info->sectors_per_fat;
  130. sectors_per_cluster = info->old.sectors_per_cluster;
  131. serial_number = info->serial_number;
  132. root_dir = info->root_directory;
  133. reserved_sectors = info->old.reserved_sectors;
  134. fat_copies = info->old.fat_copies;
  135. data_region_offset = reserved_sectors + fat_copies * sectors_per_fat;
  136. fat = (cluster_t*)new char[SECTOR_SIZE * sectors_per_fat];
  137. for (uint32_t i = 0; i < sectors_per_fat; ++i)
  138. _raw_read_sector((char*)fat + i * SECTOR_SIZE, reserved_sectors + i);
  139. int i = 0;
  140. while (i < 11 && info->label[i] != 0x20) {
  141. label[i] = info->label[i];
  142. ++i;
  143. }
  144. label[i] = 0x00;
  145. _raw_read_sector(buf, info->fs_info_sector);
  146. auto* fsinfo = reinterpret_cast<fs_info_sector*>(buf);
  147. free_clusters = fsinfo->free_clusters;
  148. next_free_cluster_hint = fsinfo->next_free_cluster;
  149. delete[] buf;
  150. size_t _root_dir_clusters = 1;
  151. cluster_t next = root_dir;
  152. while ((next = fat[next]) < EOC)
  153. ++_root_dir_clusters;
  154. auto* n = cache_inode(
  155. _root_dir_clusters * sectors_per_cluster * SECTOR_SIZE,
  156. root_dir, S_IFDIR | 0777, 0, 0);
  157. n->nlink = 2;
  158. register_root_node(n);
  159. }
  160. fat32::~fat32()
  161. {
  162. delete[]((char*)fat);
  163. }
  164. size_t fat32::inode_read(inode* file, char* buf, size_t buf_size, size_t offset, size_t n)
  165. {
  166. cluster_t next = cl(file);
  167. uint32_t cluster_size = SECTOR_SIZE * sectors_per_cluster;
  168. size_t orig_n = n;
  169. do {
  170. if (offset == 0) {
  171. if (n > cluster_size) {
  172. auto* data = read_cluster(next);
  173. memcpy(buf, data, cluster_size);
  174. release_cluster(next);
  175. buf_size -= cluster_size;
  176. buf += cluster_size;
  177. n -= cluster_size;
  178. } else {
  179. auto* data = read_cluster(next);
  180. auto read = _write_buf_n(buf, buf_size, data, n);
  181. release_cluster(next);
  182. return orig_n - n + read;
  183. }
  184. } else {
  185. if (offset > cluster_size) {
  186. offset -= cluster_size;
  187. } else {
  188. auto* data = read_cluster(next);
  189. auto to_read = cluster_size - offset;
  190. if (to_read > n)
  191. to_read = n;
  192. auto read = _write_buf_n(buf, buf_size, data + offset, to_read);
  193. buf += read;
  194. n -= read;
  195. release_cluster(next);
  196. if (read != to_read) {
  197. return orig_n - n;
  198. }
  199. offset = 0;
  200. }
  201. }
  202. next = fat[next];
  203. } while (n && next < EOC);
  204. return orig_n - n;
  205. }
  206. int fat32::inode_statx(dentry* ent, statx* st, unsigned int mask)
  207. {
  208. st->stx_mask = 0;
  209. if (mask & STATX_SIZE) {
  210. st->stx_size = ent->ind->size;
  211. st->stx_mask |= STATX_SIZE;
  212. }
  213. if (mask & STATX_BLOCKS) {
  214. st->stx_blocks = align_up<12>(ent->ind->size) / 512;
  215. st->stx_blksize = 4096;
  216. st->stx_mask |= STATX_BLOCKS;
  217. }
  218. if (mask & STATX_NLINK) {
  219. st->stx_nlink = ent->ind->nlink;
  220. st->stx_mask |= STATX_NLINK;
  221. }
  222. st->stx_mode = 0;
  223. if (mask & STATX_MODE) {
  224. st->stx_mode |= ent->ind->mode & ~S_IFMT;
  225. st->stx_mask |= STATX_MODE;
  226. }
  227. if (mask & STATX_TYPE) {
  228. st->stx_mode |= ent->ind->mode & S_IFMT;
  229. st->stx_mask |= STATX_TYPE;
  230. }
  231. if (mask & STATX_INO) {
  232. st->stx_ino = ent->ind->ino;
  233. st->stx_mask |= STATX_INO;
  234. }
  235. if (mask & STATX_UID) {
  236. st->stx_uid = ent->ind->uid;
  237. st->stx_mask |= STATX_UID;
  238. }
  239. if (mask & STATX_GID) {
  240. st->stx_gid = ent->ind->gid;
  241. st->stx_mask |= STATX_GID;
  242. }
  243. return GB_OK;
  244. }
  245. int fat32::inode_stat(dentry* dent, struct stat* st)
  246. {
  247. auto* ind = dent->ind;
  248. memset(st, 0x00, sizeof(struct stat));
  249. st->st_mode = ind->mode;
  250. st->st_dev = device;
  251. st->st_nlink = S_ISDIR(ind->mode) ? 2 : 1;
  252. st->st_size = ind->size;
  253. st->st_blksize = 4096;
  254. st->st_blocks = (ind->size + 511) / 512;
  255. st->st_ino = ind->ino;
  256. return GB_OK;
  257. }
  258. } // namespace fs::fat