FatPartition.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. /**
  2. * Copyright (c) 2011-2021 Bill Greiman
  3. * This file is part of the SdFat library for SD memory cards.
  4. *
  5. * MIT License
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included
  15. * in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23. * DEALINGS IN THE SOFTWARE.
  24. */
  25. #include <string.h>
  26. #define DBG_FILE "FatPartition.cpp"
  27. #include "../common/DebugMacros.h"
  28. #include "FatLib.h"
  29. //------------------------------------------------------------------------------
  30. bool FatPartition::allocateCluster(uint32_t current, uint32_t* next) {
  31. uint32_t find;
  32. bool setStart;
  33. if (m_allocSearchStart < current) {
  34. // Try to keep file contiguous. Start just after current cluster.
  35. find = current;
  36. setStart = false;
  37. } else {
  38. find = m_allocSearchStart;
  39. setStart = true;
  40. }
  41. while (1) {
  42. find++;
  43. if (find > m_lastCluster) {
  44. if (setStart) {
  45. // Can't find space, checked all clusters.
  46. DBG_FAIL_MACRO;
  47. goto fail;
  48. }
  49. find = m_allocSearchStart;
  50. setStart = true;
  51. continue;
  52. }
  53. if (find == current) {
  54. // Can't find space, already searched clusters after current.
  55. DBG_FAIL_MACRO;
  56. goto fail;
  57. }
  58. uint32_t f;
  59. int8_t fg = fatGet(find, &f);
  60. if (fg < 0) {
  61. DBG_FAIL_MACRO;
  62. goto fail;
  63. }
  64. if (fg && f == 0) {
  65. break;
  66. }
  67. }
  68. if (setStart) {
  69. m_allocSearchStart = find;
  70. }
  71. // Mark end of chain.
  72. if (!fatPutEOC(find)) {
  73. DBG_FAIL_MACRO;
  74. goto fail;
  75. }
  76. if (current) {
  77. // Link clusters.
  78. if (!fatPut(current, find)) {
  79. DBG_FAIL_MACRO;
  80. goto fail;
  81. }
  82. }
  83. updateFreeClusterCount(-1);
  84. *next = find;
  85. return true;
  86. fail:
  87. return false;
  88. }
  89. //------------------------------------------------------------------------------
  90. // find a contiguous group of clusters
  91. bool FatPartition::allocContiguous(uint32_t count, uint32_t* firstCluster) {
  92. // flag to save place to start next search
  93. bool setStart = true;
  94. // start of group
  95. uint32_t bgnCluster;
  96. // end of group
  97. uint32_t endCluster;
  98. // Start at cluster after last allocated cluster.
  99. endCluster = bgnCluster = m_allocSearchStart + 1;
  100. // search the FAT for free clusters
  101. while (1) {
  102. if (endCluster > m_lastCluster) {
  103. // Can't find space.
  104. DBG_FAIL_MACRO;
  105. goto fail;
  106. }
  107. uint32_t f;
  108. int8_t fg = fatGet(endCluster, &f);
  109. if (fg < 0) {
  110. DBG_FAIL_MACRO;
  111. goto fail;
  112. }
  113. if (f || fg == 0) {
  114. // don't update search start if unallocated clusters before endCluster.
  115. if (bgnCluster != endCluster) {
  116. setStart = false;
  117. }
  118. // cluster in use try next cluster as bgnCluster
  119. bgnCluster = endCluster + 1;
  120. } else if ((endCluster - bgnCluster + 1) == count) {
  121. // done - found space
  122. break;
  123. }
  124. endCluster++;
  125. }
  126. // Remember possible next free cluster.
  127. if (setStart) {
  128. m_allocSearchStart = endCluster;
  129. }
  130. // mark end of chain
  131. if (!fatPutEOC(endCluster)) {
  132. DBG_FAIL_MACRO;
  133. goto fail;
  134. }
  135. // link clusters
  136. while (endCluster > bgnCluster) {
  137. if (!fatPut(endCluster - 1, endCluster)) {
  138. DBG_FAIL_MACRO;
  139. goto fail;
  140. }
  141. endCluster--;
  142. }
  143. // Maintain count of free clusters.
  144. updateFreeClusterCount(-count);
  145. // return first cluster number to caller
  146. *firstCluster = bgnCluster;
  147. return true;
  148. fail:
  149. return false;
  150. }
  151. //------------------------------------------------------------------------------
  152. // Fetch a FAT entry - return -1 error, 0 EOC, else 1.
  153. int8_t FatPartition::fatGet(uint32_t cluster, uint32_t* value) {
  154. uint32_t sector;
  155. uint32_t next;
  156. uint8_t* pc;
  157. // error if reserved cluster of beyond FAT
  158. if (cluster < 2 || cluster > m_lastCluster) {
  159. DBG_FAIL_MACRO;
  160. goto fail;
  161. }
  162. if (fatType() == 32) {
  163. sector = m_fatStartSector + (cluster >> (m_bytesPerSectorShift - 2));
  164. pc = fatCachePrepare(sector, FsCache::CACHE_FOR_READ);
  165. if (!pc) {
  166. DBG_FAIL_MACRO;
  167. goto fail;
  168. }
  169. uint16_t offset = (cluster << 2) & m_sectorMask;
  170. next = getLe32(pc + offset);
  171. } else if (fatType() == 16) {
  172. cluster &= 0XFFFF;
  173. sector = m_fatStartSector + (cluster >> (m_bytesPerSectorShift - 1) );
  174. pc = fatCachePrepare(sector, FsCache::CACHE_FOR_READ);
  175. if (!pc) {
  176. DBG_FAIL_MACRO;
  177. goto fail;
  178. }
  179. uint16_t offset = (cluster << 1) & m_sectorMask;
  180. next = getLe16(pc + offset);
  181. } else if (FAT12_SUPPORT && fatType() == 12) {
  182. uint16_t index = cluster;
  183. index += index >> 1;
  184. sector = m_fatStartSector + (index >> m_bytesPerSectorShift);
  185. pc = fatCachePrepare(sector, FsCache::CACHE_FOR_READ);
  186. if (!pc) {
  187. DBG_FAIL_MACRO;
  188. goto fail;
  189. }
  190. index &= m_sectorMask;
  191. uint16_t tmp = pc[index];
  192. index++;
  193. if (index == m_bytesPerSector) {
  194. pc = fatCachePrepare(sector + 1, FsCache::CACHE_FOR_READ);
  195. if (!pc) {
  196. DBG_FAIL_MACRO;
  197. goto fail;
  198. }
  199. index = 0;
  200. }
  201. tmp |= pc[index] << 8;
  202. next = cluster & 1 ? tmp >> 4 : tmp & 0XFFF;
  203. } else {
  204. DBG_FAIL_MACRO;
  205. goto fail;
  206. }
  207. if (isEOC(next)) {
  208. return 0;
  209. }
  210. *value = next;
  211. return 1;
  212. fail:
  213. return -1;
  214. }
  215. //------------------------------------------------------------------------------
  216. // Store a FAT entry
  217. bool FatPartition::fatPut(uint32_t cluster, uint32_t value) {
  218. uint32_t sector;
  219. uint8_t* pc;
  220. // error if reserved cluster of beyond FAT
  221. if (cluster < 2 || cluster > m_lastCluster) {
  222. DBG_FAIL_MACRO;
  223. goto fail;
  224. }
  225. if (fatType() == 32) {
  226. sector = m_fatStartSector + (cluster >> (m_bytesPerSectorShift - 2));
  227. pc = fatCachePrepare(sector, FsCache::CACHE_FOR_WRITE);
  228. if (!pc) {
  229. DBG_FAIL_MACRO;
  230. goto fail;
  231. }
  232. uint16_t offset = (cluster << 2) & m_sectorMask;
  233. setLe32(pc + offset, value);
  234. return true;
  235. }
  236. if (fatType() == 16) {
  237. cluster &= 0XFFFF;
  238. sector = m_fatStartSector + (cluster >> (m_bytesPerSectorShift - 1) );
  239. pc = fatCachePrepare(sector, FsCache::CACHE_FOR_WRITE);
  240. if (!pc) {
  241. DBG_FAIL_MACRO;
  242. goto fail;
  243. }
  244. uint16_t offset = (cluster << 1) & m_sectorMask;
  245. setLe16(pc + offset, value);
  246. return true;
  247. }
  248. if (FAT12_SUPPORT && fatType() == 12) {
  249. uint16_t index = cluster;
  250. index += index >> 1;
  251. sector = m_fatStartSector + (index >> m_bytesPerSectorShift);
  252. pc = fatCachePrepare(sector, FsCache::CACHE_FOR_WRITE);
  253. if (!pc) {
  254. DBG_FAIL_MACRO;
  255. goto fail;
  256. }
  257. index &= m_sectorMask;
  258. uint8_t tmp = value;
  259. if (cluster & 1) {
  260. tmp = (pc[index] & 0XF) | tmp << 4;
  261. }
  262. pc[index] = tmp;
  263. index++;
  264. if (index == m_bytesPerSector) {
  265. sector++;
  266. index = 0;
  267. pc = fatCachePrepare(sector, FsCache::CACHE_FOR_WRITE);
  268. if (!pc) {
  269. DBG_FAIL_MACRO;
  270. goto fail;
  271. }
  272. }
  273. tmp = value >> 4;
  274. if (!(cluster & 1)) {
  275. tmp = ((pc[index] & 0XF0)) | tmp >> 4;
  276. }
  277. pc[index] = tmp;
  278. return true;
  279. } else {
  280. DBG_FAIL_MACRO;
  281. goto fail;
  282. }
  283. fail:
  284. return false;
  285. }
  286. //------------------------------------------------------------------------------
  287. // free a cluster chain
  288. bool FatPartition::freeChain(uint32_t cluster) {
  289. uint32_t next;
  290. int8_t fg;
  291. do {
  292. fg = fatGet(cluster, &next);
  293. if (fg < 0) {
  294. DBG_FAIL_MACRO;
  295. goto fail;
  296. }
  297. // free cluster
  298. if (!fatPut(cluster, 0)) {
  299. DBG_FAIL_MACRO;
  300. goto fail;
  301. }
  302. // Add one to count of free clusters.
  303. updateFreeClusterCount(1);
  304. if (cluster < m_allocSearchStart) {
  305. m_allocSearchStart = cluster - 1;
  306. }
  307. cluster = next;
  308. } while (fg);
  309. return true;
  310. fail:
  311. return false;
  312. }
  313. //------------------------------------------------------------------------------
  314. int32_t FatPartition::freeClusterCount() {
  315. #if MAINTAIN_FREE_CLUSTER_COUNT
  316. if (m_freeClusterCount >= 0) {
  317. return m_freeClusterCount;
  318. }
  319. #endif // MAINTAIN_FREE_CLUSTER_COUNT
  320. uint32_t free = 0;
  321. uint32_t sector;
  322. uint32_t todo = m_lastCluster + 1;
  323. uint16_t n;
  324. if (FAT12_SUPPORT && fatType() == 12) {
  325. for (unsigned i = 2; i < todo; i++) {
  326. uint32_t c;
  327. int8_t fg = fatGet(i, &c);
  328. if (fg < 0) {
  329. DBG_FAIL_MACRO;
  330. goto fail;
  331. }
  332. if (fg && c == 0) {
  333. free++;
  334. }
  335. }
  336. } else if (fatType() == 16 || fatType() == 32) {
  337. sector = m_fatStartSector;
  338. while (todo) {
  339. uint8_t* pc = fatCachePrepare(sector++, FsCache::CACHE_FOR_READ);
  340. if (!pc) {
  341. DBG_FAIL_MACRO;
  342. goto fail;
  343. }
  344. n = fatType() == 16 ? m_bytesPerSector/2 : m_bytesPerSector/4;
  345. if (todo < n) {
  346. n = todo;
  347. }
  348. if (fatType() == 16) {
  349. uint16_t* p16 = reinterpret_cast<uint16_t*>(pc);
  350. for (uint16_t i = 0; i < n; i++) {
  351. if (p16[i] == 0) {
  352. free++;
  353. }
  354. }
  355. } else {
  356. uint32_t* p32 = reinterpret_cast<uint32_t*>(pc);
  357. for (uint16_t i = 0; i < n; i++) {
  358. if (p32[i] == 0) {
  359. free++;
  360. }
  361. }
  362. }
  363. todo -= n;
  364. }
  365. } else {
  366. // invalid FAT type
  367. DBG_FAIL_MACRO;
  368. goto fail;
  369. }
  370. setFreeClusterCount(free);
  371. return free;
  372. fail:
  373. return -1;
  374. }
  375. //------------------------------------------------------------------------------
  376. bool FatPartition::init(BlockDevice* dev, uint8_t part) {
  377. uint32_t clusterCount;
  378. uint32_t totalSectors;
  379. uint32_t volumeStartSector = 0;
  380. m_blockDev = dev;
  381. pbs_t* pbs;
  382. BpbFat32_t* bpb;
  383. MbrSector_t* mbr;
  384. uint8_t tmp;
  385. m_fatType = 0;
  386. m_allocSearchStart = 1;
  387. m_cache.init(dev);
  388. #if USE_SEPARATE_FAT_CACHE
  389. m_fatCache.init(dev);
  390. #endif // USE_SEPARATE_FAT_CACHE
  391. // if part == 0 assume super floppy with FAT boot sector in sector zero
  392. // if part > 0 assume mbr volume with partition table
  393. if (part) {
  394. if (part > 4) {
  395. DBG_FAIL_MACRO;
  396. goto fail;
  397. }
  398. mbr = reinterpret_cast<MbrSector_t*>
  399. (dataCachePrepare(0, FsCache::CACHE_FOR_READ));
  400. MbrPart_t* mp = mbr->part + part - 1;
  401. if (!mbr || mp->type == 0 || (mp->boot != 0 && mp->boot != 0X80)) {
  402. DBG_FAIL_MACRO;
  403. goto fail;
  404. }
  405. volumeStartSector = getLe32(mp->relativeSectors);
  406. }
  407. pbs = reinterpret_cast<pbs_t*>
  408. (dataCachePrepare(volumeStartSector, FsCache::CACHE_FOR_READ));
  409. bpb = reinterpret_cast<BpbFat32_t*>(pbs->bpb);
  410. if (!pbs || bpb->fatCount != 2 ||
  411. getLe16(bpb->bytesPerSector) != m_bytesPerSector) {
  412. DBG_FAIL_MACRO;
  413. goto fail;
  414. }
  415. m_sectorsPerCluster = bpb->sectorsPerCluster;
  416. m_clusterSectorMask = m_sectorsPerCluster - 1;
  417. // determine shift that is same as multiply by m_sectorsPerCluster
  418. m_sectorsPerClusterShift = 0;
  419. for (tmp = 1; m_sectorsPerCluster != tmp; tmp <<= 1) {
  420. if (tmp == 0) {
  421. DBG_FAIL_MACRO;
  422. goto fail;
  423. }
  424. m_sectorsPerClusterShift++;
  425. }
  426. m_sectorsPerFat = getLe16(bpb->sectorsPerFat16);
  427. if (m_sectorsPerFat == 0) {
  428. m_sectorsPerFat = getLe32(bpb->sectorsPerFat32);
  429. }
  430. m_fatStartSector = volumeStartSector + getLe16(bpb->reservedSectorCount);
  431. // count for FAT16 zero for FAT32
  432. m_rootDirEntryCount = getLe16(bpb->rootDirEntryCount);
  433. // directory start for FAT16 dataStart for FAT32
  434. m_rootDirStart = m_fatStartSector + 2 * m_sectorsPerFat;
  435. // data start for FAT16 and FAT32
  436. m_dataStartSector = m_rootDirStart +
  437. ((FS_DIR_SIZE*m_rootDirEntryCount + m_bytesPerSector - 1)/m_bytesPerSector);
  438. // total sectors for FAT16 or FAT32
  439. totalSectors = getLe16(bpb->totalSectors16);
  440. if (totalSectors == 0) {
  441. totalSectors = getLe32(bpb->totalSectors32);
  442. }
  443. // total data sectors
  444. clusterCount = totalSectors - (m_dataStartSector - volumeStartSector);
  445. // divide by cluster size to get cluster count
  446. clusterCount >>= m_sectorsPerClusterShift;
  447. m_lastCluster = clusterCount + 1;
  448. // Indicate unknown number of free clusters.
  449. setFreeClusterCount(-1);
  450. // FAT type is determined by cluster count
  451. if (clusterCount < 4085) {
  452. m_fatType = 12;
  453. if (!FAT12_SUPPORT) {
  454. DBG_FAIL_MACRO;
  455. goto fail;
  456. }
  457. } else if (clusterCount < 65525) {
  458. m_fatType = 16;
  459. } else {
  460. m_rootDirStart = getLe32(bpb->fat32RootCluster);
  461. m_fatType = 32;
  462. }
  463. m_cache.setMirrorOffset(m_sectorsPerFat);
  464. #if USE_SEPARATE_FAT_CACHE
  465. m_fatCache.setMirrorOffset(m_sectorsPerFat);
  466. #endif // USE_SEPARATE_FAT_CACHE
  467. return true;
  468. fail:
  469. return false;
  470. }