Lines Matching full:lfs
7 #include "lfs.h"
14 static inline void lfs_cache_drop(lfs_t *lfs, lfs_cache_t *rcache) { in lfs_cache_drop() argument
17 (void)lfs; in lfs_cache_drop()
21 static inline void lfs_cache_zero(lfs_t *lfs, lfs_cache_t *pcache) { in lfs_cache_zero() argument
23 memset(pcache->buffer, 0xff, lfs->cfg->cache_size); in lfs_cache_zero()
27 static int lfs_bd_read(lfs_t *lfs, in lfs_bd_read() argument
32 if (block >= lfs->cfg->block_count || in lfs_bd_read()
33 off+size > lfs->cfg->block_size) { in lfs_bd_read()
74 if (size >= hint && off % lfs->cfg->read_size == 0 && in lfs_bd_read()
75 size >= lfs->cfg->read_size) { in lfs_bd_read()
77 diff = lfs_aligndown(diff, lfs->cfg->read_size); in lfs_bd_read()
78 int err = lfs->cfg->read(lfs->cfg, block, off, data, diff); in lfs_bd_read()
90 LFS_ASSERT(block < lfs->cfg->block_count); in lfs_bd_read()
92 rcache->off = lfs_aligndown(off, lfs->cfg->read_size); in lfs_bd_read()
95 lfs_alignup(off+hint, lfs->cfg->read_size), in lfs_bd_read()
96 lfs->cfg->block_size) in lfs_bd_read()
98 lfs->cfg->cache_size); in lfs_bd_read()
99 int err = lfs->cfg->read(lfs->cfg, rcache->block, in lfs_bd_read()
116 static int lfs_bd_cmp(lfs_t *lfs, in lfs_bd_cmp() argument
124 int err = lfs_bd_read(lfs, in lfs_bd_cmp()
139 static int lfs_bd_flush(lfs_t *lfs, in lfs_bd_flush() argument
142 LFS_ASSERT(pcache->block < lfs->cfg->block_count); in lfs_bd_flush()
143 lfs_size_t diff = lfs_alignup(pcache->size, lfs->cfg->prog_size); in lfs_bd_flush()
144 int err = lfs->cfg->prog(lfs->cfg, pcache->block, in lfs_bd_flush()
153 lfs_cache_drop(lfs, rcache); in lfs_bd_flush()
154 int res = lfs_bd_cmp(lfs, in lfs_bd_flush()
166 lfs_cache_zero(lfs, pcache); in lfs_bd_flush()
172 static int lfs_bd_sync(lfs_t *lfs, in lfs_bd_sync() argument
174 lfs_cache_drop(lfs, rcache); in lfs_bd_sync()
176 int err = lfs_bd_flush(lfs, pcache, rcache, validate); in lfs_bd_sync()
181 err = lfs->cfg->sync(lfs->cfg); in lfs_bd_sync()
186 static int lfs_bd_prog(lfs_t *lfs, in lfs_bd_prog() argument
191 LFS_ASSERT(block == LFS_BLOCK_INLINE || block < lfs->cfg->block_count); in lfs_bd_prog()
192 LFS_ASSERT(off + size <= lfs->cfg->block_size); in lfs_bd_prog()
197 off < pcache->off + lfs->cfg->cache_size) { in lfs_bd_prog()
200 lfs->cfg->cache_size - (off-pcache->off)); in lfs_bd_prog()
208 if (pcache->size == lfs->cfg->cache_size) { in lfs_bd_prog()
210 int err = lfs_bd_flush(lfs, pcache, rcache, validate); in lfs_bd_prog()
225 pcache->off = lfs_aligndown(off, lfs->cfg->prog_size); in lfs_bd_prog()
232 static int lfs_bd_erase(lfs_t *lfs, lfs_block_t block) { in lfs_bd_erase() argument
233 LFS_ASSERT(block < lfs->cfg->block_count); in lfs_bd_erase()
234 int err = lfs->cfg->erase(lfs->cfg, block); in lfs_bd_erase()
416 static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir,
418 static int lfs_dir_compact(lfs_t *lfs,
421 static int lfs_file_outline(lfs_t *lfs, lfs_file_t *file);
422 static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file);
423 static void lfs_fs_preporphans(lfs_t *lfs, int8_t orphans);
424 static void lfs_fs_prepmove(lfs_t *lfs,
426 static int lfs_fs_pred(lfs_t *lfs, const lfs_block_t dir[2],
428 static lfs_stag_t lfs_fs_parent(lfs_t *lfs, const lfs_block_t dir[2],
430 static int lfs_fs_relocate(lfs_t *lfs,
432 int lfs_fs_traverseraw(lfs_t *lfs,
435 static int lfs_fs_forceconsistency(lfs_t *lfs);
436 static int lfs_deinit(lfs_t *lfs);
438 static int lfs1_traverse(lfs_t *lfs,
444 lfs_t *lfs = (lfs_t*)p; in lfs_alloc_lookahead() local
445 lfs_block_t off = ((block - lfs->free.off) in lfs_alloc_lookahead()
446 + lfs->cfg->block_count) % lfs->cfg->block_count; in lfs_alloc_lookahead()
448 if (off < lfs->free.size) { in lfs_alloc_lookahead()
449 lfs->free.buffer[off / 32] |= 1U << (off % 32); in lfs_alloc_lookahead()
455 static void lfs_alloc_ack(lfs_t *lfs) { in lfs_alloc_ack() argument
456 lfs->free.ack = lfs->cfg->block_count; in lfs_alloc_ack()
461 static void lfs_alloc_reset(lfs_t *lfs) { in lfs_alloc_reset() argument
462 lfs->free.off = lfs->seed % lfs->cfg->block_size; in lfs_alloc_reset()
463 lfs->free.size = 0; in lfs_alloc_reset()
464 lfs->free.i = 0; in lfs_alloc_reset()
465 lfs_alloc_ack(lfs); in lfs_alloc_reset()
468 static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { in lfs_alloc() argument
470 while (lfs->free.i != lfs->free.size) { in lfs_alloc()
471 lfs_block_t off = lfs->free.i; in lfs_alloc()
472 lfs->free.i += 1; in lfs_alloc()
473 lfs->free.ack -= 1; in lfs_alloc()
475 if (!(lfs->free.buffer[off / 32] & (1U << (off % 32)))) { in lfs_alloc()
477 *block = (lfs->free.off + off) % lfs->cfg->block_count; in lfs_alloc()
481 while (lfs->free.i != lfs->free.size && in lfs_alloc()
482 (lfs->free.buffer[lfs->free.i / 32] in lfs_alloc()
483 & (1U << (lfs->free.i % 32)))) { in lfs_alloc()
484 lfs->free.i += 1; in lfs_alloc()
485 lfs->free.ack -= 1; in lfs_alloc()
493 if (lfs->free.ack == 0) { in lfs_alloc()
495 lfs->free.i + lfs->free.off); in lfs_alloc()
499 lfs->free.off = (lfs->free.off + lfs->free.size) in lfs_alloc()
500 % lfs->cfg->block_count; in lfs_alloc()
501 lfs->free.size = lfs_min(8*lfs->cfg->lookahead_size, lfs->free.ack); in lfs_alloc()
502 lfs->free.i = 0; in lfs_alloc()
505 memset(lfs->free.buffer, 0, lfs->cfg->lookahead_size); in lfs_alloc()
506 int err = lfs_fs_traverseraw(lfs, lfs_alloc_lookahead, lfs, true); in lfs_alloc()
508 lfs_alloc_reset(lfs); in lfs_alloc()
515 static lfs_stag_t lfs_dir_getslice(lfs_t *lfs, const lfs_mdir_t *dir, in lfs_dir_getslice() argument
522 if (lfs_gstate_hasmovehere(&lfs->gdisk, dir->pair) && in lfs_dir_getslice()
524 lfs_tag_id(lfs->gdisk.tag) <= lfs_tag_id(gtag)) { in lfs_dir_getslice()
533 int err = lfs_bd_read(lfs, in lfs_dir_getslice()
534 NULL, &lfs->rcache, sizeof(ntag), in lfs_dir_getslice()
561 err = lfs_bd_read(lfs, in lfs_dir_getslice()
562 NULL, &lfs->rcache, diff, in lfs_dir_getslice()
577 static lfs_stag_t lfs_dir_get(lfs_t *lfs, const lfs_mdir_t *dir, in lfs_dir_get() argument
579 return lfs_dir_getslice(lfs, dir, in lfs_dir_get()
584 static int lfs_dir_getread(lfs_t *lfs, const lfs_mdir_t *dir, in lfs_dir_getread() argument
589 if (off+size > lfs->cfg->block_size) { in lfs_dir_getread()
632 rcache->off = lfs_aligndown(off, lfs->cfg->read_size); in lfs_dir_getread()
633 rcache->size = lfs_min(lfs_alignup(off+hint, lfs->cfg->read_size), in lfs_dir_getread()
634 lfs->cfg->cache_size); in lfs_dir_getread()
635 int err = lfs_dir_getslice(lfs, dir, gmask, gtag, in lfs_dir_getread()
673 static int lfs_dir_traverse(lfs_t *lfs, in lfs_dir_traverse() argument
686 int err = lfs_bd_read(lfs, in lfs_dir_traverse()
687 NULL, &lfs->rcache, sizeof(tag), in lfs_dir_traverse()
716 int filter = lfs_dir_traverse(lfs, in lfs_dir_traverse()
740 int err = lfs_dir_traverse(lfs, in lfs_dir_traverse()
767 static lfs_stag_t lfs_dir_fetchmatch(lfs_t *lfs, in lfs_dir_fetchmatch() argument
777 if (pair[0] >= lfs->cfg->block_count || pair[1] >= lfs->cfg->block_count) { in lfs_dir_fetchmatch()
785 int err = lfs_bd_read(lfs, in lfs_dir_fetchmatch()
786 NULL, &lfs->rcache, sizeof(revs[i]), in lfs_dir_fetchmatch()
822 int err = lfs_bd_read(lfs, in lfs_dir_fetchmatch()
823 NULL, &lfs->rcache, lfs->cfg->block_size, in lfs_dir_fetchmatch()
840 dir->off % lfs->cfg->prog_size == 0); in lfs_dir_fetchmatch()
842 } else if (off + lfs_tag_dsize(tag) > lfs->cfg->block_size) { in lfs_dir_fetchmatch()
852 err = lfs_bd_read(lfs, in lfs_dir_fetchmatch()
853 NULL, &lfs->rcache, lfs->cfg->block_size, in lfs_dir_fetchmatch()
874 lfs->seed ^= crc; in lfs_dir_fetchmatch()
893 err = lfs_bd_read(lfs, in lfs_dir_fetchmatch()
894 NULL, &lfs->rcache, lfs->cfg->block_size, in lfs_dir_fetchmatch()
926 err = lfs_bd_read(lfs, in lfs_dir_fetchmatch()
927 NULL, &lfs->rcache, lfs->cfg->block_size, in lfs_dir_fetchmatch()
969 if (lfs_gstate_hasmovehere(&lfs->gdisk, dir->pair)) { in lfs_dir_fetchmatch()
970 if (lfs_tag_id(lfs->gdisk.tag) == lfs_tag_id(besttag)) { in lfs_dir_fetchmatch()
973 lfs_tag_id(lfs->gdisk.tag) < lfs_tag_id(besttag)) { in lfs_dir_fetchmatch()
1002 static int lfs_dir_fetch(lfs_t *lfs, in lfs_dir_fetch() argument
1006 return (int)lfs_dir_fetchmatch(lfs, dir, pair, in lfs_dir_fetch()
1010 static int lfs_dir_getgstate(lfs_t *lfs, const lfs_mdir_t *dir, in lfs_dir_getgstate() argument
1013 lfs_stag_t res = lfs_dir_get(lfs, dir, LFS_MKTAG(0x7ff, 0, 0), in lfs_dir_getgstate()
1028 static int lfs_dir_getinfo(lfs_t *lfs, lfs_mdir_t *dir, in lfs_dir_getinfo() argument
1037 lfs_stag_t tag = lfs_dir_get(lfs, dir, LFS_MKTAG(0x780, 0x3ff, 0), in lfs_dir_getinfo()
1038 LFS_MKTAG(LFS_TYPE_NAME, id, lfs->name_max+1), info->name); in lfs_dir_getinfo()
1046 tag = lfs_dir_get(lfs, dir, LFS_MKTAG(0x700, 0x3ff, 0), in lfs_dir_getinfo()
1063 lfs_t *lfs; member
1071 lfs_t *lfs = name->lfs; in lfs_dir_find_match() local
1076 int res = lfs_bd_cmp(lfs, in lfs_dir_find_match()
1077 NULL, &lfs->rcache, diff, in lfs_dir_find_match()
1092 static lfs_stag_t lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir, in lfs_dir_find() argument
1102 dir->tail[0] = lfs->root[0]; in lfs_dir_find()
1103 dir->tail[1] = lfs->root[1]; in lfs_dir_find()
1157 lfs_stag_t res = lfs_dir_get(lfs, dir, LFS_MKTAG(0x700, 0x3ff, 0), in lfs_dir_find()
1167 tag = lfs_dir_fetchmatch(lfs, dir, dir->tail, in lfs_dir_find()
1173 lfs, name, namelen}); in lfs_dir_find()
1203 static int lfs_dir_commitprog(lfs_t *lfs, struct lfs_commit *commit, in lfs_dir_commitprog() argument
1205 int err = lfs_bd_prog(lfs, in lfs_dir_commitprog()
1206 &lfs->pcache, &lfs->rcache, false, in lfs_dir_commitprog()
1218 static int lfs_dir_commitattr(lfs_t *lfs, struct lfs_commit *commit, in lfs_dir_commitattr() argument
1228 int err = lfs_dir_commitprog(lfs, commit, &ntag, sizeof(ntag)); in lfs_dir_commitattr()
1235 err = lfs_dir_commitprog(lfs, commit, buffer, dsize-sizeof(tag)); in lfs_dir_commitattr()
1245 err = lfs_bd_read(lfs, in lfs_dir_commitattr()
1246 NULL, &lfs->rcache, dsize-sizeof(tag)-i, in lfs_dir_commitattr()
1252 err = lfs_dir_commitprog(lfs, commit, &dat, 1); in lfs_dir_commitattr()
1263 static int lfs_dir_commitcrc(lfs_t *lfs, struct lfs_commit *commit) { in lfs_dir_commitcrc() argument
1268 lfs->cfg->prog_size); in lfs_dir_commitcrc()
1282 int err = lfs_bd_read(lfs, in lfs_dir_commitcrc()
1283 NULL, &lfs->rcache, sizeof(tag), in lfs_dir_commitcrc()
1298 err = lfs_bd_prog(lfs, in lfs_dir_commitcrc()
1299 &lfs->pcache, &lfs->rcache, false, in lfs_dir_commitcrc()
1311 int err = lfs_bd_sync(lfs, &lfs->pcache, &lfs->rcache, false); in lfs_dir_commitcrc()
1330 err = lfs_bd_read(lfs, in lfs_dir_commitcrc()
1331 NULL, &lfs->rcache, noff+sizeof(uint32_t)-i, in lfs_dir_commitcrc()
1356 static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir) { in lfs_dir_alloc() argument
1359 int err = lfs_alloc(lfs, &dir->pair[(i+1)%2]); in lfs_dir_alloc()
1370 int err = lfs_bd_read(lfs, in lfs_dir_alloc()
1371 NULL, &lfs->rcache, sizeof(dir->rev), in lfs_dir_alloc()
1394 static int lfs_dir_drop(lfs_t *lfs, lfs_mdir_t *dir, lfs_mdir_t *tail) { in lfs_dir_drop() argument
1396 int err = lfs_dir_getgstate(lfs, tail, &lfs->gdelta); in lfs_dir_drop()
1403 err = lfs_dir_commit(lfs, dir, LFS_MKATTRS( in lfs_dir_drop()
1413 static int lfs_dir_split(lfs_t *lfs, in lfs_dir_split() argument
1417 lfs_alloc_ack(lfs); in lfs_dir_split()
1419 int err = lfs_dir_alloc(lfs, &tail); in lfs_dir_split()
1428 err = lfs_dir_compact(lfs, &tail, attrs, attrcount, source, split, end); in lfs_dir_split()
1438 if (lfs_pair_cmp(dir->pair, lfs->root) == 0 && split == 0) { in lfs_dir_split()
1439 lfs->root[0] = tail.pair[0]; in lfs_dir_split()
1440 lfs->root[1] = tail.pair[1]; in lfs_dir_split()
1455 lfs_t *lfs; member
1461 return lfs_dir_commitattr(commit->lfs, commit->commit, tag, buffer); in lfs_dir_commit_commit()
1464 static int lfs_dir_compact(lfs_t *lfs, in lfs_dir_compact() argument
1476 int err = lfs_dir_traverse(lfs, in lfs_dir_compact()
1490 size <= lfs_min(lfs->cfg->block_size - 36, in lfs_dir_compact()
1491 lfs_alignup(lfs->cfg->block_size/2, in lfs_dir_compact()
1492 lfs->cfg->prog_size))) { in lfs_dir_compact()
1500 err = lfs_dir_split(lfs, dir, attrs, attrcount, in lfs_dir_compact()
1506 if (err == LFS_ERR_NOSPC && size <= lfs->cfg->block_size - 36) { in lfs_dir_compact()
1523 if (lfs->cfg->block_cycles > 0 && in lfs_dir_compact()
1524 (dir->rev % ((lfs->cfg->block_cycles+1)|1) == 0)) { in lfs_dir_compact()
1528 lfs_ssize_t res = lfs_fs_size(lfs); in lfs_dir_compact()
1535 if ((lfs_size_t)res < lfs->cfg->block_count/2) { in lfs_dir_compact()
1537 int err = lfs_dir_split(lfs, dir, attrs, attrcount, in lfs_dir_compact()
1550 } else if (lfs->lfs1) { in lfs_dir_compact()
1576 .end = lfs->cfg->block_size - 8, in lfs_dir_compact()
1580 int err = lfs_bd_erase(lfs, dir->pair[1]); in lfs_dir_compact()
1590 err = lfs_dir_commitprog(lfs, &commit, in lfs_dir_compact()
1601 err = lfs_dir_traverse(lfs, in lfs_dir_compact()
1607 lfs, &commit}); in lfs_dir_compact()
1618 err = lfs_dir_commitattr(lfs, &commit, in lfs_dir_compact()
1633 lfs_gstate_xor(&delta, &lfs->gdisk); in lfs_dir_compact()
1634 lfs_gstate_xor(&delta, &lfs->gstate); in lfs_dir_compact()
1636 lfs_gstate_xor(&delta, &lfs->gdelta); in lfs_dir_compact()
1639 err = lfs_dir_getgstate(lfs, dir, &delta); in lfs_dir_compact()
1646 err = lfs_dir_commitattr(lfs, &commit, in lfs_dir_compact()
1658 err = lfs_dir_commitcrc(lfs, &commit); in lfs_dir_compact()
1667 LFS_ASSERT(commit.off % lfs->cfg->prog_size == 0); in lfs_dir_compact()
1673 lfs->gdelta = (lfs_gstate_t){0}; in lfs_dir_compact()
1675 lfs->gdisk = lfs->gstate; in lfs_dir_compact()
1683 lfs_cache_drop(lfs, &lfs->pcache); in lfs_dir_compact()
1696 int err = lfs_alloc(lfs, &dir->pair[1]); in lfs_dir_compact()
1710 int err = lfs_fs_relocate(lfs, oldpair, dir->pair); in lfs_dir_compact()
1719 static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, in lfs_dir_commit() argument
1723 for (lfs_file_t *f = (lfs_file_t*)lfs->mlist; f; f = f->next) { in lfs_dir_commit()
1726 f->ctz.size > lfs->cfg->cache_size) { in lfs_dir_commit()
1727 int err = lfs_file_outline(lfs, f); in lfs_dir_commit()
1732 err = lfs_file_flush(lfs, f); in lfs_dir_commit()
1760 int err = lfs_fs_pred(lfs, dir->pair, &pdir); in lfs_dir_commit()
1767 err = lfs_dir_drop(lfs, &pdir, dir); in lfs_dir_commit()
1784 .end = lfs->cfg->block_size - 8, in lfs_dir_commit()
1789 int err = lfs_dir_traverse(lfs, in lfs_dir_commit()
1793 lfs, &commit}); in lfs_dir_commit()
1805 lfs_gstate_xor(&delta, &lfs->gstate); in lfs_dir_commit()
1806 lfs_gstate_xor(&delta, &lfs->gdisk); in lfs_dir_commit()
1807 lfs_gstate_xor(&delta, &lfs->gdelta); in lfs_dir_commit()
1810 err = lfs_dir_getgstate(lfs, dir, &delta); in lfs_dir_commit()
1817 err = lfs_dir_commitattr(lfs, &commit, in lfs_dir_commit()
1830 err = lfs_dir_commitcrc(lfs, &commit); in lfs_dir_commit()
1840 LFS_ASSERT(commit.off % lfs->cfg->prog_size == 0); in lfs_dir_commit()
1844 lfs->gdisk = lfs->gstate; in lfs_dir_commit()
1845 lfs->gdelta = (lfs_gstate_t){0}; in lfs_dir_commit()
1849 lfs_cache_drop(lfs, &lfs->pcache); in lfs_dir_commit()
1851 int err = lfs_dir_compact(lfs, dir, attrs, attrcount, in lfs_dir_commit()
1866 for (struct lfs_mlist *d = lfs->mlist; d; d = d->next) { in lfs_dir_commit()
1891 for (struct lfs_mlist *d = lfs->mlist; d; d = d->next) { in lfs_dir_commit()
1896 int err = lfs_dir_fetch(lfs, &d->m, d->m.tail); in lfs_dir_commit()
1909 int lfs_mkdir(lfs_t *lfs, const char *path) { in lfs_mkdir() argument
1910 LFS_TRACE("lfs_mkdir(%p, \"%s\")", (void*)lfs, path); in lfs_mkdir()
1912 int err = lfs_fs_forceconsistency(lfs); in lfs_mkdir()
1919 cwd.next = lfs->mlist; in lfs_mkdir()
1921 err = lfs_dir_find(lfs, &cwd.m, &path, &id); in lfs_mkdir()
1929 if (nlen > lfs->name_max) { in lfs_mkdir()
1935 lfs_alloc_ack(lfs); in lfs_mkdir()
1937 err = lfs_dir_alloc(lfs, &dir); in lfs_mkdir()
1946 err = lfs_dir_fetch(lfs, &pred, pred.tail); in lfs_mkdir()
1955 err = lfs_dir_commit(lfs, &dir, LFS_MKATTRS( in lfs_mkdir()
1966 lfs_fs_preporphans(lfs, +1); in lfs_mkdir()
1974 lfs->mlist = &cwd; in lfs_mkdir()
1977 err = lfs_dir_commit(lfs, &pred, LFS_MKATTRS( in lfs_mkdir()
1981 lfs->mlist = cwd.next; in lfs_mkdir()
1986 lfs->mlist = cwd.next; in lfs_mkdir()
1987 lfs_fs_preporphans(lfs, -1); in lfs_mkdir()
1992 err = lfs_dir_commit(lfs, &cwd.m, LFS_MKATTRS( in lfs_mkdir()
2008 int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) { in lfs_dir_open() argument
2009 LFS_TRACE("lfs_dir_open(%p, %p, \"%s\")", (void*)lfs, (void*)dir, path); in lfs_dir_open()
2010 lfs_stag_t tag = lfs_dir_find(lfs, &dir->m, &path, NULL); in lfs_dir_open()
2024 pair[0] = lfs->root[0]; in lfs_dir_open()
2025 pair[1] = lfs->root[1]; in lfs_dir_open()
2028 lfs_stag_t res = lfs_dir_get(lfs, &dir->m, LFS_MKTAG(0x700, 0x3ff, 0), in lfs_dir_open()
2038 int err = lfs_dir_fetch(lfs, &dir->m, pair); in lfs_dir_open()
2052 dir->next = (lfs_dir_t*)lfs->mlist; in lfs_dir_open()
2053 lfs->mlist = (struct lfs_mlist*)dir; in lfs_dir_open()
2059 int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir) { in lfs_dir_close() argument
2060 LFS_TRACE("lfs_dir_close(%p, %p)", (void*)lfs, (void*)dir); in lfs_dir_close()
2062 for (struct lfs_mlist **p = &lfs->mlist; *p; p = &(*p)->next) { in lfs_dir_close()
2073 int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info) { in lfs_dir_read() argument
2075 (void*)lfs, (void*)dir, (void*)info); in lfs_dir_read()
2100 int err = lfs_dir_fetch(lfs, &dir->m, dir->m.tail); in lfs_dir_read()
2109 int err = lfs_dir_getinfo(lfs, &dir->m, dir->id, info); in lfs_dir_read()
2126 int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off) { in lfs_dir_seek() argument
2128 (void*)lfs, (void*)dir, off); in lfs_dir_seek()
2130 int err = lfs_dir_rewind(lfs, dir); in lfs_dir_seek()
2141 dir->id = (off > 0 && lfs_pair_cmp(dir->head, lfs->root) == 0); in lfs_dir_seek()
2155 err = lfs_dir_fetch(lfs, &dir->m, dir->m.tail); in lfs_dir_seek()
2169 lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir) { in lfs_dir_tell() argument
2170 LFS_TRACE("lfs_dir_tell(%p, %p)", (void*)lfs, (void*)dir); in lfs_dir_tell()
2171 (void)lfs; in lfs_dir_tell()
2176 int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir) { in lfs_dir_rewind() argument
2177 LFS_TRACE("lfs_dir_rewind(%p, %p)", (void*)lfs, (void*)dir); in lfs_dir_rewind()
2179 int err = lfs_dir_fetch(lfs, &dir->m, dir->head); in lfs_dir_rewind()
2193 static int lfs_ctz_index(lfs_t *lfs, lfs_off_t *off) { in lfs_ctz_index() argument
2195 lfs_off_t b = lfs->cfg->block_size - 2*4; in lfs_ctz_index()
2206 static int lfs_ctz_find(lfs_t *lfs, in lfs_ctz_find() argument
2216 lfs_off_t current = lfs_ctz_index(lfs, &(lfs_off_t){size-1}); in lfs_ctz_find()
2217 lfs_off_t target = lfs_ctz_index(lfs, &pos); in lfs_ctz_find()
2224 int err = lfs_bd_read(lfs, in lfs_ctz_find()
2240 static int lfs_ctz_extend(lfs_t *lfs, in lfs_ctz_extend() argument
2247 int err = lfs_alloc(lfs, &nblock); in lfs_ctz_extend()
2253 err = lfs_bd_erase(lfs, nblock); in lfs_ctz_extend()
2268 lfs_off_t index = lfs_ctz_index(lfs, &noff); in lfs_ctz_extend()
2272 if (noff != lfs->cfg->block_size) { in lfs_ctz_extend()
2275 err = lfs_bd_read(lfs, in lfs_ctz_extend()
2282 err = lfs_bd_prog(lfs, in lfs_ctz_extend()
2304 err = lfs_bd_prog(lfs, pcache, rcache, true, in lfs_ctz_extend()
2315 err = lfs_bd_read(lfs, in lfs_ctz_extend()
2334 lfs_cache_drop(lfs, pcache); in lfs_ctz_extend()
2338 static int lfs_ctz_traverse(lfs_t *lfs, in lfs_ctz_traverse() argument
2346 lfs_off_t index = lfs_ctz_index(lfs, &(lfs_off_t){size-1}); in lfs_ctz_traverse()
2360 err = lfs_bd_read(lfs, in lfs_ctz_traverse()
2383 int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file, in lfs_file_opencfg() argument
2388 (void*)lfs, (void*)file, path, flags, in lfs_file_opencfg()
2393 int err = lfs_fs_forceconsistency(lfs); in lfs_file_opencfg()
2409 lfs_stag_t tag = lfs_dir_find(lfs, &file->m, &path, &file->id); in lfs_file_opencfg()
2417 file->next = (lfs_file_t*)lfs->mlist; in lfs_file_opencfg()
2418 lfs->mlist = (struct lfs_mlist*)file; in lfs_file_opencfg()
2428 if (nlen > lfs->name_max) { in lfs_file_opencfg()
2434 err = lfs_dir_commit(lfs, &file->m, LFS_MKATTRS( in lfs_file_opencfg()
2456 tag = lfs_dir_get(lfs, &file->m, LFS_MKTAG(0x700, 0x3ff, 0), in lfs_file_opencfg()
2468 lfs_stag_t res = lfs_dir_get(lfs, &file->m, in lfs_file_opencfg()
2480 if (file->cfg->attrs[i].size > lfs->attr_max) { in lfs_file_opencfg()
2493 file->cache.buffer = lfs_malloc(lfs->cfg->cache_size); in lfs_file_opencfg()
2501 lfs_cache_zero(lfs, &file->cache); in lfs_file_opencfg()
2510 file->cache.size = lfs->cfg->cache_size; in lfs_file_opencfg()
2514 lfs_stag_t res = lfs_dir_get(lfs, &file->m, in lfs_file_opencfg()
2532 lfs_file_close(lfs, file); in lfs_file_opencfg()
2537 int lfs_file_open(lfs_t *lfs, lfs_file_t *file, in lfs_file_open() argument
2540 (void*)lfs, (void*)file, path, flags); in lfs_file_open()
2542 int err = lfs_file_opencfg(lfs, file, path, flags, &defaults); in lfs_file_open()
2547 int lfs_file_close(lfs_t *lfs, lfs_file_t *file) { in lfs_file_close() argument
2548 LFS_TRACE("lfs_file_close(%p, %p)", (void*)lfs, (void*)file); in lfs_file_close()
2551 int err = lfs_file_sync(lfs, file); in lfs_file_close()
2554 for (struct lfs_mlist **p = &lfs->mlist; *p; p = &(*p)->next) { in lfs_file_close()
2571 static int lfs_file_relocate(lfs_t *lfs, lfs_file_t *file) { in lfs_file_relocate() argument
2577 int err = lfs_alloc(lfs, &nblock); in lfs_file_relocate()
2582 err = lfs_bd_erase(lfs, nblock); in lfs_file_relocate()
2594 err = lfs_dir_getread(lfs, &file->m, in lfs_file_relocate()
2604 err = lfs_bd_read(lfs, in lfs_file_relocate()
2605 &file->cache, &lfs->rcache, file->off-i, in lfs_file_relocate()
2612 err = lfs_bd_prog(lfs, in lfs_file_relocate()
2613 &lfs->pcache, &lfs->rcache, true, in lfs_file_relocate()
2624 memcpy(file->cache.buffer, lfs->pcache.buffer, lfs->cfg->cache_size); in lfs_file_relocate()
2625 file->cache.block = lfs->pcache.block; in lfs_file_relocate()
2626 file->cache.off = lfs->pcache.off; in lfs_file_relocate()
2627 file->cache.size = lfs->pcache.size; in lfs_file_relocate()
2628 lfs_cache_zero(lfs, &lfs->pcache); in lfs_file_relocate()
2638 lfs_cache_drop(lfs, &lfs->pcache); in lfs_file_relocate()
2642 static int lfs_file_outline(lfs_t *lfs, lfs_file_t *file) { in lfs_file_outline() argument
2644 lfs_alloc_ack(lfs); in lfs_file_outline()
2645 int err = lfs_file_relocate(lfs, file); in lfs_file_outline()
2654 static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) { in lfs_file_flush() argument
2659 lfs_cache_drop(lfs, &file->cache); in lfs_file_flush()
2674 .cache = lfs->rcache, in lfs_file_flush()
2676 lfs_cache_drop(lfs, &lfs->rcache); in lfs_file_flush()
2682 lfs_ssize_t res = lfs_file_read(lfs, &orig, &data, 1); in lfs_file_flush()
2687 res = lfs_file_write(lfs, file, &data, 1); in lfs_file_flush()
2693 if (lfs->rcache.block != LFS_BLOCK_NULL) { in lfs_file_flush()
2694 lfs_cache_drop(lfs, &orig.cache); in lfs_file_flush()
2695 lfs_cache_drop(lfs, &lfs->rcache); in lfs_file_flush()
2701 int err = lfs_bd_flush(lfs, &file->cache, &lfs->rcache, true); in lfs_file_flush()
2713 err = lfs_file_relocate(lfs, file); in lfs_file_flush()
2734 int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) { in lfs_file_sync() argument
2735 LFS_TRACE("lfs_file_sync(%p, %p)", (void*)lfs, (void*)file); in lfs_file_sync()
2744 int err = lfs_file_flush(lfs, file); in lfs_file_sync()
2774 err = lfs_dir_commit(lfs, &file->m, LFS_MKATTRS( in lfs_file_sync()
2791 lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file, in lfs_file_read() argument
2794 (void*)lfs, (void*)file, buffer, size); in lfs_file_read()
2803 int err = lfs_file_flush(lfs, file); in lfs_file_read()
2822 file->off == lfs->cfg->block_size) { in lfs_file_read()
2824 int err = lfs_ctz_find(lfs, NULL, &file->cache, in lfs_file_read()
2840 lfs_size_t diff = lfs_min(nsize, lfs->cfg->block_size - file->off); in lfs_file_read()
2842 int err = lfs_dir_getread(lfs, &file->m, in lfs_file_read()
2843 NULL, &file->cache, lfs->cfg->block_size, in lfs_file_read()
2852 int err = lfs_bd_read(lfs, in lfs_file_read()
2853 NULL, &file->cache, lfs->cfg->block_size, in lfs_file_read()
2871 lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file, in lfs_file_write() argument
2874 (void*)lfs, (void*)file, buffer, size); in lfs_file_write()
2883 int err = lfs_file_flush(lfs, file); in lfs_file_write()
2894 if (file->pos + size > lfs->file_max) { in lfs_file_write()
2906 lfs_ssize_t res = lfs_file_write(lfs, file, &(uint8_t){0}, 1); in lfs_file_write()
2917 lfs->cfg->cache_size, lfs->cfg->block_size/8))) { in lfs_file_write()
2919 int err = lfs_file_outline(lfs, file); in lfs_file_write()
2930 file->off == lfs->cfg->block_size) { in lfs_file_write()
2934 int err = lfs_ctz_find(lfs, NULL, &file->cache, in lfs_file_write()
2944 lfs_cache_zero(lfs, &file->cache); in lfs_file_write()
2948 lfs_alloc_ack(lfs); in lfs_file_write()
2949 int err = lfs_ctz_extend(lfs, &file->cache, &lfs->rcache, in lfs_file_write()
2966 lfs_size_t diff = lfs_min(nsize, lfs->cfg->block_size - file->off); in lfs_file_write()
2968 int err = lfs_bd_prog(lfs, &file->cache, &lfs->rcache, true, in lfs_file_write()
2981 err = lfs_file_relocate(lfs, file); in lfs_file_write()
2994 lfs_alloc_ack(lfs); in lfs_file_write()
3002 lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file, in lfs_file_seek() argument
3005 (void*)lfs, (void*)file, off, whence); in lfs_file_seek()
3009 int err = lfs_file_flush(lfs, file); in lfs_file_seek()
3025 if (npos > lfs->file_max) { in lfs_file_seek()
3037 int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) { in lfs_file_truncate() argument
3039 (void*)lfs, (void*)file, size); in lfs_file_truncate()
3049 lfs_off_t oldsize = lfs_file_size(lfs, file); in lfs_file_truncate()
3052 int err = lfs_file_flush(lfs, file); in lfs_file_truncate()
3059 err = lfs_ctz_find(lfs, NULL, &file->cache, in lfs_file_truncate()
3073 lfs_soff_t res = lfs_file_seek(lfs, file, 0, LFS_SEEK_END); in lfs_file_truncate()
3082 lfs_ssize_t res = lfs_file_write(lfs, file, &(uint8_t){0}, 1); in lfs_file_truncate()
3091 lfs_soff_t res = lfs_file_seek(lfs, file, pos, LFS_SEEK_SET); in lfs_file_truncate()
3101 lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file) { in lfs_file_tell() argument
3102 LFS_TRACE("lfs_file_tell(%p, %p)", (void*)lfs, (void*)file); in lfs_file_tell()
3104 (void)lfs; in lfs_file_tell()
3109 int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file) { in lfs_file_rewind() argument
3110 LFS_TRACE("lfs_file_rewind(%p, %p)", (void*)lfs, (void*)file); in lfs_file_rewind()
3111 lfs_soff_t res = lfs_file_seek(lfs, file, 0, LFS_SEEK_SET); in lfs_file_rewind()
3121 lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) { in lfs_file_size() argument
3122 LFS_TRACE("lfs_file_size(%p, %p)", (void*)lfs, (void*)file); in lfs_file_size()
3124 (void)lfs; in lfs_file_size()
3137 int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) { in lfs_stat() argument
3138 LFS_TRACE("lfs_stat(%p, \"%s\", %p)", (void*)lfs, path, (void*)info); in lfs_stat()
3140 lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL); in lfs_stat()
3146 int err = lfs_dir_getinfo(lfs, &cwd, lfs_tag_id(tag), info); in lfs_stat()
3151 int lfs_remove(lfs_t *lfs, const char *path) { in lfs_remove() argument
3152 LFS_TRACE("lfs_remove(%p, \"%s\")", (void*)lfs, path); in lfs_remove()
3154 int err = lfs_fs_forceconsistency(lfs); in lfs_remove()
3161 lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL); in lfs_remove()
3168 dir.next = lfs->mlist; in lfs_remove()
3172 lfs_stag_t res = lfs_dir_get(lfs, &cwd, LFS_MKTAG(0x700, 0x3ff, 0), in lfs_remove()
3180 err = lfs_dir_fetch(lfs, &dir.m, pair); in lfs_remove()
3192 lfs_fs_preporphans(lfs, +1); in lfs_remove()
3198 lfs->mlist = &dir; in lfs_remove()
3202 err = lfs_dir_commit(lfs, &cwd, LFS_MKATTRS( in lfs_remove()
3205 lfs->mlist = dir.next; in lfs_remove()
3210 lfs->mlist = dir.next; in lfs_remove()
3213 lfs_fs_preporphans(lfs, -1); in lfs_remove()
3215 err = lfs_fs_pred(lfs, dir.m.pair, &cwd); in lfs_remove()
3221 err = lfs_dir_drop(lfs, &cwd, &dir.m); in lfs_remove()
3232 int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { in lfs_rename() argument
3233 LFS_TRACE("lfs_rename(%p, \"%s\", \"%s\")", (void*)lfs, oldpath, newpath); in lfs_rename()
3236 int err = lfs_fs_forceconsistency(lfs); in lfs_rename()
3244 lfs_stag_t oldtag = lfs_dir_find(lfs, &oldcwd, &oldpath, NULL); in lfs_rename()
3254 lfs_stag_t prevtag = lfs_dir_find(lfs, &newcwd, &newpath, &newid); in lfs_rename()
3267 prevdir.next = lfs->mlist; in lfs_rename()
3271 if (nlen > lfs->name_max) { in lfs_rename()
3292 lfs_stag_t res = lfs_dir_get(lfs, &newcwd, LFS_MKTAG(0x700, 0x3ff, 0), in lfs_rename()
3301 err = lfs_dir_fetch(lfs, &prevdir.m, prevpair); in lfs_rename()
3313 lfs_fs_preporphans(lfs, +1); in lfs_rename()
3319 lfs->mlist = &prevdir; in lfs_rename()
3323 lfs_fs_prepmove(lfs, newoldid, oldcwd.pair); in lfs_rename()
3327 err = lfs_dir_commit(lfs, &newcwd, LFS_MKATTRS( in lfs_rename()
3336 lfs->mlist = prevdir.next; in lfs_rename()
3343 if (!samepair && lfs_gstate_hasmove(&lfs->gstate)) { in lfs_rename()
3345 lfs_fs_prepmove(lfs, 0x3ff, NULL); in lfs_rename()
3346 err = lfs_dir_commit(lfs, &oldcwd, LFS_MKATTRS( in lfs_rename()
3349 lfs->mlist = prevdir.next; in lfs_rename()
3355 lfs->mlist = prevdir.next; in lfs_rename()
3358 lfs_fs_preporphans(lfs, -1); in lfs_rename()
3360 err = lfs_fs_pred(lfs, prevdir.m.pair, &newcwd); in lfs_rename()
3366 err = lfs_dir_drop(lfs, &newcwd, &prevdir.m); in lfs_rename()
3377 lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path, in lfs_getattr() argument
3380 (void*)lfs, path, type, buffer, size); in lfs_getattr()
3382 lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL); in lfs_getattr()
3392 int err = lfs_dir_fetch(lfs, &cwd, lfs->root); in lfs_getattr()
3399 tag = lfs_dir_get(lfs, &cwd, LFS_MKTAG(0x7ff, 0x3ff, 0), in lfs_getattr()
3401 id, lfs_min(size, lfs->attr_max)), in lfs_getattr()
3418 static int lfs_commitattr(lfs_t *lfs, const char *path, in lfs_commitattr() argument
3421 lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL); in lfs_commitattr()
3430 int err = lfs_dir_fetch(lfs, &cwd, lfs->root); in lfs_commitattr()
3436 return lfs_dir_commit(lfs, &cwd, LFS_MKATTRS( in lfs_commitattr()
3440 int lfs_setattr(lfs_t *lfs, const char *path, in lfs_setattr() argument
3443 (void*)lfs, path, type, buffer, size); in lfs_setattr()
3444 if (size > lfs->attr_max) { in lfs_setattr()
3449 int err = lfs_commitattr(lfs, path, type, buffer, size); in lfs_setattr()
3454 int lfs_removeattr(lfs_t *lfs, const char *path, uint8_t type) { in lfs_removeattr() argument
3455 LFS_TRACE("lfs_removeattr(%p, \"%s\", %"PRIu8")", (void*)lfs, path, type); in lfs_removeattr()
3456 int err = lfs_commitattr(lfs, path, type, NULL, 0x3ff); in lfs_removeattr()
3463 static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { in lfs_init() argument
3464 lfs->cfg = cfg; in lfs_init()
3467 // validate that the lfs-cfg sizes were initiated properly before in lfs_init()
3469 LFS_ASSERT(lfs->cfg->read_size != 0); in lfs_init()
3470 LFS_ASSERT(lfs->cfg->prog_size != 0); in lfs_init()
3471 LFS_ASSERT(lfs->cfg->cache_size != 0); in lfs_init()
3475 LFS_ASSERT(lfs->cfg->cache_size % lfs->cfg->read_size == 0); in lfs_init()
3476 LFS_ASSERT(lfs->cfg->cache_size % lfs->cfg->prog_size == 0); in lfs_init()
3477 LFS_ASSERT(lfs->cfg->block_size % lfs->cfg->cache_size == 0); in lfs_init()
3480 LFS_ASSERT(4*lfs_npw2(0xffffffff / (lfs->cfg->block_size-2*4)) in lfs_init()
3481 <= lfs->cfg->block_size); in lfs_init()
3489 LFS_ASSERT(lfs->cfg->block_cycles != 0); in lfs_init()
3493 if (lfs->cfg->read_buffer) { in lfs_init()
3494 lfs->rcache.buffer = lfs->cfg->read_buffer; in lfs_init()
3496 lfs->rcache.buffer = lfs_malloc(lfs->cfg->cache_size); in lfs_init()
3497 if (!lfs->rcache.buffer) { in lfs_init()
3504 if (lfs->cfg->prog_buffer) { in lfs_init()
3505 lfs->pcache.buffer = lfs->cfg->prog_buffer; in lfs_init()
3507 lfs->pcache.buffer = lfs_malloc(lfs->cfg->cache_size); in lfs_init()
3508 if (!lfs->pcache.buffer) { in lfs_init()
3515 lfs_cache_zero(lfs, &lfs->rcache); in lfs_init()
3516 lfs_cache_zero(lfs, &lfs->pcache); in lfs_init()
3519 LFS_ASSERT(lfs->cfg->lookahead_size > 0); in lfs_init()
3520 LFS_ASSERT(lfs->cfg->lookahead_size % 8 == 0 && in lfs_init()
3521 (uintptr_t)lfs->cfg->lookahead_buffer % 4 == 0); in lfs_init()
3522 if (lfs->cfg->lookahead_buffer) { in lfs_init()
3523 lfs->free.buffer = lfs->cfg->lookahead_buffer; in lfs_init()
3525 lfs->free.buffer = lfs_malloc(lfs->cfg->lookahead_size); in lfs_init()
3526 if (!lfs->free.buffer) { in lfs_init()
3533 LFS_ASSERT(lfs->cfg->name_max <= LFS_NAME_MAX); in lfs_init()
3534 lfs->name_max = lfs->cfg->name_max; in lfs_init()
3535 if (!lfs->name_max) { in lfs_init()
3536 lfs->name_max = LFS_NAME_MAX; in lfs_init()
3539 LFS_ASSERT(lfs->cfg->file_max <= LFS_FILE_MAX); in lfs_init()
3540 lfs->file_max = lfs->cfg->file_max; in lfs_init()
3541 if (!lfs->file_max) { in lfs_init()
3542 lfs->file_max = LFS_FILE_MAX; in lfs_init()
3545 LFS_ASSERT(lfs->cfg->attr_max <= LFS_ATTR_MAX); in lfs_init()
3546 lfs->attr_max = lfs->cfg->attr_max; in lfs_init()
3547 if (!lfs->attr_max) { in lfs_init()
3548 lfs->attr_max = LFS_ATTR_MAX; in lfs_init()
3552 lfs->root[0] = LFS_BLOCK_NULL; in lfs_init()
3553 lfs->root[1] = LFS_BLOCK_NULL; in lfs_init()
3554 lfs->mlist = NULL; in lfs_init()
3555 lfs->seed = 0; in lfs_init()
3556 lfs->gdisk = (lfs_gstate_t){0}; in lfs_init()
3557 lfs->gstate = (lfs_gstate_t){0}; in lfs_init()
3558 lfs->gdelta = (lfs_gstate_t){0}; in lfs_init()
3560 lfs->lfs1 = NULL; in lfs_init()
3566 lfs_deinit(lfs); in lfs_init()
3570 static int lfs_deinit(lfs_t *lfs) { in lfs_deinit() argument
3572 if (!lfs->cfg->read_buffer) { in lfs_deinit()
3573 lfs_free(lfs->rcache.buffer); in lfs_deinit()
3576 if (!lfs->cfg->prog_buffer) { in lfs_deinit()
3577 lfs_free(lfs->pcache.buffer); in lfs_deinit()
3580 if (!lfs->cfg->lookahead_buffer) { in lfs_deinit()
3581 lfs_free(lfs->free.buffer); in lfs_deinit()
3587 int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { in lfs_format() argument
3597 (void*)lfs, (void*)cfg, cfg->context, in lfs_format()
3606 err = lfs_init(lfs, cfg); in lfs_format()
3613 memset(lfs->free.buffer, 0, lfs->cfg->lookahead_size); in lfs_format()
3614 lfs->free.off = 0; in lfs_format()
3615 lfs->free.size = lfs_min(8*lfs->cfg->lookahead_size, in lfs_format()
3616 lfs->cfg->block_count); in lfs_format()
3617 lfs->free.i = 0; in lfs_format()
3618 lfs_alloc_ack(lfs); in lfs_format()
3622 err = lfs_dir_alloc(lfs, &root); in lfs_format()
3630 .block_size = lfs->cfg->block_size, in lfs_format()
3631 .block_count = lfs->cfg->block_count, in lfs_format()
3632 .name_max = lfs->name_max, in lfs_format()
3633 .file_max = lfs->file_max, in lfs_format()
3634 .attr_max = lfs->attr_max, in lfs_format()
3638 err = lfs_dir_commit(lfs, &root, LFS_MKATTRS( in lfs_format()
3648 err = lfs_dir_fetch(lfs, &root, (const lfs_block_t[2]){0, 1}); in lfs_format()
3656 err = lfs_dir_commit(lfs, &root, NULL, 0); in lfs_format()
3663 lfs_deinit(lfs); in lfs_format()
3668 int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { in lfs_mount() argument
3678 (void*)lfs, (void*)cfg, cfg->context, in lfs_mount()
3685 int err = lfs_init(lfs, cfg); in lfs_mount()
3695 if (cycle >= lfs->cfg->block_count/2) { in lfs_mount()
3703 lfs_stag_t tag = lfs_dir_fetchmatch(lfs, &dir, dir.tail, in lfs_mount()
3708 lfs, "littlefs", 8}); in lfs_mount()
3717 lfs->root[0] = dir.pair[0]; in lfs_mount()
3718 lfs->root[1] = dir.pair[1]; in lfs_mount()
3722 tag = lfs_dir_get(lfs, &dir, LFS_MKTAG(0x7ff, 0x3ff, 0), in lfs_mount()
3744 if (superblock.name_max > lfs->name_max) { in lfs_mount()
3746 superblock.name_max, lfs->name_max); in lfs_mount()
3751 lfs->name_max = superblock.name_max; in lfs_mount()
3755 if (superblock.file_max > lfs->file_max) { in lfs_mount()
3757 superblock.file_max, lfs->file_max); in lfs_mount()
3762 lfs->file_max = superblock.file_max; in lfs_mount()
3766 if (superblock.attr_max > lfs->attr_max) { in lfs_mount()
3768 superblock.attr_max, lfs->attr_max); in lfs_mount()
3773 lfs->attr_max = superblock.attr_max; in lfs_mount()
3778 err = lfs_dir_getgstate(lfs, &dir, &lfs->gstate); in lfs_mount()
3785 if (lfs_pair_isnull(lfs->root)) { in lfs_mount()
3791 if (!lfs_gstate_iszero(&lfs->gstate)) { in lfs_mount()
3793 lfs->gstate.tag, in lfs_mount()
3794 lfs->gstate.pair[0], in lfs_mount()
3795 lfs->gstate.pair[1]); in lfs_mount()
3797 lfs->gstate.tag += !lfs_tag_isvalid(lfs->gstate.tag); in lfs_mount()
3798 lfs->gdisk = lfs->gstate; in lfs_mount()
3801 lfs_alloc_reset(lfs); in lfs_mount()
3807 lfs_unmount(lfs); in lfs_mount()
3812 int lfs_unmount(lfs_t *lfs) { in lfs_unmount() argument
3813 LFS_TRACE("lfs_unmount(%p)", (void*)lfs); in lfs_unmount()
3814 int err = lfs_deinit(lfs); in lfs_unmount()
3821 int lfs_fs_traverseraw(lfs_t *lfs, in lfs_fs_traverseraw() argument
3829 if (lfs->lfs1) { in lfs_fs_traverseraw()
3830 int err = lfs1_traverse(lfs, cb, data); in lfs_fs_traverseraw()
3835 dir.tail[0] = lfs->root[0]; in lfs_fs_traverseraw()
3836 dir.tail[1] = lfs->root[1]; in lfs_fs_traverseraw()
3842 if (cycle >= lfs->cfg->block_count/2) { in lfs_fs_traverseraw()
3856 int err = lfs_dir_fetch(lfs, &dir, dir.tail); in lfs_fs_traverseraw()
3863 lfs_stag_t tag = lfs_dir_get(lfs, &dir, LFS_MKTAG(0x700, 0x3ff, 0), in lfs_fs_traverseraw()
3874 err = lfs_ctz_traverse(lfs, NULL, &lfs->rcache, in lfs_fs_traverseraw()
3892 for (lfs_file_t *f = (lfs_file_t*)lfs->mlist; f; f = f->next) { in lfs_fs_traverseraw()
3898 int err = lfs_ctz_traverse(lfs, &f->cache, &lfs->rcache, in lfs_fs_traverseraw()
3906 int err = lfs_ctz_traverse(lfs, &f->cache, &lfs->rcache, in lfs_fs_traverseraw()
3917 int lfs_fs_traverse(lfs_t *lfs, in lfs_fs_traverse() argument
3920 (void*)lfs, (void*)(uintptr_t)cb, data); in lfs_fs_traverse()
3921 int err = lfs_fs_traverseraw(lfs, cb, data, true); in lfs_fs_traverse()
3926 static int lfs_fs_pred(lfs_t *lfs, in lfs_fs_pred() argument
3933 if (cycle >= lfs->cfg->block_count/2) { in lfs_fs_pred()
3943 int err = lfs_dir_fetch(lfs, pdir, pdir->tail); in lfs_fs_pred()
3953 lfs_t *lfs; member
3960 lfs_t *lfs = find->lfs; in lfs_fs_parent_match() local
3965 int err = lfs_bd_read(lfs, in lfs_fs_parent_match()
3966 &lfs->pcache, &lfs->rcache, lfs->cfg->block_size, in lfs_fs_parent_match()
3976 static lfs_stag_t lfs_fs_parent(lfs_t *lfs, const lfs_block_t pair[2], in lfs_fs_parent() argument
3983 if (cycle >= lfs->cfg->block_count/2) { in lfs_fs_parent()
3989 lfs_stag_t tag = lfs_dir_fetchmatch(lfs, parent, parent->tail, in lfs_fs_parent()
3994 lfs, {pair[0], pair[1]}}); in lfs_fs_parent()
4003 static int lfs_fs_relocate(lfs_t *lfs, in lfs_fs_relocate() argument
4006 if (lfs_pair_cmp(oldpair, lfs->root) == 0) { in lfs_fs_relocate()
4007 lfs->root[0] = newpair[0]; in lfs_fs_relocate()
4008 lfs->root[1] = newpair[1]; in lfs_fs_relocate()
4012 for (struct lfs_mlist *d = lfs->mlist; d; d = d->next) { in lfs_fs_relocate()
4027 lfs_stag_t tag = lfs_fs_parent(lfs, oldpair, &parent); in lfs_fs_relocate()
4034 lfs_fs_preporphans(lfs, +1); in lfs_fs_relocate()
4039 if (lfs_gstate_hasmovehere(&lfs->gstate, parent.pair)) { in lfs_fs_relocate()
4040 moveid = lfs_tag_id(lfs->gstate.tag); in lfs_fs_relocate()
4044 lfs_fs_prepmove(lfs, 0x3ff, NULL); in lfs_fs_relocate()
4051 int err = lfs_dir_commit(lfs, &parent, LFS_MKATTRS( in lfs_fs_relocate()
4061 lfs_fs_preporphans(lfs, -1); in lfs_fs_relocate()
4065 int err = lfs_fs_pred(lfs, oldpair, &parent); in lfs_fs_relocate()
4075 if (lfs_gstate_hasmovehere(&lfs->gstate, parent.pair)) { in lfs_fs_relocate()
4076 moveid = lfs_tag_id(lfs->gstate.tag); in lfs_fs_relocate()
4080 lfs_fs_prepmove(lfs, 0x3ff, NULL); in lfs_fs_relocate()
4085 err = lfs_dir_commit(lfs, &parent, LFS_MKATTRS( in lfs_fs_relocate()
4098 static void lfs_fs_preporphans(lfs_t *lfs, int8_t orphans) { in lfs_fs_preporphans() argument
4099 LFS_ASSERT(lfs_tag_size(lfs->gstate.tag) > 0 || orphans >= 0); in lfs_fs_preporphans()
4100 lfs->gstate.tag += orphans; in lfs_fs_preporphans()
4101 lfs->gstate.tag = ((lfs->gstate.tag & ~LFS_MKTAG(0x800, 0, 0)) | in lfs_fs_preporphans()
4102 ((uint32_t)lfs_gstate_hasorphans(&lfs->gstate) << 31)); in lfs_fs_preporphans()
4105 static void lfs_fs_prepmove(lfs_t *lfs, in lfs_fs_prepmove() argument
4107 lfs->gstate.tag = ((lfs->gstate.tag & ~LFS_MKTAG(0x7ff, 0x3ff, 0)) | in lfs_fs_prepmove()
4109 lfs->gstate.pair[0] = (id != 0x3ff) ? pair[0] : 0; in lfs_fs_prepmove()
4110 lfs->gstate.pair[1] = (id != 0x3ff) ? pair[1] : 0; in lfs_fs_prepmove()
4113 static int lfs_fs_demove(lfs_t *lfs) { in lfs_fs_demove() argument
4114 if (!lfs_gstate_hasmove(&lfs->gdisk)) { in lfs_fs_demove()
4120 lfs->gdisk.pair[0], in lfs_fs_demove()
4121 lfs->gdisk.pair[1], in lfs_fs_demove()
4122 lfs_tag_id(lfs->gdisk.tag)); in lfs_fs_demove()
4126 int err = lfs_dir_fetch(lfs, &movedir, lfs->gdisk.pair); in lfs_fs_demove()
4132 uint16_t moveid = lfs_tag_id(lfs->gdisk.tag); in lfs_fs_demove()
4133 lfs_fs_prepmove(lfs, 0x3ff, NULL); in lfs_fs_demove()
4134 err = lfs_dir_commit(lfs, &movedir, LFS_MKATTRS( in lfs_fs_demove()
4143 static int lfs_fs_deorphan(lfs_t *lfs) { in lfs_fs_deorphan() argument
4144 if (!lfs_gstate_hasorphans(&lfs->gstate)) { in lfs_fs_deorphan()
4154 int err = lfs_dir_fetch(lfs, &dir, pdir.tail); in lfs_fs_deorphan()
4163 lfs_stag_t tag = lfs_fs_parent(lfs, pdir.tail, &parent); in lfs_fs_deorphan()
4173 err = lfs_dir_drop(lfs, &pdir, &dir); in lfs_fs_deorphan()
4183 lfs_stag_t res = lfs_dir_get(lfs, &parent, in lfs_fs_deorphan()
4197 err = lfs_dir_commit(lfs, &pdir, LFS_MKATTRS( in lfs_fs_deorphan()
4213 lfs_fs_preporphans(lfs, -lfs_gstate_getorphans(&lfs->gstate)); in lfs_fs_deorphan()
4217 static int lfs_fs_forceconsistency(lfs_t *lfs) { in lfs_fs_forceconsistency() argument
4218 int err = lfs_fs_demove(lfs); in lfs_fs_forceconsistency()
4223 err = lfs_fs_deorphan(lfs); in lfs_fs_forceconsistency()
4238 lfs_ssize_t lfs_fs_size(lfs_t *lfs) { in lfs_fs_size() argument
4239 LFS_TRACE("lfs_fs_size(%p)", (void*)lfs); in lfs_fs_size()
4241 int err = lfs_fs_traverseraw(lfs, lfs_fs_size_count, &size, false); in lfs_fs_size()
4339 static int lfs1_bd_read(lfs_t *lfs, lfs_block_t block, in lfs1_bd_read() argument
4343 return lfs_bd_read(lfs, &lfs->pcache, &lfs->rcache, size, in lfs1_bd_read()
4347 static int lfs1_bd_crc(lfs_t *lfs, lfs_block_t block, in lfs1_bd_crc() argument
4351 int err = lfs1_bd_read(lfs, block, off+i, &c, 1); in lfs1_bd_crc()
4402 static int lfs1_dir_fetch(lfs_t *lfs, in lfs1_dir_fetch() argument
4411 int err = lfs1_bd_read(lfs, tpair[i], 0, &test, sizeof(test)); in lfs1_dir_fetch()
4425 (0x7fffffff & test.size) > lfs->cfg->block_size) { in lfs1_dir_fetch()
4433 err = lfs1_bd_crc(lfs, tpair[i], sizeof(test), in lfs1_dir_fetch()
4464 static int lfs1_dir_next(lfs_t *lfs, lfs1_dir_t *dir, lfs1_entry_t *entry) { in lfs1_dir_next() argument
4471 int err = lfs1_dir_fetch(lfs, dir, dir->d.tail); in lfs1_dir_next()
4480 int err = lfs1_bd_read(lfs, dir->pair[0], dir->off, in lfs1_dir_next()
4494 int lfs1_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data) { in lfs1_traverse() argument
4495 if (lfs_pair_isnull(lfs->lfs1->root)) { in lfs1_traverse()
4512 int err = lfs1_dir_fetch(lfs, &dir, cwd); in lfs1_traverse()
4519 err = lfs1_bd_read(lfs, dir.pair[0], dir.off, in lfs1_traverse()
4528 err = lfs_ctz_traverse(lfs, NULL, &lfs->rcache, in lfs1_traverse()
4539 err = lfs_dir_fetch(lfs, &dir2, dir2.tail); in lfs1_traverse()
4563 static int lfs1_moved(lfs_t *lfs, const void *e) { in lfs1_moved() argument
4564 if (lfs_pair_isnull(lfs->lfs1->root)) { in lfs1_moved()
4570 int err = lfs1_dir_fetch(lfs, &cwd, (const lfs_block_t[2]){0, 1}); in lfs1_moved()
4578 err = lfs1_dir_fetch(lfs, &cwd, cwd.d.tail); in lfs1_moved()
4584 err = lfs1_dir_next(lfs, &cwd, &entry); in lfs1_moved()
4604 static int lfs1_mount(lfs_t *lfs, struct lfs1 *lfs1, in lfs1_mount() argument
4608 err = lfs_init(lfs, cfg); in lfs1_mount()
4613 lfs->lfs1 = lfs1; in lfs1_mount()
4614 lfs->lfs1->root[0] = LFS_BLOCK_NULL; in lfs1_mount()
4615 lfs->lfs1->root[1] = LFS_BLOCK_NULL; in lfs1_mount()
4618 lfs->free.off = 0; in lfs1_mount()
4619 lfs->free.size = 0; in lfs1_mount()
4620 lfs->free.i = 0; in lfs1_mount()
4621 lfs_alloc_ack(lfs); in lfs1_mount()
4626 err = lfs1_dir_fetch(lfs, &dir, (const lfs_block_t[2]){0, 1}); in lfs1_mount()
4632 err = lfs1_bd_read(lfs, dir.pair[0], sizeof(dir.d), in lfs1_mount()
4639 lfs->lfs1->root[0] = superblock.d.root[0]; in lfs1_mount()
4640 lfs->lfs1->root[1] = superblock.d.root[1]; in lfs1_mount()
4663 lfs_deinit(lfs); in lfs1_mount()
4667 static int lfs1_unmount(lfs_t *lfs) { in lfs1_unmount() argument
4668 return lfs_deinit(lfs); in lfs1_unmount()
4672 int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg) { in lfs_migrate() argument
4682 (void*)lfs, (void*)cfg, cfg->context, in lfs_migrate()
4690 int err = lfs1_mount(lfs, &lfs1, cfg); in lfs_migrate()
4701 dir1.d.tail[0] = lfs->lfs1->root[0]; in lfs_migrate()
4702 dir1.d.tail[1] = lfs->lfs1->root[1]; in lfs_migrate()
4705 err = lfs1_dir_fetch(lfs, &dir1, dir1.d.tail); in lfs_migrate()
4711 err = lfs_dir_alloc(lfs, &dir2); in lfs_migrate()
4719 lfs->root[0] = dir2.pair[0]; in lfs_migrate()
4720 lfs->root[1] = dir2.pair[1]; in lfs_migrate()
4722 err = lfs_dir_commit(lfs, &dir2, NULL, 0); in lfs_migrate()
4729 err = lfs1_dir_next(lfs, &dir1, &entry1); in lfs_migrate()
4740 int moved = lfs1_moved(lfs, &entry1.d.u); in lfs_migrate()
4756 err = lfs1_bd_read(lfs, dir1.pair[0], in lfs_migrate()
4766 err = lfs_dir_fetch(lfs, &dir2, lfs->root); in lfs_migrate()
4772 err = lfs_dir_find(lfs, &dir2, &(const char*){name}, &id); in lfs_migrate()
4779 err = lfs_dir_commit(lfs, &dir2, LFS_MKATTRS( in lfs_migrate()
4797 err = lfs_dir_fetch(lfs, &dir2, lfs->root); in lfs_migrate()
4803 err = lfs_dir_fetch(lfs, &dir2, dir2.tail); in lfs_migrate()
4810 err = lfs_dir_commit(lfs, &dir2, LFS_MKATTRS( in lfs_migrate()
4822 lfs->root[0], lfs->root[1], dir1.head[0], dir1.head[1]); in lfs_migrate()
4824 err = lfs_bd_erase(lfs, dir1.head[1]); in lfs_migrate()
4829 err = lfs_dir_fetch(lfs, &dir2, lfs->root); in lfs_migrate()
4836 err = lfs_bd_read(lfs, in lfs_migrate()
4837 NULL, &lfs->rcache, dir2.off, in lfs_migrate()
4843 err = lfs_bd_prog(lfs, in lfs_migrate()
4844 &lfs->pcache, &lfs->rcache, true, in lfs_migrate()
4851 err = lfs_bd_flush(lfs, &lfs->pcache, &lfs->rcache, true); in lfs_migrate()
4858 err = lfs1_dir_fetch(lfs, &dir1, (const lfs_block_t[2]){0, 1}); in lfs_migrate()
4869 dir2.tail[0] = lfs->lfs1->root[0]; in lfs_migrate()
4870 dir2.tail[1] = lfs->lfs1->root[1]; in lfs_migrate()
4876 .block_size = lfs->cfg->block_size, in lfs_migrate()
4877 .block_count = lfs->cfg->block_count, in lfs_migrate()
4878 .name_max = lfs->name_max, in lfs_migrate()
4879 .file_max = lfs->file_max, in lfs_migrate()
4880 .attr_max = lfs->attr_max, in lfs_migrate()
4884 err = lfs_dir_commit(lfs, &dir2, LFS_MKATTRS( in lfs_migrate()
4894 err = lfs_dir_fetch(lfs, &dir2, (const lfs_block_t[2]){0, 1}); in lfs_migrate()
4901 err = lfs_dir_commit(lfs, &dir2, NULL, 0); in lfs_migrate()
4908 lfs1_unmount(lfs); in lfs_migrate()