lfs.c 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382
  1. /*
  2. * The little filesystem
  3. *
  4. * Copyright (c) 2017 Christopher Haster
  5. * Distributed under the MIT license
  6. */
  7. #include "lfs.h"
  8. #include "lfs_util.h"
  9. #include <string.h>
  10. #include <stdbool.h>
  11. /// Block device operations ///
  12. static int lfs_bd_read(lfs_t *lfs, lfs_block_t block,
  13. lfs_off_t off, lfs_size_t size, void *buffer) {
  14. return lfs->cfg->read(lfs->cfg, block, off, size, buffer);
  15. }
  16. static int lfs_bd_prog(lfs_t *lfs, lfs_block_t block,
  17. lfs_off_t off, lfs_size_t size, const void *buffer) {
  18. return lfs->cfg->prog(lfs->cfg, block, off, size, buffer);
  19. }
  20. static int lfs_bd_erase(lfs_t *lfs, lfs_block_t block) {
  21. return lfs->cfg->erase(lfs->cfg, block);
  22. }
  23. static int lfs_bd_sync(lfs_t *lfs) {
  24. return lfs->cfg->sync(lfs->cfg);
  25. }
  26. static int lfs_bd_cmp(lfs_t *lfs, lfs_block_t block,
  27. lfs_off_t off, lfs_size_t size, const void *buffer) {
  28. const uint8_t *data = buffer;
  29. for (lfs_off_t i = 0; i < size; i++) {
  30. uint8_t c;
  31. int err = lfs_bd_read(lfs, block, off+i, 1, &c);
  32. if (err) {
  33. return err;
  34. }
  35. if (c != *data) {
  36. return false;
  37. }
  38. data += 1;
  39. }
  40. return true;
  41. }
  42. /// Block allocator ///
  43. static int lfs_alloc_lookahead(void *p, lfs_block_t block) {
  44. lfs_t *lfs = p;
  45. lfs_block_t off = block - lfs->free.begin;
  46. if (off < LFS_CFG_LOOKAHEAD) {
  47. lfs->lookahead[off / 32] |= 1U << (off % 32);
  48. }
  49. return 0;
  50. }
  51. static int lfs_alloc_stride(void *p, lfs_block_t block) {
  52. lfs_t *lfs = p;
  53. lfs_block_t noff = block - lfs->free.begin;
  54. lfs_block_t off = lfs->free.end - lfs->free.begin;
  55. if (noff < off) {
  56. lfs->free.end = noff + lfs->free.begin;
  57. }
  58. return 0;
  59. }
  60. static int lfs_alloc_scan(lfs_t *lfs) {
  61. lfs_block_t start = lfs->free.begin;
  62. while (true) {
  63. // mask out blocks in lookahead region
  64. memset(lfs->lookahead, 0, sizeof(lfs->lookahead));
  65. int err = lfs_traverse(lfs, lfs_alloc_lookahead, lfs);
  66. if (err) {
  67. return err;
  68. }
  69. // check if we've found a free block
  70. for (uint32_t off = 0; off < LFS_CFG_LOOKAHEAD; off++) {
  71. if (lfs->lookahead[off / 32] & (1U << (off % 32))) {
  72. continue;
  73. }
  74. // found free block, now find stride of free blocks
  75. // since this is relatively cheap (stress on relatively)
  76. lfs->free.begin += off;
  77. lfs->free.end = lfs->cfg->block_count; // before superblock
  78. // find maximum stride in tree
  79. return lfs_traverse(lfs, lfs_alloc_stride, lfs);
  80. }
  81. // continue to next lookahead unless we've searched the whole device
  82. if (start-1 - lfs->free.begin < LFS_CFG_LOOKAHEAD) {
  83. return 0;
  84. }
  85. // continue to next lookahead region
  86. lfs->free.begin += LFS_CFG_LOOKAHEAD;
  87. }
  88. }
  89. static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
  90. // If we don't remember any free blocks we will need to start searching
  91. if (lfs->free.begin == lfs->free.end) {
  92. int err = lfs_alloc_scan(lfs);
  93. if (err) {
  94. return err;
  95. }
  96. if (lfs->free.begin == lfs->free.end) {
  97. // Still can't allocate a block? check for orphans
  98. int err = lfs_deorphan(lfs);
  99. if (err) {
  100. return err;
  101. }
  102. err = lfs_alloc_scan(lfs);
  103. if (err) {
  104. return err;
  105. }
  106. if (lfs->free.begin == lfs->free.end) {
  107. // Ok, it's true, we're out of space
  108. return LFS_ERROR_NO_SPACE;
  109. }
  110. }
  111. }
  112. // Take first available block
  113. *block = lfs->free.begin;
  114. lfs->free.begin += 1;
  115. return 0;
  116. }
  117. static int lfs_alloc_erased(lfs_t *lfs, lfs_block_t *block) {
  118. // TODO rm me?
  119. int err = lfs_alloc(lfs, block);
  120. if (err) {
  121. return err;
  122. }
  123. return lfs_bd_erase(lfs, *block);
  124. }
  125. /// Index list operations ///
  126. // Next index offset
  127. static lfs_off_t lfs_indexnext(lfs_t *lfs, lfs_off_t ioff) {
  128. ioff += 1;
  129. while (ioff % lfs->words == 0) {
  130. ioff += lfs_min(lfs_ctz(ioff/lfs->words + 1), lfs->words-1) + 1;
  131. }
  132. return ioff;
  133. }
  134. static lfs_off_t lfs_indexfrom(lfs_t *lfs, lfs_off_t off) {
  135. lfs_off_t i = 0;
  136. while (off > lfs->cfg->block_size) {
  137. i = lfs_indexnext(lfs, i);
  138. off -= lfs->cfg->block_size;
  139. }
  140. return i;
  141. }
  142. // Find index in index chain given its index offset
  143. static int lfs_index_find(lfs_t *lfs, lfs_block_t head,
  144. lfs_size_t icount, lfs_off_t ioff, lfs_block_t *block) {
  145. lfs_off_t iitarget = ioff / lfs->words;
  146. lfs_off_t iicurrent = (icount-1) / lfs->words;
  147. while (iitarget != iicurrent) {
  148. lfs_size_t skip = lfs_min(
  149. lfs_min(lfs_ctz(iicurrent+1), lfs->words-1),
  150. lfs_npw2((iitarget ^ iicurrent)+1)-1);
  151. int err = lfs_bd_read(lfs, head, 4*skip, 4, &head);
  152. if (err) {
  153. return err;
  154. }
  155. iicurrent -= 1 << skip;
  156. }
  157. return lfs_bd_read(lfs, head, 4*(ioff % lfs->words), 4, block);
  158. }
  159. // Append index to index chain, updates head and icount
  160. static int lfs_index_append(lfs_t *lfs, lfs_block_t *headp,
  161. lfs_size_t *icountp, lfs_block_t block) {
  162. lfs_block_t head = *headp;
  163. lfs_size_t ioff = *icountp - 1;
  164. ioff += 1;
  165. while (ioff % lfs->words == 0) {
  166. lfs_block_t nhead;
  167. int err = lfs_alloc_erased(lfs, &nhead);
  168. if (err) {
  169. return err;
  170. }
  171. lfs_off_t skips = lfs_min(
  172. lfs_ctz(ioff/lfs->words + 1), lfs->words-2) + 1;
  173. for (lfs_off_t i = 0; i < skips; i++) {
  174. err = lfs_bd_prog(lfs, nhead, 4*i, 4, &head);
  175. if (err) {
  176. return err;
  177. }
  178. if (head && i != skips-1) {
  179. err = lfs_bd_read(lfs, head, 4*i, 4, &head);
  180. if (err) {
  181. return err;
  182. }
  183. }
  184. }
  185. ioff += skips;
  186. head = nhead;
  187. }
  188. int err = lfs_bd_prog(lfs, head, 4*(ioff % lfs->words), 4, &block);
  189. if (err) {
  190. return err;
  191. }
  192. *headp = head;
  193. *icountp = ioff + 1;
  194. return 0;
  195. }
  196. static int lfs_index_traverse(lfs_t *lfs, lfs_block_t head,
  197. lfs_size_t icount, int (*cb)(void*, lfs_block_t), void *data) {
  198. lfs_off_t iicurrent = (icount-1) / lfs->words;
  199. while (iicurrent > 0) {
  200. int err = cb(data, head);
  201. if (err) {
  202. return err;
  203. }
  204. lfs_size_t skip = lfs_min(lfs_ctz(iicurrent+1), lfs->words-1);
  205. for (lfs_off_t i = skip; i < lfs->words; i++) {
  206. lfs_block_t block;
  207. int err = lfs_bd_read(lfs, head, 4*i, 4, &block);
  208. if (err) {
  209. return err;
  210. }
  211. err = cb(data, block);
  212. if (err) {
  213. return err;
  214. }
  215. }
  216. err = lfs_bd_read(lfs, head, 0, 4, &head);
  217. if (err) {
  218. return err;
  219. }
  220. iicurrent -= 1;
  221. }
  222. int err = cb(data, head);
  223. if (err) {
  224. return err;
  225. }
  226. for (lfs_off_t i = 0; i < lfs->words; i++) {
  227. lfs_block_t block;
  228. int err = lfs_bd_read(lfs, head, 4*i, 4, &block);
  229. if (err) {
  230. return err;
  231. }
  232. err = cb(data, block);
  233. if (err) {
  234. return err;
  235. }
  236. }
  237. return 0;
  238. }
  239. /// Metadata pair and directory operations ///
  240. static inline void lfs_pairswap(lfs_block_t pair[2]) {
  241. lfs_block_t t = pair[0];
  242. pair[0] = pair[1];
  243. pair[1] = t;
  244. }
  245. static inline bool lfs_pairisnull(const lfs_block_t pair[2]) {
  246. return !pair[0] || !pair[1];
  247. }
  248. static inline int lfs_paircmp(
  249. const lfs_block_t paira[2],
  250. const lfs_block_t pairb[2]) {
  251. return !((paira[0] == pairb[0] && paira[1] == pairb[1]) ||
  252. (paira[0] == pairb[1] && paira[1] == pairb[0]));
  253. }
  254. static int lfs_dir_alloc(lfs_t *lfs, lfs_dir_t *dir) {
  255. // Allocate pair of dir blocks
  256. for (int i = 0; i < 2; i++) {
  257. int err = lfs_alloc(lfs, &dir->pair[i]);
  258. if (err) {
  259. return err;
  260. }
  261. }
  262. // Rather than clobbering one of the blocks we just pretend
  263. // the revision may be valid
  264. int err = lfs_bd_read(lfs, dir->pair[0], 0, 4, &dir->d.rev);
  265. if (err) {
  266. return err;
  267. }
  268. // Set defaults
  269. dir->d.rev += 1;
  270. dir->d.size = sizeof(dir->d);
  271. dir->d.tail[0] = 0;
  272. dir->d.tail[1] = 0;
  273. dir->off = sizeof(dir->d);
  274. // Don't write out yet, let caller take care of that
  275. return 0;
  276. }
  277. static int lfs_dir_fetch(lfs_t *lfs,
  278. lfs_dir_t *dir, const lfs_block_t pair[2]) {
  279. // copy out pair, otherwise may be aliasing dir
  280. const lfs_block_t tpair[2] = {pair[0], pair[1]};
  281. bool valid = false;
  282. // check both blocks for the most recent revision
  283. for (int i = 0; i < 2; i++) {
  284. struct lfs_disk_dir test;
  285. int err = lfs_bd_read(lfs, tpair[i], 0, sizeof(test), &test);
  286. if (err) {
  287. return err;
  288. }
  289. if (valid && lfs_scmp(test.rev, dir->d.rev) < 0) {
  290. continue;
  291. }
  292. uint32_t crc = 0xffffffff;
  293. crc = lfs_crc(crc, sizeof(test), &test);
  294. for (lfs_off_t j = sizeof(test); j < lfs->cfg->block_size; j += 4) {
  295. uint32_t word;
  296. int err = lfs_bd_read(lfs, tpair[i], j, 4, &word);
  297. if (err) {
  298. return err;
  299. }
  300. crc = lfs_crc(crc, 4, &word);
  301. }
  302. if (crc != 0) {
  303. continue;
  304. }
  305. valid = true;
  306. // setup dir in case it's valid
  307. dir->pair[0] = tpair[(i+0) % 2];
  308. dir->pair[1] = tpair[(i+1) % 2];
  309. dir->off = sizeof(dir->d);
  310. dir->d = test;
  311. }
  312. if (!valid) {
  313. LFS_ERROR("Corrupted dir pair at %d %d", tpair[0], tpair[1]);
  314. return LFS_ERROR_CORRUPT;
  315. }
  316. return 0;
  317. }
  318. static int lfs_dir_commit(lfs_t *lfs, lfs_dir_t *dir,
  319. const lfs_entry_t *entry, const void *data) {
  320. dir->d.rev += 1;
  321. lfs_pairswap(dir->pair);
  322. int err = lfs_bd_erase(lfs, dir->pair[0]);
  323. if (err) {
  324. return err;
  325. }
  326. uint32_t crc = 0xffffffff;
  327. crc = lfs_crc(crc, sizeof(dir->d), &dir->d);
  328. err = lfs_bd_prog(lfs, dir->pair[0], 0, sizeof(dir->d), &dir->d);
  329. if (err) {
  330. return err;
  331. }
  332. lfs_off_t off = sizeof(dir->d);
  333. lfs_size_t size = 0x7fffffff & dir->d.size;
  334. while (off < size) {
  335. if (entry && off == entry->off) {
  336. crc = lfs_crc(crc, sizeof(entry->d), &entry->d);
  337. int err = lfs_bd_prog(lfs, dir->pair[0],
  338. off, sizeof(entry->d), &entry->d);
  339. if (err) {
  340. return err;
  341. }
  342. off += sizeof(entry->d);
  343. if (data) {
  344. crc = lfs_crc(crc, entry->d.len - sizeof(entry->d), data);
  345. int err = lfs_bd_prog(lfs, dir->pair[0],
  346. off, entry->d.len - sizeof(entry->d), data);
  347. if (err) {
  348. return err;
  349. }
  350. off += entry->d.len - sizeof(entry->d);
  351. }
  352. } else {
  353. uint8_t data;
  354. int err = lfs_bd_read(lfs, dir->pair[1], off, 1, &data);
  355. if (err) {
  356. return err;
  357. }
  358. crc = lfs_crc(crc, 1, &data);
  359. err = lfs_bd_prog(lfs, dir->pair[0], off, 1, &data);
  360. if (err) {
  361. return err;
  362. }
  363. off += 1;
  364. }
  365. }
  366. while (off < lfs->cfg->block_size-4) {
  367. uint8_t data;
  368. int err = lfs_bd_read(lfs, dir->pair[0], off, 1, &data);
  369. if (err) {
  370. return err;
  371. }
  372. crc = lfs_crc(crc, 1, &data);
  373. off += 1;
  374. }
  375. err = lfs_bd_prog(lfs, dir->pair[0], lfs->cfg->block_size-4, 4, &crc);
  376. if (err) {
  377. return err;
  378. }
  379. return lfs_bd_sync(lfs);
  380. }
  381. static int lfs_dir_shift(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) {
  382. dir->d.rev += 1;
  383. dir->d.size -= entry->d.len;
  384. lfs_pairswap(dir->pair);
  385. int err = lfs_bd_erase(lfs, dir->pair[0]);
  386. if (err) {
  387. return err;
  388. }
  389. uint32_t crc = 0xffffffff;
  390. crc = lfs_crc(crc, sizeof(dir->d), &dir->d);
  391. err = lfs_bd_prog(lfs, dir->pair[0], 0, sizeof(dir->d), &dir->d);
  392. if (err) {
  393. return err;
  394. }
  395. lfs_off_t woff = sizeof(dir->d);
  396. lfs_off_t roff = sizeof(dir->d);
  397. lfs_size_t size = 0x7fffffff & dir->d.size;
  398. while (woff < size) {
  399. if (roff == entry->off) {
  400. roff += entry->d.len;
  401. } else {
  402. uint8_t data;
  403. int err = lfs_bd_read(lfs, dir->pair[1], roff, 1, &data);
  404. if (err) {
  405. return err;
  406. }
  407. crc = lfs_crc(crc, 1, (void*)&data);
  408. err = lfs_bd_prog(lfs, dir->pair[0], woff, 1, &data);
  409. if (err) {
  410. return err;
  411. }
  412. woff += 1;
  413. roff += 1;
  414. }
  415. }
  416. while (woff < lfs->cfg->block_size-4) {
  417. uint8_t data;
  418. int err = lfs_bd_read(lfs, dir->pair[0], woff, 1, &data);
  419. if (err) {
  420. return err;
  421. }
  422. crc = lfs_crc(crc, 1, &data);
  423. woff += 1;
  424. }
  425. err = lfs_bd_prog(lfs, dir->pair[0], lfs->cfg->block_size-4, 4, &crc);
  426. if (err) {
  427. return err;
  428. }
  429. return lfs_bd_sync(lfs);
  430. }
  431. static int lfs_dir_append(lfs_t *lfs, lfs_dir_t *dir,
  432. lfs_entry_t *entry, const void *data) {
  433. // check if we fit, if top bit is set we do not and move on
  434. while (true) {
  435. if (dir->d.size + entry->d.len <= lfs->cfg->block_size - 4) {
  436. entry->pair[0] = dir->pair[0];
  437. entry->pair[1] = dir->pair[1];
  438. entry->off = dir->d.size;
  439. dir->d.size += entry->d.len;
  440. return lfs_dir_commit(lfs, dir, entry, data);
  441. }
  442. if (!(0x80000000 & dir->d.size)) {
  443. lfs_dir_t newdir;
  444. int err = lfs_dir_alloc(lfs, &newdir);
  445. if (err) {
  446. return err;
  447. }
  448. newdir.d.tail[0] = dir->d.tail[0];
  449. newdir.d.tail[1] = dir->d.tail[1];
  450. entry->pair[0] = newdir.pair[0];
  451. entry->pair[1] = newdir.pair[1];
  452. entry->off = newdir.d.size;
  453. newdir.d.size += entry->d.len;
  454. err = lfs_dir_commit(lfs, &newdir, entry, data);
  455. if (err) {
  456. return err;
  457. }
  458. dir->d.size |= 0x80000000;
  459. dir->d.tail[0] = newdir.pair[0];
  460. dir->d.tail[1] = newdir.pair[1];
  461. return lfs_dir_commit(lfs, dir, NULL, NULL);
  462. }
  463. int err = lfs_dir_fetch(lfs, dir, dir->d.tail);
  464. if (err) {
  465. return err;
  466. }
  467. }
  468. }
  469. static int lfs_dir_remove(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) {
  470. // either shift out the one entry or remove the whole dir block
  471. if (dir->d.size == sizeof(dir->d)) {
  472. lfs_dir_t pdir;
  473. int err = lfs_dir_fetch(lfs, &pdir, lfs->root);
  474. if (err) {
  475. return err;
  476. }
  477. while (lfs_paircmp(pdir.d.tail, dir->pair) != 0) {
  478. int err = lfs_dir_fetch(lfs, &pdir, pdir.d.tail);
  479. if (err) {
  480. return err;
  481. }
  482. }
  483. // TODO easier check for head block? (common case)
  484. if (!(pdir.d.size & 0x80000000)) {
  485. return lfs_dir_shift(lfs, dir, entry);
  486. } else {
  487. pdir.d.tail[0] = dir->d.tail[0];
  488. pdir.d.tail[1] = dir->d.tail[1];
  489. return lfs_dir_commit(lfs, &pdir, NULL, NULL);
  490. }
  491. } else {
  492. return lfs_dir_shift(lfs, dir, entry);
  493. }
  494. }
  495. static int lfs_dir_next(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) {
  496. while (true) {
  497. if ((0x7fffffff & dir->d.size) - dir->off < sizeof(entry->d)) {
  498. if (!(dir->d.size >> 31)) {
  499. entry->pair[0] = dir->pair[0];
  500. entry->pair[1] = dir->pair[1];
  501. entry->off = dir->off;
  502. return LFS_ERROR_NO_ENTRY;
  503. }
  504. int err = lfs_dir_fetch(lfs, dir, dir->d.tail);
  505. if (err) {
  506. return err;
  507. }
  508. dir->off = sizeof(dir->d);
  509. }
  510. int err = lfs_bd_read(lfs, dir->pair[0], dir->off,
  511. sizeof(entry->d), &entry->d);
  512. if (err) {
  513. return err;
  514. }
  515. dir->off += entry->d.len;
  516. if ((0xff & entry->d.type) == LFS_TYPE_REG ||
  517. (0xff & entry->d.type) == LFS_TYPE_DIR) {
  518. entry->pair[0] = dir->pair[0];
  519. entry->pair[1] = dir->pair[1];
  520. entry->off = dir->off - entry->d.len;
  521. return 0;
  522. }
  523. }
  524. }
  525. static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir,
  526. lfs_entry_t *entry, const char **path) {
  527. const char *pathname = *path;
  528. size_t pathlen;
  529. while (true) {
  530. nextname:
  531. // skip slashes
  532. pathname += strspn(pathname, "/");
  533. pathlen = strcspn(pathname, "/");
  534. // skip '.' and root '..'
  535. if ((pathlen == 1 && memcmp(pathname, ".", 1) == 0) ||
  536. (pathlen == 2 && memcmp(pathname, "..", 2) == 0)) {
  537. pathname += pathlen;
  538. goto nextname;
  539. }
  540. // skip if matched by '..' in name
  541. const char *suffix = pathname + pathlen;
  542. size_t sufflen;
  543. int depth = 1;
  544. while (true) {
  545. suffix += strspn(suffix, "/");
  546. sufflen = strcspn(suffix, "/");
  547. if (sufflen == 0) {
  548. break;
  549. }
  550. if (sufflen == 2 && memcmp(suffix, "..", 2) == 0) {
  551. depth -= 1;
  552. if (depth == 0) {
  553. pathname = suffix + sufflen;
  554. goto nextname;
  555. }
  556. } else {
  557. depth += 1;
  558. }
  559. suffix += sufflen;
  560. }
  561. // find path
  562. while (true) {
  563. int err = lfs_dir_next(lfs, dir, entry);
  564. if (err) {
  565. return err;
  566. }
  567. if (entry->d.len - sizeof(entry->d) != pathlen) {
  568. continue;
  569. }
  570. int ret = lfs_bd_cmp(lfs, dir->pair[0],
  571. entry->off + sizeof(entry->d), pathlen, pathname);
  572. if (ret < 0) {
  573. return ret;
  574. }
  575. // Found match
  576. if (ret == true) {
  577. break;
  578. }
  579. }
  580. pathname += pathlen;
  581. pathname += strspn(pathname, "/");
  582. if (pathname[0] == '\0') {
  583. return 0;
  584. }
  585. // continue on if we hit a directory
  586. if (entry->d.type != LFS_TYPE_DIR) {
  587. return LFS_ERROR_NOT_DIR;
  588. }
  589. int err = lfs_dir_fetch(lfs, dir, entry->d.u.dir);
  590. if (err) {
  591. return err;
  592. }
  593. *path = pathname;
  594. }
  595. return 0;
  596. }
  597. /// Top level directory operations ///
  598. int lfs_mkdir(lfs_t *lfs, const char *path) {
  599. // fetch parent directory
  600. lfs_dir_t cwd;
  601. int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
  602. if (err) {
  603. return err;
  604. }
  605. lfs_entry_t entry;
  606. err = lfs_dir_find(lfs, &cwd, &entry, &path);
  607. if (err != LFS_ERROR_NO_ENTRY) {
  608. return err ? err : LFS_ERROR_EXISTS;
  609. }
  610. // Build up new directory
  611. lfs_dir_t dir;
  612. err = lfs_dir_alloc(lfs, &dir);
  613. if (err) {
  614. return err;
  615. }
  616. dir.d.tail[0] = cwd.d.tail[0];
  617. dir.d.tail[1] = cwd.d.tail[1];
  618. err = lfs_dir_commit(lfs, &dir, NULL, NULL);
  619. if (err) {
  620. return err;
  621. }
  622. entry.d.type = LFS_TYPE_DIR;
  623. entry.d.len = sizeof(entry.d) + strlen(path);
  624. entry.d.u.dir[0] = dir.pair[0];
  625. entry.d.u.dir[1] = dir.pair[1];
  626. cwd.d.tail[0] = dir.pair[0];
  627. cwd.d.tail[1] = dir.pair[1];
  628. return lfs_dir_append(lfs, &cwd, &entry, path);
  629. }
  630. int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
  631. dir->pair[0] = lfs->root[0];
  632. dir->pair[1] = lfs->root[1];
  633. int err = lfs_dir_fetch(lfs, dir, dir->pair);
  634. if (err) {
  635. return err;
  636. } else if (strcmp(path, "/") == 0) {
  637. // special offset for '.' and '..'
  638. dir->off = sizeof(dir->d) - 2;
  639. return 0;
  640. }
  641. lfs_entry_t entry;
  642. err = lfs_dir_find(lfs, dir, &entry, &path);
  643. if (err) {
  644. return err;
  645. } else if (entry.d.type != LFS_TYPE_DIR) {
  646. return LFS_ERROR_NOT_DIR;
  647. }
  648. err = lfs_dir_fetch(lfs, dir, entry.d.u.dir);
  649. if (err) {
  650. return err;
  651. }
  652. // special offset for '.' and '..'
  653. dir->off = sizeof(dir->d) - 2;
  654. return 0;
  655. }
  656. int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir) {
  657. // Do nothing, dir is always synchronized
  658. return 0;
  659. }
  660. int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info) {
  661. memset(info, 0, sizeof(*info));
  662. if (dir->off == sizeof(dir->d) - 2) {
  663. info->type = LFS_TYPE_DIR;
  664. strcpy(info->name, ".");
  665. dir->off += 1;
  666. return 1;
  667. } else if (dir->off == sizeof(dir->d) - 1) {
  668. info->type = LFS_TYPE_DIR;
  669. strcpy(info->name, "..");
  670. dir->off += 1;
  671. return 1;
  672. }
  673. lfs_entry_t entry;
  674. int err = lfs_dir_next(lfs, dir, &entry);
  675. if (err) {
  676. return (err == LFS_ERROR_NO_ENTRY) ? 0 : err;
  677. }
  678. info->type = entry.d.type & 0xff;
  679. if (info->type == LFS_TYPE_REG) {
  680. info->size = entry.d.u.file.size;
  681. }
  682. err = lfs_bd_read(lfs, dir->pair[0], entry.off + sizeof(entry.d),
  683. entry.d.len - sizeof(entry.d), info->name);
  684. if (err) {
  685. return err;
  686. }
  687. return 1;
  688. }
  689. /// Top level file operations ///
  690. int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
  691. const char *path, int flags) {
  692. // Allocate entry for file if it doesn't exist
  693. // TODO check open files
  694. lfs_dir_t cwd;
  695. int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
  696. if (err) {
  697. return err;
  698. }
  699. err = lfs_dir_find(lfs, &cwd, &file->entry, &path);
  700. if (err && !((flags & LFS_O_CREAT) && err == LFS_ERROR_NO_ENTRY)) {
  701. return err;
  702. } else if (err != LFS_ERROR_NO_ENTRY &&
  703. file->entry.d.type == LFS_TYPE_DIR) {
  704. return LFS_ERROR_IS_DIR;
  705. }
  706. if ((flags & LFS_O_CREAT) && err == LFS_ERROR_NO_ENTRY) {
  707. // create entry to remember name
  708. file->entry.d.type = 1;
  709. file->entry.d.len = sizeof(file->entry.d) + strlen(path);
  710. file->entry.d.u.file.head = 0;
  711. file->entry.d.u.file.size = 0;
  712. int err = lfs_dir_append(lfs, &cwd, &file->entry, path);
  713. if (err) {
  714. return err;
  715. }
  716. }
  717. file->head = file->entry.d.u.file.head;
  718. file->size = file->entry.d.u.file.size;
  719. file->windex = lfs_indexfrom(lfs, file->size);
  720. file->rblock = 0;
  721. file->rindex = 0;
  722. file->roff = 0;
  723. // TODO do this lazily in write?
  724. // TODO cow the head i/d block
  725. if (file->size < lfs->cfg->block_size) {
  726. file->wblock = file->head;
  727. } else {
  728. int err = lfs_index_find(lfs, file->head, file->windex,
  729. file->windex, &file->wblock);
  730. if (err) {
  731. return err;
  732. }
  733. }
  734. return 0;
  735. }
  736. int lfs_file_close(lfs_t *lfs, lfs_file_t *file) {
  737. // Store file
  738. lfs_dir_t cwd;
  739. int err = lfs_dir_fetch(lfs, &cwd, file->entry.pair);
  740. if (err) {
  741. return err;
  742. }
  743. file->entry.d.u.file.head = file->head;
  744. file->entry.d.u.file.size = file->size;
  745. return lfs_dir_commit(lfs, &cwd, &file->entry, NULL);
  746. }
  747. lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
  748. const void *buffer, lfs_size_t size) {
  749. const uint8_t *data = buffer;
  750. lfs_size_t nsize = size;
  751. while (nsize > 0) {
  752. lfs_off_t woff = file->size % lfs->cfg->block_size;
  753. if (file->size == 0) {
  754. int err = lfs_alloc_erased(lfs, &file->wblock);
  755. if (err) {
  756. return err;
  757. }
  758. file->head = file->wblock;
  759. file->windex = 0;
  760. } else if (woff == 0) {
  761. int err = lfs_alloc_erased(lfs, &file->wblock);
  762. if (err) {
  763. return err;
  764. }
  765. err = lfs_index_append(lfs, &file->head,
  766. &file->windex, file->wblock);
  767. if (err) {
  768. return err;
  769. }
  770. }
  771. lfs_size_t diff = lfs_min(nsize, lfs->cfg->block_size - woff);
  772. int err = lfs_bd_prog(lfs, file->wblock, woff, diff, data);
  773. if (err) {
  774. return err;
  775. }
  776. file->size += diff;
  777. data += diff;
  778. nsize -= diff;
  779. }
  780. return size;
  781. }
  782. lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
  783. void *buffer, lfs_size_t size) {
  784. uint8_t *data = buffer;
  785. lfs_size_t nsize = size;
  786. while (nsize > 0 && file->roff < file->size) {
  787. lfs_off_t roff = file->roff % lfs->cfg->block_size;
  788. // TODO cache index blocks
  789. if (file->size < lfs->cfg->block_size) {
  790. file->rblock = file->head;
  791. } else if (roff == 0) {
  792. int err = lfs_index_find(lfs, file->head, file->windex,
  793. file->rindex, &file->rblock);
  794. if (err) {
  795. return err;
  796. }
  797. file->rindex = lfs_indexnext(lfs, file->rindex);
  798. }
  799. lfs_size_t diff = lfs_min(
  800. lfs_min(nsize, file->size-file->roff),
  801. lfs->cfg->block_size - roff);
  802. int err = lfs_bd_read(lfs, file->rblock, roff, diff, data);
  803. if (err) {
  804. return err;
  805. }
  806. file->roff += diff;
  807. data += diff;
  808. nsize -= diff;
  809. }
  810. return size - nsize;
  811. }
  812. /// Generic filesystem operations ///
  813. int lfs_format(lfs_t *lfs, const struct lfs_config *config) {
  814. lfs->cfg = config;
  815. lfs->words = lfs->cfg->block_size / sizeof(uint32_t);
  816. // Create free list
  817. lfs->free.begin = 0;
  818. lfs->free.end = lfs->cfg->block_count-1;
  819. // Create superblock dir
  820. lfs_dir_t superdir;
  821. int err = lfs_dir_alloc(lfs, &superdir);
  822. if (err) {
  823. return err;
  824. }
  825. // Write root directory
  826. lfs_dir_t root;
  827. err = lfs_dir_alloc(lfs, &root);
  828. if (err) {
  829. return err;
  830. }
  831. err = lfs_dir_commit(lfs, &root, NULL, NULL);
  832. if (err) {
  833. return err;
  834. }
  835. lfs->root[0] = root.pair[0];
  836. lfs->root[1] = root.pair[1];
  837. // Write superblocks
  838. lfs_superblock_t superblock = {
  839. .off = sizeof(superdir.d),
  840. .d.type = LFS_TYPE_SUPERBLOCK,
  841. .d.len = sizeof(superblock.d),
  842. .d.version = 0x00000001,
  843. .d.magic = {"littlefs"},
  844. .d.block_size = lfs->cfg->block_size,
  845. .d.block_count = lfs->cfg->block_count,
  846. .d.root = {lfs->root[0], lfs->root[1]},
  847. };
  848. superdir.d.tail[0] = root.pair[0];
  849. superdir.d.tail[1] = root.pair[1];
  850. superdir.d.size += sizeof(superdir.d);
  851. for (int i = 0; i < 2; i++) {
  852. // Write both pairs for extra safety, do some finagling to pretend
  853. // the superblock is an entry
  854. int err = lfs_dir_commit(lfs, &superdir,
  855. (const lfs_entry_t*)&superblock,
  856. (const struct lfs_disk_entry*)&superblock.d + 1);
  857. if (err) {
  858. LFS_ERROR("Failed to write superblock at %d", superdir.pair[0]);
  859. return err;
  860. }
  861. }
  862. // sanity check that fetch works
  863. return lfs_dir_fetch(lfs, &superdir, (const lfs_block_t[2]){0, 1});
  864. }
  865. int lfs_mount(lfs_t *lfs, const struct lfs_config *config) {
  866. lfs->cfg = config;
  867. lfs->words = lfs->cfg->block_size / sizeof(uint32_t);
  868. lfs_dir_t dir;
  869. lfs_superblock_t superblock;
  870. int err = lfs_dir_fetch(lfs, &dir, (const lfs_block_t[2]){0, 1});
  871. if (!err) {
  872. err = lfs_bd_read(lfs, dir.pair[0],
  873. sizeof(dir.d), sizeof(superblock.d), &superblock.d);
  874. }
  875. if (err == LFS_ERROR_CORRUPT ||
  876. memcmp(superblock.d.magic, "littlefs", 8) != 0) {
  877. LFS_ERROR("Invalid superblock at %d %d", dir.pair[0], dir.pair[1]);
  878. return LFS_ERROR_CORRUPT;
  879. }
  880. if (superblock.d.version > 0x0000ffff) {
  881. LFS_ERROR("Invalid version %d.%d\n",
  882. 0xffff & (superblock.d.version >> 16),
  883. 0xffff & (superblock.d.version >> 0));
  884. }
  885. lfs->root[0] = superblock.d.root[0];
  886. lfs->root[1] = superblock.d.root[1];
  887. return err;
  888. }
  889. int lfs_unmount(lfs_t *lfs) {
  890. // Do nothing for now
  891. return 0;
  892. }
  893. int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data) {
  894. // iterate over metadata pairs
  895. lfs_dir_t dir;
  896. lfs_file_t file;
  897. lfs_block_t cwd[2] = {0, 1};
  898. while (true) {
  899. for (int i = 0; i < 2; i++) {
  900. int err = cb(data, cwd[i]);
  901. if (err) {
  902. return err;
  903. }
  904. }
  905. int err = lfs_dir_fetch(lfs, &dir, cwd);
  906. if (err) {
  907. return err;
  908. }
  909. // iterate over contents
  910. while ((0x7fffffff & dir.d.size) >= dir.off + sizeof(file.entry.d)) {
  911. int err = lfs_bd_read(lfs, dir.pair[0], dir.off,
  912. sizeof(file.entry.d), &file.entry.d);
  913. if (err) {
  914. return err;
  915. }
  916. dir.off += file.entry.d.len;
  917. if ((0xf & file.entry.d.type) == LFS_TYPE_REG) {
  918. if (file.entry.d.u.file.size < lfs->cfg->block_size) {
  919. int err = cb(data, file.entry.d.u.file.head);
  920. if (err) {
  921. return err;
  922. }
  923. } else {
  924. int err = lfs_index_traverse(lfs,
  925. file.entry.d.u.file.head,
  926. lfs_indexfrom(lfs, file.entry.d.u.file.size),
  927. cb, data);
  928. if (err) {
  929. return err;
  930. }
  931. }
  932. }
  933. }
  934. cwd[0] = dir.d.tail[0];
  935. cwd[1] = dir.d.tail[1];
  936. if (!cwd[0]) {
  937. return 0;
  938. }
  939. }
  940. }
  941. static int lfs_parent(lfs_t *lfs, const lfs_block_t dir[2]) {
  942. // iterate over all directory directory entries
  943. lfs_dir_t parent = {
  944. .d.tail[0] = lfs->root[0],
  945. .d.tail[1] = lfs->root[1],
  946. };
  947. while (parent.d.tail[0]) {
  948. lfs_entry_t entry;
  949. int err = lfs_dir_fetch(lfs, &parent, parent.d.tail);
  950. if (err) {
  951. return err;
  952. }
  953. while (true) {
  954. int err = lfs_dir_next(lfs, &parent, &entry);
  955. if (err && err != LFS_ERROR_NO_ENTRY) {
  956. return err;
  957. }
  958. if (err == LFS_ERROR_NO_ENTRY) {
  959. break;
  960. }
  961. if ((0xf & entry.d.type) == LFS_TYPE_DIR &&
  962. lfs_paircmp(entry.d.u.dir, dir) == 0) {
  963. return true;
  964. }
  965. }
  966. }
  967. return false;
  968. }
  969. int lfs_deorphan(lfs_t *lfs) {
  970. // iterate over all directories
  971. lfs_dir_t pdir;
  972. lfs_dir_t cdir;
  973. // skip root
  974. int err = lfs_dir_fetch(lfs, &pdir, lfs->root);
  975. if (err) {
  976. return err;
  977. }
  978. while (pdir.d.tail[0]) {
  979. int err = lfs_dir_fetch(lfs, &cdir, pdir.d.tail);
  980. if (err) {
  981. return err;
  982. }
  983. // check if we have a parent
  984. int parent = lfs_parent(lfs, pdir.d.tail);
  985. if (parent < 0) {
  986. return parent;
  987. }
  988. if (!parent) {
  989. // we are an orphan
  990. LFS_INFO("Orphan %d %d", pdir.d.tail[0], pdir.d.tail[1]);
  991. pdir.d.tail[0] = cdir.d.tail[0];
  992. pdir.d.tail[1] = cdir.d.tail[1];
  993. err = lfs_dir_commit(lfs, &pdir, NULL, NULL);
  994. if (err) {
  995. return err;
  996. }
  997. break;
  998. }
  999. memcpy(&pdir, &cdir, sizeof(pdir));
  1000. }
  1001. return 0;
  1002. }
  1003. int lfs_remove(lfs_t *lfs, const char *path) {
  1004. lfs_dir_t cwd;
  1005. int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
  1006. if (err) {
  1007. return err;
  1008. }
  1009. lfs_entry_t entry;
  1010. err = lfs_dir_find(lfs, &cwd, &entry, &path);
  1011. if (err) {
  1012. return err;
  1013. }
  1014. lfs_dir_t dir;
  1015. if (entry.d.type == LFS_TYPE_DIR) {
  1016. // must be empty before removal, checking size
  1017. // without masking top bit checks for any case where
  1018. // dir is not empty
  1019. int err = lfs_dir_fetch(lfs, &dir, entry.d.u.dir);
  1020. if (err) {
  1021. return err;
  1022. } else if (dir.d.size != sizeof(dir.d)) {
  1023. return LFS_ERROR_INVALID;
  1024. }
  1025. }
  1026. // remove the entry
  1027. err = lfs_dir_remove(lfs, &cwd, &entry);
  1028. if (err) {
  1029. return err;
  1030. }
  1031. // if we were a directory, just run a deorphan step, this should
  1032. // collect us, although is expensive
  1033. if (entry.d.type == LFS_TYPE_DIR) {
  1034. int err = lfs_deorphan(lfs);
  1035. if (err) {
  1036. return err;
  1037. }
  1038. }
  1039. return 0;
  1040. }
  1041. int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
  1042. // find old entry
  1043. lfs_dir_t oldcwd;
  1044. int err = lfs_dir_fetch(lfs, &oldcwd, lfs->root);
  1045. if (err) {
  1046. return err;
  1047. }
  1048. lfs_entry_t oldentry;
  1049. err = lfs_dir_find(lfs, &oldcwd, &oldentry, &oldpath);
  1050. if (err) {
  1051. return err;
  1052. }
  1053. // allocate new entry
  1054. lfs_dir_t newcwd;
  1055. err = lfs_dir_fetch(lfs, &newcwd, lfs->root);
  1056. if (err) {
  1057. return err;
  1058. }
  1059. lfs_entry_t preventry;
  1060. err = lfs_dir_find(lfs, &newcwd, &preventry, &newpath);
  1061. if (err && err != LFS_ERROR_NO_ENTRY) {
  1062. return err;
  1063. }
  1064. bool prevexists = (err != LFS_ERROR_NO_ENTRY);
  1065. // must have same type
  1066. if (prevexists && preventry.d.type != oldentry.d.type) {
  1067. return LFS_ERROR_INVALID;
  1068. }
  1069. lfs_dir_t dir;
  1070. if (prevexists && preventry.d.type == LFS_TYPE_DIR) {
  1071. // must be empty before removal, checking size
  1072. // without masking top bit checks for any case where
  1073. // dir is not empty
  1074. int err = lfs_dir_fetch(lfs, &dir, preventry.d.u.dir);
  1075. if (err) {
  1076. return err;
  1077. } else if (dir.d.size != sizeof(dir.d)) {
  1078. return LFS_ERROR_INVALID;
  1079. }
  1080. }
  1081. // move to new location
  1082. lfs_entry_t newentry = preventry;
  1083. newentry.d = oldentry.d;
  1084. newentry.d.len = sizeof(newentry.d) + strlen(newpath);
  1085. if (prevexists) {
  1086. int err = lfs_dir_commit(lfs, &newcwd, &newentry, newpath);
  1087. if (err) {
  1088. return err;
  1089. }
  1090. } else {
  1091. int err = lfs_dir_append(lfs, &newcwd, &newentry, newpath);
  1092. if (err) {
  1093. return err;
  1094. }
  1095. }
  1096. // fetch again in case newcwd == oldcwd
  1097. // TODO handle this better?
  1098. err = lfs_dir_fetch(lfs, &oldcwd, oldcwd.pair);
  1099. if (err) {
  1100. return err;
  1101. }
  1102. err = lfs_dir_find(lfs, &oldcwd, &oldentry, &oldpath);
  1103. if (err) {
  1104. return err;
  1105. }
  1106. // remove from old location
  1107. err = lfs_dir_remove(lfs, &oldcwd, &oldentry);
  1108. if (err) {
  1109. return err;
  1110. }
  1111. // if we were a directory, just run a deorphan step, this should
  1112. // collect us, although is expensive
  1113. if (prevexists && preventry.d.type == LFS_TYPE_DIR) {
  1114. int err = lfs_deorphan(lfs);
  1115. if (err) {
  1116. return err;
  1117. }
  1118. }
  1119. return 0;
  1120. }
  1121. int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) {
  1122. lfs_dir_t cwd;
  1123. int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
  1124. if (err) {
  1125. return err;
  1126. }
  1127. lfs_entry_t entry;
  1128. err = lfs_dir_find(lfs, &cwd, &entry, &path);
  1129. if (err) {
  1130. return err;
  1131. }
  1132. // TODO abstract out info assignment
  1133. memset(info, 0, sizeof(*info));
  1134. info->type = entry.d.type & 0xff;
  1135. if (info->type == LFS_TYPE_REG) {
  1136. info->size = entry.d.u.file.size;
  1137. }
  1138. err = lfs_bd_read(lfs, cwd.pair[0], entry.off + sizeof(entry.d),
  1139. entry.d.len - sizeof(entry.d), info->name);
  1140. if (err) {
  1141. return err;
  1142. }
  1143. return 0;
  1144. }