diff options
author | Christopher Haster <chaster@utexas.edu> | 2018-07-09 19:47:04 +0300 |
---|---|---|
committer | Christopher Haster <chaster@utexas.edu> | 2018-10-16 00:03:18 +0300 |
commit | d7b065293689658d30a214b269bbc950d2c7db39 (patch) | |
tree | 5455ae77adb549c09499dbe1e8afceb5ed6ce912 /lfs.c | |
parent | 2ff32d2dfb879e38cc99f4c759683e95bd11faef (diff) |
Removed old move logic, now passing move tests
The introduction of xored-globals required quite a bit of work to
integrate. But now that that is working, we can strip out the old move
logic.
It's worth noting that the xored-globals integration with commits is
relatively complex and subtle.
Diffstat (limited to 'lfs.c')
-rw-r--r-- | lfs.c | 339 |
1 files changed, 13 insertions, 326 deletions
@@ -264,7 +264,6 @@ int lfs_fs_traverse(lfs_t *lfs, static int lfs_pred(lfs_t *lfs, const lfs_block_t dir[2], lfs_mdir_t *pdir); static int lfs_parent(lfs_t *lfs, const lfs_block_t dir[2], lfs_mdir_t *parent, lfs_mattr_t *attr); -static int lfs_moved(lfs_t *lfs, lfs_mdir_t *fromdir, uint16_t fromid); static int lfs_relocate(lfs_t *lfs, const lfs_block_t oldpair[2], const lfs_block_t newpair[2]); int lfs_scan(lfs_t *lfs); @@ -658,12 +657,6 @@ static int lfs_commit_movescan(lfs_t *lfs, void *p, lfs_mattr_t attr) { return 0; } - if (lfs_tag_type(attr.tag) == LFS_STRUCT_MOVE) { - // TODO need this? - // ignore moves - return 0; - } - // TODO AHHHH, scopes, what about user scope above? if (lfs_tag_scope(attr.tag) == LFS_SCOPE_FS || lfs_tag_scope(attr.tag) == LFS_SCOPE_DIR) { @@ -809,7 +802,6 @@ static int lfs_dir_fetchwith(lfs_t *lfs, dir->count = 0; dir->split = false; dir->globals = (lfs_globals_t){0}; - dir->moveid = -1; dir->rev = lfs_tole32(rev[0]); lfs_crc(&crc, &dir->rev, sizeof(dir->rev)); @@ -921,9 +913,6 @@ static int lfs_dir_fetchwith(lfs_t *lfs, if (err) { return err; } - } else if (lfs_tag_type(tag) == LFS_STRUCT_MOVE) { - // TODO handle moves correctly? - temp.moveid = lfs_tag_id(tag); } else { if (lfs_tag_scope(tag) <= LFS_SCOPE_ENTRY && lfs_tag_id(tag) >= temp.count) { @@ -932,14 +921,6 @@ static int lfs_dir_fetchwith(lfs_t *lfs, if (lfs_tag_struct(tag) == LFS_STRUCT_DELETE) { temp.count -= 1; - if (temp.moveid != -1) { - //printf("RENAME DEL %d (%d)\n", lfs_tag_id(tag), temp.moveid); - } - if (lfs_tag_id(tag) == temp.moveid) { - temp.moveid = -1; - } else if (lfs_tag_id(tag) < temp.moveid) { - temp.moveid -= 1; - } } if (cb) { @@ -1086,9 +1067,9 @@ static int lfs_dir_compact(lfs_t *lfs, lfs_mdir_t *dir, lfs_mattrlist_t *list, .filter.end = end, }; - // commit with a move - for (uint16_t id = begin; id < end; id++) { - err = lfs_commit_move(lfs, &commit, id, id, source, list); + if (!relocated) { + err = lfs_commit_globals(lfs, &commit, + &dir->globals, &lfs->diff); if (err) { if (err == LFS_ERR_NOSPC) { goto split; @@ -1097,17 +1078,11 @@ static int lfs_dir_compact(lfs_t *lfs, lfs_mdir_t *dir, lfs_mattrlist_t *list, } return err; } - - ack = id; } - // reopen the reserved space at the end - // TODO can I just commit these first? - commit.end = lfs->cfg->block_size - 2*sizeof(uint32_t); - - if (!relocated) { - err = lfs_commit_globals(lfs, &commit, - &dir->globals, &lfs->diff); + // commit with a move + for (uint16_t id = begin; id < end; id++) { + err = lfs_commit_move(lfs, &commit, id, id, source, list); if (err) { if (err == LFS_ERR_NOSPC) { goto split; @@ -1116,9 +1091,15 @@ static int lfs_dir_compact(lfs_t *lfs, lfs_mdir_t *dir, lfs_mattrlist_t *list, } return err; } + + ack = id; } + // reopen reserved space at the end + commit.end = lfs->cfg->block_size - 2*sizeof(uint32_t); + if (!lfs_pairisnull(dir->tail)) { + // commit tail, which may be new after last size check // TODO le32 err = lfs_commit_commit(lfs, &commit, (lfs_mattr_t){ lfs_mktag(LFS_STRUCT_TAIL + dir->split*0x8, @@ -1279,6 +1260,7 @@ compact: } } + // TODO what if we relocated the block containing the move? return 0; } @@ -1379,19 +1361,6 @@ static int lfs_dir_get(lfs_t *lfs, lfs_mdir_t *dir, return LFS_ERR_NOENT; } - // TODO hmm, stop at commit? maybe we need to handle this elsewhere? - // Should commit get be its own thing? commit traverse? - if (id == dir->moveid && !dir->stop_at_commit) { - int moved = lfs_moved(lfs, dir, dir->moveid); - if (moved < 0) { - return moved; - } - - if (moved) { - return LFS_ERR_NOENT; - } - } - attr->tag = lfs_mktag(0, id, 0) | (attr->tag & 0xffc00fff); return 0; } @@ -1433,17 +1402,6 @@ static int lfs_dir_getentry(lfs_t *lfs, lfs_mdir_t *dir, static int lfs_dir_getinfo(lfs_t *lfs, lfs_mdir_t *dir, int16_t id, struct lfs_info *info) { - if (id == dir->moveid) { - int moved = lfs_moved(lfs, dir, dir->moveid); - if (moved < 0) { - return moved; - } - - if (moved) { - return LFS_ERR_NOENT; - } - } - lfs_mattr_t attr; int err = lfs_dir_getentry(lfs, dir, 0x703ff000, lfs_mktag(LFS_SCOPE_STRUCT, id, 0), &attr); @@ -1585,17 +1543,6 @@ static int lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir, attr.u.pair[1] = dir->tail[1]; } - if (find.id == dir->moveid) { - int moved = lfs_moved(lfs, dir, dir->moveid); - if (moved < 0) { - return moved; - } - - if (moved) { - return LFS_ERR_NOENT; - } - } - *id = find.id; find.name += find.len; find.name += strspn(find.name, "/"); @@ -2913,38 +2860,6 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { lfs->diff.move.pair[1] = oldcwd.pair[1] ^ lfs->globals.move.pair[1]; lfs->diff.move.id = oldid ^ lfs->globals.move.id; -// // mark as moving -// //printf("RENAME MOVE %d %d %d\n", oldcwd.pair[0], oldcwd.pair[1], oldid); -// err = lfs_dir_commit(lfs, &oldcwd, &(lfs_mattrlist_t){ -// {lfs_mktag(LFS_STRUCT_MOVE, oldid, 0)}}); -// if (err) { -// return err; -// } -// -// if (samepair) { -// // update pair if newcwd == oldcwd -// newcwd = oldcwd; -// } -// -// TODO check that all complaints are fixed -// // move to new location -// // TODO NAME????? -// // TODO HAH, move doesn't want to override things (due -// // to its use in compaction), but that's _exactly what we want here -// err = lfs_dir_commitwith(lfs, &newcwd, lfs_commit_move, -// &(struct lfs_commit_move){.dir=&oldcwd, .id={oldid, newid}}); -// if (err) { -// return err; -// } -// // TODO NONONONONO -// // TODO also don't call strlen twice (see prev name check) -// err = lfs_dir_commit(lfs, &newcwd, &(lfs_mattrlist_t){ -// {lfs_mktag(LFS_STRUCT_NAME, newid, strlen(newpath)), -// .u.buffer=(void*)newpath}}); -// if (err) { -// return err; -// } - // move over all attributes err = lfs_dir_commit(lfs, &newcwd, &(lfs_mattrlist_t){ {lfs_mktag(LFS_STRUCT_NAME | lfs_tag_subtype(oldattr.tag), @@ -3624,97 +3539,6 @@ static int lfs_parent(lfs_t *lfs, const lfs_block_t dir[2], return false; } */ -static int lfs_moved(lfs_t *lfs, lfs_mdir_t *fromdir, uint16_t fromid) { - // grab entry pair we're looking for - fromdir->moveid = -1; - lfs_mattr_t fromentry; - // TODO what about inline files? - int err = lfs_dir_getentry(lfs, fromdir, 0x71fff000, - lfs_mktag(LFS_STRUCT_DIR, fromid, 0), &fromentry); - fromdir->moveid = fromid; - if (err) { - return err; - } - - // skip superblock - lfs_mdir_t todir; - err = lfs_dir_fetch(lfs, &todir, (const lfs_block_t[2]){0, 1}); - if (err) { - return err; - } - - // iterate over all directory directory entries - while (!lfs_pairisnull(todir.tail)) { - int err = lfs_dir_fetch(lfs, &todir, todir.tail); - if (err) { - return err; - } - - for (int toid = 0; toid < todir.count; toid++) { - if (lfs_paircmp(todir.pair, fromdir->pair) == 0 && - toid == fromid) { - continue; - } - - lfs_mattr_t toentry; - int err = lfs_dir_getentry(lfs, &todir, 0x71fff000, - lfs_mktag(LFS_STRUCT_DIR, toid, 0), &toentry); - if (err) { - if (err == LFS_ERR_NOENT) { - continue; - } - return err; - } - - if (lfs_paircmp(toentry.u.pair, fromentry.u.pair) == 0) { - return true; - } - } - } - - return false; -} -/* -static int lfs_moved(lfs_t *lfs, const void *e) { - if (lfs_pairisnull(lfs->root)) { - return 0; - } - - // skip superblock - lfs_mdir_t cwd; - int err = lfs_dir_fetch(lfs, &cwd, (const lfs_block_t[2]){0, 1}); - if (err) { - return err; - } - - // iterate over all directory directory entries - lfs_mattr_t entry; - while (!lfs_pairisnull(cwd.d.tail)) { - err = lfs_dir_fetch(lfs, &cwd, cwd.d.tail); - if (err) { - return err; - } - - while (true) { - err = lfs_dir_next(lfs, &cwd, &entry); - if (err && err != LFS_ERR_NOENT) { - return err; - } - - if (err == LFS_ERR_NOENT) { - break; - } - - if (!(LFS_STRUCT_MOVED & entry.d.type) && - memcmp(&entry.d.u, e, sizeof(entry.d.u)) == 0) { - return true; - } - } - } - - return false; -} -*/ // TODO rename to lfs_dir_relocate? static int lfs_relocate(lfs_t *lfs, @@ -3912,148 +3736,11 @@ int lfs_deorphan(lfs_t *lfs) { } } - // check entries for moves - //if (dir.moveid >= 0) { -// TODO moves and stuff - // TODO need to load entry to find it -// // found moved entry -// int moved = lfs_moved(lfs, &entry.u); -// if (moved < 0) { -// return moved; -// } -// -// if (moved) { -// LFS_DEBUG("Found move %d %d", -// entry.d.u.dir[0], entry.d.u.dir[1]); -// err = lfs_dir_set(lfs, &dir, &entry, (struct lfs_region[]){ -// {LFS_FROM_MEM, 0, entry.size, NULL, 0}}, 1); -// if (err) { -// return err; -// } -// } else { -// LFS_DEBUG("Found partial move %d %d", -// entry.d.u.dir[0], entry.d.u.dir[1]); -// entry.d.type &= ~LFS_STRUCT_MOVED; -// err = lfs_dir_set(lfs, &dir, &entry, (struct lfs_region[]){ -// {LFS_FROM_MEM, 0, 1, &entry.d, 1}}, 1); -// if (err) { -// return err; -// } -// } - //} - memcpy(&pdir, &dir, sizeof(pdir)); } return 0; } -/* -int lfs_deorphan(lfs_t *lfs) { - lfs->deorphaned = true; - - if (lfs_pairisnull(lfs->root)) { - return 0; - } - - lfs_mdir_t pdir = {.d.size = 0x80000000}; - lfs_mdir_t cwd = {.d.tail[0] = 0, .d.tail[1] = 1}; - - // iterate over all directory directory entries - while (!lfs_pairisnull(cwd.d.tail)) { - int err = lfs_dir_fetch(lfs, &cwd, cwd.d.tail); - if (err) { - return err; - } - - // check head blocks for orphans - if (!(0x80000000 & pdir.d.size)) { - // check if we have a parent - lfs_mdir_t parent; - lfs_mattr_t entry; - int res = lfs_parent(lfs, pdir.d.tail, &parent, &entry); - if (res < 0) { - return res; - } - - if (!res) { - // we are an orphan - LFS_DEBUG("Found orphan %d %d", - pdir.d.tail[0], pdir.d.tail[1]); - - pdir.d.tail[0] = cwd.d.tail[0]; - pdir.d.tail[1] = cwd.d.tail[1]; - - err = lfs_dir_commit(lfs, &pdir, NULL, 0); - if (err) { - return err; - } - - break; - } - - if (!lfs_pairsync(entry.d.u.dir, pdir.d.tail)) { - // we have desynced - LFS_DEBUG("Found desync %d %d", - entry.d.u.dir[0], entry.d.u.dir[1]); - - pdir.d.tail[0] = entry.d.u.dir[0]; - pdir.d.tail[1] = entry.d.u.dir[1]; - - err = lfs_dir_commit(lfs, &pdir, NULL, 0); - if (err) { - return err; - } - - break; - } - } - - // check entries for moves - lfs_mattr_t entry; - while (true) { - err = lfs_dir_next(lfs, &cwd, &entry); - if (err && err != LFS_ERR_NOENT) { - return err; - } - - if (err == LFS_ERR_NOENT) { - break; - } - - // found moved entry - if (entry.d.type & LFS_STRUCT_MOVED) { - int moved = lfs_moved(lfs, &entry.d.u); - if (moved < 0) { - return moved; - } - - if (moved) { - LFS_DEBUG("Found move %d %d", - entry.d.u.dir[0], entry.d.u.dir[1]); - err = lfs_dir_set(lfs, &cwd, &entry, (struct lfs_region[]){ - {LFS_FROM_MEM, 0, entry.size, NULL, 0}}, 1); - if (err) { - return err; - } - } else { - LFS_DEBUG("Found partial move %d %d", - entry.d.u.dir[0], entry.d.u.dir[1]); - entry.d.type &= ~LFS_STRUCT_MOVED; - err = lfs_dir_set(lfs, &cwd, &entry, (struct lfs_region[]){ - {LFS_FROM_MEM, 0, 1, &entry.d, 1}}, 1); - if (err) { - return err; - } - } - } - } - - memcpy(&pdir, &cwd, sizeof(pdir)); - } - - return 0; -} -*/ /// External filesystem filesystem operations /// //int lfs_fs_getattrs(lfs_t *lfs, const struct lfs_attr *attrs, int count) { |