diff --git a/.travis.yml b/.travis.yml index e3f786b..255e84b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -126,7 +126,7 @@ jobs: - mkdir mount/littlefs - cp -r $(git ls-tree --name-only HEAD) mount/littlefs - cd mount/littlefs - - ls + - ls -flh - make -B test_dirs test_files QUIET=1 # Automatically update releases diff --git a/lfs.c b/lfs.c index 0d5f079..32e626f 100644 --- a/lfs.c +++ b/lfs.c @@ -1746,29 +1746,58 @@ int lfs_mkdir(lfs_t *lfs, const char *path) { // build up new directory lfs_alloc_ack(lfs); - lfs_mdir_t dir; err = lfs_dir_alloc(lfs, &dir); if (err) { return err; } - dir.tail[0] = cwd.tail[0]; - dir.tail[1] = cwd.tail[1]; + // find end of list + lfs_mdir_t pred = cwd; + while (pred.split) { + err = lfs_dir_fetch(lfs, &pred, pred.tail); + if (err) { + return err; + } + } + + // setup dir + dir.tail[0] = pred.tail[0]; + dir.tail[1] = pred.tail[1]; err = lfs_dir_commit(lfs, &dir, NULL); if (err) { return err; } - // get next slot and commit - cwd.tail[0] = dir.pair[0]; - cwd.tail[1] = dir.pair[1]; + // current block end of list? + if (!cwd.split) { + // update atomically + cwd.tail[0] = dir.pair[0]; + cwd.tail[1] = dir.pair[1]; + } else { + // update tails, this creates a desync + pred.tail[0] = dir.pair[0]; + pred.tail[1] = dir.pair[1]; + lfs_global_orphans(lfs, +1); + err = lfs_dir_commit(lfs, &pred, + LFS_MKATTR(LFS_TYPE_SOFTTAIL, 0x1ff, + pred.tail, sizeof(pred.tail), + NULL)); + if (err) { + return err; + } + lfs_global_orphans(lfs, -1); + } + + // now insert into our parent block lfs_pair_tole32(dir.pair); err = lfs_dir_commit(lfs, &cwd, - LFS_MKATTR(LFS_TYPE_SOFTTAIL, 0x1ff, cwd.tail, sizeof(cwd.tail), LFS_MKATTR(LFS_TYPE_DIRSTRUCT, id, dir.pair, sizeof(dir.pair), LFS_MKATTR(LFS_TYPE_DIR, id, path, nlen, - NULL)))); + (!cwd.split) + ? LFS_MKATTR(LFS_TYPE_SOFTTAIL, 0x1ff, + cwd.tail, sizeof(cwd.tail), NULL) + : NULL))); lfs_pair_fromle32(dir.pair); if (err) { return err; diff --git a/tests/test_corrupt.sh b/tests/test_corrupt.sh index a73b7f8..81b0674 100755 --- a/tests/test_corrupt.sh +++ b/tests/test_corrupt.sh @@ -89,7 +89,7 @@ do rm -rf blocks mkdir blocks lfs_mktree - chmod a-w blocks/$b + chmod a-w blocks/$b || true lfs_mktree lfs_chktree done