119ea8026Sopenharmony_ci# specific corner cases worth explicitly testing for
219ea8026Sopenharmony_ci[cases.test_relocations_dangling_split_dir]
319ea8026Sopenharmony_cidefines.ITERATIONS = 20
419ea8026Sopenharmony_cidefines.COUNT = 10
519ea8026Sopenharmony_cidefines.BLOCK_CYCLES = [8, 1]
619ea8026Sopenharmony_cicode = '''
719ea8026Sopenharmony_ci    lfs_t lfs;
819ea8026Sopenharmony_ci    lfs_format(&lfs, cfg) => 0;
919ea8026Sopenharmony_ci    // fill up filesystem so only ~16 blocks are left
1019ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
1119ea8026Sopenharmony_ci    lfs_file_t file;
1219ea8026Sopenharmony_ci    lfs_file_open(&lfs, &file, "padding", LFS_O_CREAT | LFS_O_WRONLY) => 0;
1319ea8026Sopenharmony_ci    uint8_t buffer[512];
1419ea8026Sopenharmony_ci    memset(buffer, 0, 512);
1519ea8026Sopenharmony_ci    while (BLOCK_COUNT - lfs_fs_size(&lfs) > 16) {
1619ea8026Sopenharmony_ci        lfs_file_write(&lfs, &file, buffer, 512) => 512;
1719ea8026Sopenharmony_ci    }
1819ea8026Sopenharmony_ci    lfs_file_close(&lfs, &file) => 0;
1919ea8026Sopenharmony_ci    // make a child dir to use in bounded space
2019ea8026Sopenharmony_ci    lfs_mkdir(&lfs, "child") => 0;
2119ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
2219ea8026Sopenharmony_ci
2319ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
2419ea8026Sopenharmony_ci    for (unsigned j = 0; j < ITERATIONS; j++) {
2519ea8026Sopenharmony_ci        for (unsigned i = 0; i < COUNT; i++) {
2619ea8026Sopenharmony_ci            char path[1024];
2719ea8026Sopenharmony_ci            sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
2819ea8026Sopenharmony_ci            lfs_file_open(&lfs, &file, path, LFS_O_CREAT | LFS_O_WRONLY) => 0;
2919ea8026Sopenharmony_ci            lfs_file_close(&lfs, &file) => 0;
3019ea8026Sopenharmony_ci        }
3119ea8026Sopenharmony_ci
3219ea8026Sopenharmony_ci        lfs_dir_t dir;
3319ea8026Sopenharmony_ci        struct lfs_info info;
3419ea8026Sopenharmony_ci        lfs_dir_open(&lfs, &dir, "child") => 0;
3519ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
3619ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
3719ea8026Sopenharmony_ci        for (unsigned i = 0; i < COUNT; i++) {
3819ea8026Sopenharmony_ci            char path[1024];
3919ea8026Sopenharmony_ci            sprintf(path, "test%03d_loooooooooooooooooong_name", i);
4019ea8026Sopenharmony_ci            lfs_dir_read(&lfs, &dir, &info) => 1;
4119ea8026Sopenharmony_ci            strcmp(info.name, path) => 0;
4219ea8026Sopenharmony_ci        }
4319ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 0;
4419ea8026Sopenharmony_ci        lfs_dir_close(&lfs, &dir) => 0;
4519ea8026Sopenharmony_ci
4619ea8026Sopenharmony_ci        if (j == (unsigned)ITERATIONS-1) {
4719ea8026Sopenharmony_ci            break;
4819ea8026Sopenharmony_ci        }
4919ea8026Sopenharmony_ci
5019ea8026Sopenharmony_ci        for (unsigned i = 0; i < COUNT; i++) {
5119ea8026Sopenharmony_ci            char path[1024];
5219ea8026Sopenharmony_ci            sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
5319ea8026Sopenharmony_ci            lfs_remove(&lfs, path) => 0;
5419ea8026Sopenharmony_ci        }
5519ea8026Sopenharmony_ci    }
5619ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
5719ea8026Sopenharmony_ci
5819ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
5919ea8026Sopenharmony_ci    lfs_dir_t dir;
6019ea8026Sopenharmony_ci    struct lfs_info info;
6119ea8026Sopenharmony_ci    lfs_dir_open(&lfs, &dir, "child") => 0;
6219ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 1;
6319ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 1;
6419ea8026Sopenharmony_ci    for (unsigned i = 0; i < COUNT; i++) {
6519ea8026Sopenharmony_ci        char path[1024];
6619ea8026Sopenharmony_ci        sprintf(path, "test%03d_loooooooooooooooooong_name", i);
6719ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
6819ea8026Sopenharmony_ci        strcmp(info.name, path) => 0;
6919ea8026Sopenharmony_ci    }
7019ea8026Sopenharmony_ci    lfs_dir_read(&lfs, &dir, &info) => 0;
7119ea8026Sopenharmony_ci    lfs_dir_close(&lfs, &dir) => 0;
7219ea8026Sopenharmony_ci    for (unsigned i = 0; i < COUNT; i++) {
7319ea8026Sopenharmony_ci        char path[1024];
7419ea8026Sopenharmony_ci        sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
7519ea8026Sopenharmony_ci        lfs_remove(&lfs, path) => 0;
7619ea8026Sopenharmony_ci    }
7719ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
7819ea8026Sopenharmony_ci'''
7919ea8026Sopenharmony_ci
8019ea8026Sopenharmony_ci[cases.test_relocations_outdated_head]
8119ea8026Sopenharmony_cidefines.ITERATIONS = 20
8219ea8026Sopenharmony_cidefines.COUNT = 10
8319ea8026Sopenharmony_cidefines.BLOCK_CYCLES = [8, 1]
8419ea8026Sopenharmony_cicode = '''
8519ea8026Sopenharmony_ci    lfs_t lfs;
8619ea8026Sopenharmony_ci    lfs_format(&lfs, cfg) => 0;
8719ea8026Sopenharmony_ci    // fill up filesystem so only ~16 blocks are left
8819ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
8919ea8026Sopenharmony_ci    lfs_file_t file;
9019ea8026Sopenharmony_ci    lfs_file_open(&lfs, &file, "padding", LFS_O_CREAT | LFS_O_WRONLY) => 0;
9119ea8026Sopenharmony_ci    uint8_t buffer[512];
9219ea8026Sopenharmony_ci    memset(buffer, 0, 512);
9319ea8026Sopenharmony_ci    while (BLOCK_COUNT - lfs_fs_size(&lfs) > 16) {
9419ea8026Sopenharmony_ci        lfs_file_write(&lfs, &file, buffer, 512) => 512;
9519ea8026Sopenharmony_ci    }
9619ea8026Sopenharmony_ci    lfs_file_close(&lfs, &file) => 0;
9719ea8026Sopenharmony_ci    // make a child dir to use in bounded space
9819ea8026Sopenharmony_ci    lfs_mkdir(&lfs, "child") => 0;
9919ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
10019ea8026Sopenharmony_ci
10119ea8026Sopenharmony_ci    lfs_mount(&lfs, cfg) => 0;
10219ea8026Sopenharmony_ci    for (unsigned j = 0; j < ITERATIONS; j++) {
10319ea8026Sopenharmony_ci        for (unsigned i = 0; i < COUNT; i++) {
10419ea8026Sopenharmony_ci            char path[1024];
10519ea8026Sopenharmony_ci            sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
10619ea8026Sopenharmony_ci            lfs_file_open(&lfs, &file, path, LFS_O_CREAT | LFS_O_WRONLY) => 0;
10719ea8026Sopenharmony_ci            lfs_file_close(&lfs, &file) => 0;
10819ea8026Sopenharmony_ci        }
10919ea8026Sopenharmony_ci
11019ea8026Sopenharmony_ci        lfs_dir_t dir;
11119ea8026Sopenharmony_ci        struct lfs_info info;
11219ea8026Sopenharmony_ci        lfs_dir_open(&lfs, &dir, "child") => 0;
11319ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
11419ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
11519ea8026Sopenharmony_ci        for (unsigned i = 0; i < COUNT; i++) {
11619ea8026Sopenharmony_ci            char path[1024];
11719ea8026Sopenharmony_ci            sprintf(path, "test%03d_loooooooooooooooooong_name", i);
11819ea8026Sopenharmony_ci            lfs_dir_read(&lfs, &dir, &info) => 1;
11919ea8026Sopenharmony_ci            strcmp(info.name, path) => 0;
12019ea8026Sopenharmony_ci            info.size => 0;
12119ea8026Sopenharmony_ci
12219ea8026Sopenharmony_ci            sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
12319ea8026Sopenharmony_ci            lfs_file_open(&lfs, &file, path, LFS_O_WRONLY) => 0;
12419ea8026Sopenharmony_ci            lfs_file_write(&lfs, &file, "hi", 2) => 2;
12519ea8026Sopenharmony_ci            lfs_file_close(&lfs, &file) => 0;
12619ea8026Sopenharmony_ci        }
12719ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 0;
12819ea8026Sopenharmony_ci
12919ea8026Sopenharmony_ci        lfs_dir_rewind(&lfs, &dir) => 0;
13019ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
13119ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
13219ea8026Sopenharmony_ci        for (unsigned i = 0; i < COUNT; i++) {
13319ea8026Sopenharmony_ci            char path[1024];
13419ea8026Sopenharmony_ci            sprintf(path, "test%03d_loooooooooooooooooong_name", i);
13519ea8026Sopenharmony_ci            lfs_dir_read(&lfs, &dir, &info) => 1;
13619ea8026Sopenharmony_ci            strcmp(info.name, path) => 0;
13719ea8026Sopenharmony_ci            info.size => 2;
13819ea8026Sopenharmony_ci
13919ea8026Sopenharmony_ci            sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
14019ea8026Sopenharmony_ci            lfs_file_open(&lfs, &file, path, LFS_O_WRONLY) => 0;
14119ea8026Sopenharmony_ci            lfs_file_write(&lfs, &file, "hi", 2) => 2;
14219ea8026Sopenharmony_ci            lfs_file_close(&lfs, &file) => 0;
14319ea8026Sopenharmony_ci        }
14419ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 0;
14519ea8026Sopenharmony_ci
14619ea8026Sopenharmony_ci        lfs_dir_rewind(&lfs, &dir) => 0;
14719ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
14819ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 1;
14919ea8026Sopenharmony_ci        for (unsigned i = 0; i < COUNT; i++) {
15019ea8026Sopenharmony_ci            char path[1024];
15119ea8026Sopenharmony_ci            sprintf(path, "test%03d_loooooooooooooooooong_name", i);
15219ea8026Sopenharmony_ci            lfs_dir_read(&lfs, &dir, &info) => 1;
15319ea8026Sopenharmony_ci            strcmp(info.name, path) => 0;
15419ea8026Sopenharmony_ci            info.size => 2;
15519ea8026Sopenharmony_ci        }
15619ea8026Sopenharmony_ci        lfs_dir_read(&lfs, &dir, &info) => 0;
15719ea8026Sopenharmony_ci        lfs_dir_close(&lfs, &dir) => 0;
15819ea8026Sopenharmony_ci
15919ea8026Sopenharmony_ci        for (unsigned i = 0; i < COUNT; i++) {
16019ea8026Sopenharmony_ci            char path[1024];
16119ea8026Sopenharmony_ci            sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
16219ea8026Sopenharmony_ci            lfs_remove(&lfs, path) => 0;
16319ea8026Sopenharmony_ci        }
16419ea8026Sopenharmony_ci    }
16519ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
16619ea8026Sopenharmony_ci'''
16719ea8026Sopenharmony_ci
16819ea8026Sopenharmony_ci# reentrant testing for relocations, this is the same as the
16919ea8026Sopenharmony_ci# orphan testing, except here we also set block_cycles so that
17019ea8026Sopenharmony_ci# almost every tree operation needs a relocation
17119ea8026Sopenharmony_ci[cases.test_relocations_reentrant]
17219ea8026Sopenharmony_cireentrant = true
17319ea8026Sopenharmony_ci# TODO fix this case, caused by non-DAG trees
17419ea8026Sopenharmony_ci# NOTE the second condition is required
17519ea8026Sopenharmony_ciif = '!(DEPTH == 3 && CACHE_SIZE != 64) && 2*FILES < BLOCK_COUNT'
17619ea8026Sopenharmony_cidefines = [
17719ea8026Sopenharmony_ci    {FILES=6,  DEPTH=1, CYCLES=20, BLOCK_CYCLES=1},
17819ea8026Sopenharmony_ci    {FILES=26, DEPTH=1, CYCLES=20, BLOCK_CYCLES=1},
17919ea8026Sopenharmony_ci    {FILES=3,  DEPTH=3, CYCLES=20, BLOCK_CYCLES=1},
18019ea8026Sopenharmony_ci]
18119ea8026Sopenharmony_cicode = '''
18219ea8026Sopenharmony_ci    lfs_t lfs;
18319ea8026Sopenharmony_ci    int err = lfs_mount(&lfs, cfg);
18419ea8026Sopenharmony_ci    if (err) {
18519ea8026Sopenharmony_ci        lfs_format(&lfs, cfg) => 0;
18619ea8026Sopenharmony_ci        lfs_mount(&lfs, cfg) => 0;
18719ea8026Sopenharmony_ci    }
18819ea8026Sopenharmony_ci
18919ea8026Sopenharmony_ci    uint32_t prng = 1;
19019ea8026Sopenharmony_ci    const char alpha[] = "abcdefghijklmnopqrstuvwxyz";
19119ea8026Sopenharmony_ci    for (unsigned i = 0; i < CYCLES; i++) {
19219ea8026Sopenharmony_ci        // create random path
19319ea8026Sopenharmony_ci        char full_path[256];
19419ea8026Sopenharmony_ci        for (unsigned d = 0; d < DEPTH; d++) {
19519ea8026Sopenharmony_ci            sprintf(&full_path[2*d], "/%c", alpha[TEST_PRNG(&prng) % FILES]);
19619ea8026Sopenharmony_ci        }
19719ea8026Sopenharmony_ci
19819ea8026Sopenharmony_ci        // if it does not exist, we create it, else we destroy
19919ea8026Sopenharmony_ci        struct lfs_info info;
20019ea8026Sopenharmony_ci        int res = lfs_stat(&lfs, full_path, &info);
20119ea8026Sopenharmony_ci        if (res == LFS_ERR_NOENT) {
20219ea8026Sopenharmony_ci            // create each directory in turn, ignore if dir already exists
20319ea8026Sopenharmony_ci            for (unsigned d = 0; d < DEPTH; d++) {
20419ea8026Sopenharmony_ci                char path[1024];
20519ea8026Sopenharmony_ci                strcpy(path, full_path);
20619ea8026Sopenharmony_ci                path[2*d+2] = '\0';
20719ea8026Sopenharmony_ci                err = lfs_mkdir(&lfs, path);
20819ea8026Sopenharmony_ci                assert(!err || err == LFS_ERR_EXIST);
20919ea8026Sopenharmony_ci            }
21019ea8026Sopenharmony_ci
21119ea8026Sopenharmony_ci            for (unsigned d = 0; d < DEPTH; d++) {
21219ea8026Sopenharmony_ci                char path[1024];
21319ea8026Sopenharmony_ci                strcpy(path, full_path);
21419ea8026Sopenharmony_ci                path[2*d+2] = '\0';
21519ea8026Sopenharmony_ci                lfs_stat(&lfs, path, &info) => 0;
21619ea8026Sopenharmony_ci                assert(strcmp(info.name, &path[2*d+1]) == 0);
21719ea8026Sopenharmony_ci                assert(info.type == LFS_TYPE_DIR);
21819ea8026Sopenharmony_ci            }
21919ea8026Sopenharmony_ci        } else {
22019ea8026Sopenharmony_ci            // is valid dir?
22119ea8026Sopenharmony_ci            assert(strcmp(info.name, &full_path[2*(DEPTH-1)+1]) == 0);
22219ea8026Sopenharmony_ci            assert(info.type == LFS_TYPE_DIR);
22319ea8026Sopenharmony_ci
22419ea8026Sopenharmony_ci            // try to delete path in reverse order, ignore if dir is not empty
22519ea8026Sopenharmony_ci            for (unsigned d = DEPTH-1; d+1 > 0; d--) {
22619ea8026Sopenharmony_ci                char path[1024];
22719ea8026Sopenharmony_ci                strcpy(path, full_path);
22819ea8026Sopenharmony_ci                path[2*d+2] = '\0';
22919ea8026Sopenharmony_ci                err = lfs_remove(&lfs, path);
23019ea8026Sopenharmony_ci                assert(!err || err == LFS_ERR_NOTEMPTY);
23119ea8026Sopenharmony_ci            }
23219ea8026Sopenharmony_ci
23319ea8026Sopenharmony_ci            lfs_stat(&lfs, full_path, &info) => LFS_ERR_NOENT;
23419ea8026Sopenharmony_ci        }
23519ea8026Sopenharmony_ci    }
23619ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
23719ea8026Sopenharmony_ci'''
23819ea8026Sopenharmony_ci
23919ea8026Sopenharmony_ci# reentrant testing for relocations, but now with random renames!
24019ea8026Sopenharmony_ci[cases.test_relocations_reentrant_renames]
24119ea8026Sopenharmony_cireentrant = true
24219ea8026Sopenharmony_ci# TODO fix this case, caused by non-DAG trees
24319ea8026Sopenharmony_ci# NOTE the second condition is required
24419ea8026Sopenharmony_ciif = '!(DEPTH == 3 && CACHE_SIZE != 64) && 2*FILES < BLOCK_COUNT'
24519ea8026Sopenharmony_cidefines = [
24619ea8026Sopenharmony_ci    {FILES=6,  DEPTH=1, CYCLES=20, BLOCK_CYCLES=1},
24719ea8026Sopenharmony_ci    {FILES=26, DEPTH=1, CYCLES=20, BLOCK_CYCLES=1},
24819ea8026Sopenharmony_ci    {FILES=3,  DEPTH=3, CYCLES=20, BLOCK_CYCLES=1},
24919ea8026Sopenharmony_ci]
25019ea8026Sopenharmony_cicode = '''
25119ea8026Sopenharmony_ci    lfs_t lfs;
25219ea8026Sopenharmony_ci    int err = lfs_mount(&lfs, cfg);
25319ea8026Sopenharmony_ci    if (err) {
25419ea8026Sopenharmony_ci        lfs_format(&lfs, cfg) => 0;
25519ea8026Sopenharmony_ci        lfs_mount(&lfs, cfg) => 0;
25619ea8026Sopenharmony_ci    }
25719ea8026Sopenharmony_ci
25819ea8026Sopenharmony_ci    uint32_t prng = 1;
25919ea8026Sopenharmony_ci    const char alpha[] = "abcdefghijklmnopqrstuvwxyz";
26019ea8026Sopenharmony_ci    for (unsigned i = 0; i < CYCLES; i++) {
26119ea8026Sopenharmony_ci        // create random path
26219ea8026Sopenharmony_ci        char full_path[256];
26319ea8026Sopenharmony_ci        for (unsigned d = 0; d < DEPTH; d++) {
26419ea8026Sopenharmony_ci            sprintf(&full_path[2*d], "/%c", alpha[TEST_PRNG(&prng) % FILES]);
26519ea8026Sopenharmony_ci        }
26619ea8026Sopenharmony_ci
26719ea8026Sopenharmony_ci        // if it does not exist, we create it, else we destroy
26819ea8026Sopenharmony_ci        struct lfs_info info;
26919ea8026Sopenharmony_ci        int res = lfs_stat(&lfs, full_path, &info);
27019ea8026Sopenharmony_ci        assert(!res || res == LFS_ERR_NOENT);
27119ea8026Sopenharmony_ci        if (res == LFS_ERR_NOENT) {
27219ea8026Sopenharmony_ci            // create each directory in turn, ignore if dir already exists
27319ea8026Sopenharmony_ci            for (unsigned d = 0; d < DEPTH; d++) {
27419ea8026Sopenharmony_ci                char path[1024];
27519ea8026Sopenharmony_ci                strcpy(path, full_path);
27619ea8026Sopenharmony_ci                path[2*d+2] = '\0';
27719ea8026Sopenharmony_ci                err = lfs_mkdir(&lfs, path);
27819ea8026Sopenharmony_ci                assert(!err || err == LFS_ERR_EXIST);
27919ea8026Sopenharmony_ci            }
28019ea8026Sopenharmony_ci
28119ea8026Sopenharmony_ci            for (unsigned d = 0; d < DEPTH; d++) {
28219ea8026Sopenharmony_ci                char path[1024];
28319ea8026Sopenharmony_ci                strcpy(path, full_path);
28419ea8026Sopenharmony_ci                path[2*d+2] = '\0';
28519ea8026Sopenharmony_ci                lfs_stat(&lfs, path, &info) => 0;
28619ea8026Sopenharmony_ci                assert(strcmp(info.name, &path[2*d+1]) == 0);
28719ea8026Sopenharmony_ci                assert(info.type == LFS_TYPE_DIR);
28819ea8026Sopenharmony_ci            }
28919ea8026Sopenharmony_ci        } else {
29019ea8026Sopenharmony_ci            assert(strcmp(info.name, &full_path[2*(DEPTH-1)+1]) == 0);
29119ea8026Sopenharmony_ci            assert(info.type == LFS_TYPE_DIR);
29219ea8026Sopenharmony_ci
29319ea8026Sopenharmony_ci            // create new random path
29419ea8026Sopenharmony_ci            char new_path[256];
29519ea8026Sopenharmony_ci            for (unsigned d = 0; d < DEPTH; d++) {
29619ea8026Sopenharmony_ci                sprintf(&new_path[2*d], "/%c", alpha[TEST_PRNG(&prng) % FILES]);
29719ea8026Sopenharmony_ci            }
29819ea8026Sopenharmony_ci
29919ea8026Sopenharmony_ci            // if new path does not exist, rename, otherwise destroy
30019ea8026Sopenharmony_ci            res = lfs_stat(&lfs, new_path, &info);
30119ea8026Sopenharmony_ci            assert(!res || res == LFS_ERR_NOENT);
30219ea8026Sopenharmony_ci            if (res == LFS_ERR_NOENT) {
30319ea8026Sopenharmony_ci                // stop once some dir is renamed
30419ea8026Sopenharmony_ci                for (unsigned d = 0; d < DEPTH; d++) {
30519ea8026Sopenharmony_ci                    char path[1024];
30619ea8026Sopenharmony_ci                    strcpy(&path[2*d], &full_path[2*d]);
30719ea8026Sopenharmony_ci                    path[2*d+2] = '\0';
30819ea8026Sopenharmony_ci                    strcpy(&path[128+2*d], &new_path[2*d]);
30919ea8026Sopenharmony_ci                    path[128+2*d+2] = '\0';
31019ea8026Sopenharmony_ci                    err = lfs_rename(&lfs, path, path+128);
31119ea8026Sopenharmony_ci                    assert(!err || err == LFS_ERR_NOTEMPTY);
31219ea8026Sopenharmony_ci                    if (!err) {
31319ea8026Sopenharmony_ci                        strcpy(path, path+128);
31419ea8026Sopenharmony_ci                    }
31519ea8026Sopenharmony_ci                }
31619ea8026Sopenharmony_ci
31719ea8026Sopenharmony_ci                for (unsigned d = 0; d < DEPTH; d++) {
31819ea8026Sopenharmony_ci                    char path[1024];
31919ea8026Sopenharmony_ci                    strcpy(path, new_path);
32019ea8026Sopenharmony_ci                    path[2*d+2] = '\0';
32119ea8026Sopenharmony_ci                    lfs_stat(&lfs, path, &info) => 0;
32219ea8026Sopenharmony_ci                    assert(strcmp(info.name, &path[2*d+1]) == 0);
32319ea8026Sopenharmony_ci                    assert(info.type == LFS_TYPE_DIR);
32419ea8026Sopenharmony_ci                }
32519ea8026Sopenharmony_ci                
32619ea8026Sopenharmony_ci                lfs_stat(&lfs, full_path, &info) => LFS_ERR_NOENT;
32719ea8026Sopenharmony_ci            } else {
32819ea8026Sopenharmony_ci                // try to delete path in reverse order,
32919ea8026Sopenharmony_ci                // ignore if dir is not empty
33019ea8026Sopenharmony_ci                for (unsigned d = DEPTH-1; d+1 > 0; d--) {
33119ea8026Sopenharmony_ci                    char path[1024];
33219ea8026Sopenharmony_ci                    strcpy(path, full_path);
33319ea8026Sopenharmony_ci                    path[2*d+2] = '\0';
33419ea8026Sopenharmony_ci                    err = lfs_remove(&lfs, path);
33519ea8026Sopenharmony_ci                    assert(!err || err == LFS_ERR_NOTEMPTY);
33619ea8026Sopenharmony_ci                }
33719ea8026Sopenharmony_ci
33819ea8026Sopenharmony_ci                lfs_stat(&lfs, full_path, &info) => LFS_ERR_NOENT;
33919ea8026Sopenharmony_ci            }
34019ea8026Sopenharmony_ci        }
34119ea8026Sopenharmony_ci    }
34219ea8026Sopenharmony_ci    lfs_unmount(&lfs) => 0;
34319ea8026Sopenharmony_ci'''
344