浏览代码

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.
Christopher Haster 7 年之前
父节点
当前提交
d7b0652936
共有 2 个文件被更改,包括 13 次插入328 次删除
  1. 13 326
      lfs.c
  2. 0 2
      lfs.h

+ 13 - 326
lfs.c

@@ -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) {

+ 0 - 2
lfs.h

@@ -107,7 +107,6 @@ enum lfs_type {
 
     LFS_STRUCT_NAME     = 0x041,
     LFS_STRUCT_DELETE   = 0x047,
-    LFS_STRUCT_MOVE     = 0x046, // TODO rm me
 
     LFS_STRUCT_TAIL     = 0x081,
     LFS_STRUCT_CRC      = 0x087,
@@ -319,7 +318,6 @@ typedef struct lfs_mdir {
     bool split;
     lfs_globals_t globals;
     bool stop_at_commit; // TODO hmmm
-    uint16_t moveid; // TODO rm me
 } lfs_mdir_t;
 
 typedef struct lfs_cache {