mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Squashed 'littlefs/' changes from 996cd8a..5ee20e8
5ee20e8 Fixed pipefail issue that was preventing CI from reporting errors bf78b09 Added directory list for synchronizing in flight directories e169d06 Removed vestigial function declaration git-subtree-dir: littlefs git-subtree-split: 5ee20e8d774adf0bb538269870b3552fdfc0e046pull/6179/head
							parent
							
								
									0a197465d3
								
							
						
					
					
						commit
						3eb2f38279
					
				
							
								
								
									
										4
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										4
									
								
								Makefile
								
								
								
								
							| 
						 | 
				
			
			@ -11,6 +11,8 @@ ASM := $(SRC:.c=.s)
 | 
			
		|||
 | 
			
		||||
TEST := $(patsubst tests/%.sh,%,$(wildcard tests/test_*))
 | 
			
		||||
 | 
			
		||||
SHELL = /bin/bash -o pipefail
 | 
			
		||||
 | 
			
		||||
ifdef DEBUG
 | 
			
		||||
CFLAGS += -O0 -g3
 | 
			
		||||
else
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +37,7 @@ test: test_format test_dirs test_files test_seek test_parallel \
 | 
			
		|||
	test_alloc test_paths test_orphan test_move test_corrupt
 | 
			
		||||
test_%: tests/test_%.sh
 | 
			
		||||
ifdef QUIET
 | 
			
		||||
	./$< | sed '/^[^-=]/d'
 | 
			
		||||
	./$< | sed -n '/^[-=]/p'
 | 
			
		||||
else
 | 
			
		||||
	./$<
 | 
			
		||||
endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										82
									
								
								lfs.c
								
								
								
								
							
							
						
						
									
										82
									
								
								lfs.c
								
								
								
								
							| 
						 | 
				
			
			@ -569,7 +569,18 @@ relocate:
 | 
			
		|||
        // update references if we relocated
 | 
			
		||||
        LFS_DEBUG("Relocating %d %d to %d %d",
 | 
			
		||||
                oldpair[0], oldpair[1], dir->pair[0], dir->pair[1]);
 | 
			
		||||
        return lfs_relocate(lfs, oldpair, dir->pair);
 | 
			
		||||
        int err = lfs_relocate(lfs, oldpair, dir->pair);
 | 
			
		||||
        if (err) {
 | 
			
		||||
            return err;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // shift over any directories that are affected
 | 
			
		||||
    for (lfs_dir_t *d = lfs->dirs; d; d = d->next) {
 | 
			
		||||
        if (lfs_paircmp(d->pair, dir->pair) == 0) {
 | 
			
		||||
            d->pair[0] = dir->pair[0];
 | 
			
		||||
            d->pair[1] = dir->pair[1];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -628,7 +639,7 @@ static int lfs_dir_append(lfs_t *lfs, lfs_dir_t *dir,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static int lfs_dir_remove(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) {
 | 
			
		||||
    // either shift out the one entry or remove the whole dir block
 | 
			
		||||
    // check if we should just drop the directory block
 | 
			
		||||
    if ((dir->d.size & 0x7fffffff) == sizeof(dir->d)+4
 | 
			
		||||
            + lfs_entry_size(entry)) {
 | 
			
		||||
        lfs_dir_t pdir;
 | 
			
		||||
| 
						 | 
				
			
			@ -637,38 +648,44 @@ static int lfs_dir_remove(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) {
 | 
			
		|||
            return res;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!(pdir.d.size & 0x80000000)) {
 | 
			
		||||
            return lfs_dir_commit(lfs, dir, (struct lfs_region[]){
 | 
			
		||||
                    {entry->off, lfs_entry_size(entry), NULL, 0},
 | 
			
		||||
                }, 1);
 | 
			
		||||
        } else {
 | 
			
		||||
        if (pdir.d.size & 0x80000000) {
 | 
			
		||||
            pdir.d.size &= dir->d.size | 0x7fffffff;
 | 
			
		||||
            pdir.d.tail[0] = dir->d.tail[0];
 | 
			
		||||
            pdir.d.tail[1] = dir->d.tail[1];
 | 
			
		||||
            return lfs_dir_commit(lfs, &pdir, NULL, 0);
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        int err = lfs_dir_commit(lfs, dir, (struct lfs_region[]){
 | 
			
		||||
                {entry->off, lfs_entry_size(entry), NULL, 0},
 | 
			
		||||
            }, 1);
 | 
			
		||||
        if (err) {
 | 
			
		||||
            return err;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        // shift over any files that are affected
 | 
			
		||||
        for (lfs_file_t *f = lfs->files; f; f = f->next) {
 | 
			
		||||
            if (lfs_paircmp(f->pair, dir->pair) == 0) {
 | 
			
		||||
                if (f->poff == entry->off) {
 | 
			
		||||
                    f->pair[0] = 0xffffffff;
 | 
			
		||||
                    f->pair[1] = 0xffffffff;
 | 
			
		||||
                } else if (f->poff > entry->off) {
 | 
			
		||||
                    f->poff -= lfs_entry_size(entry);
 | 
			
		||||
                }
 | 
			
		||||
    // shift out the entry
 | 
			
		||||
    int err = lfs_dir_commit(lfs, dir, (struct lfs_region[]){
 | 
			
		||||
            {entry->off, lfs_entry_size(entry), NULL, 0},
 | 
			
		||||
        }, 1);
 | 
			
		||||
    if (err) {
 | 
			
		||||
        return err;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // shift over any files/directories that are affected
 | 
			
		||||
    for (lfs_file_t *f = lfs->files; f; f = f->next) {
 | 
			
		||||
        if (lfs_paircmp(f->pair, dir->pair) == 0) {
 | 
			
		||||
            if (f->poff == entry->off) {
 | 
			
		||||
                f->pair[0] = 0xffffffff;
 | 
			
		||||
                f->pair[1] = 0xffffffff;
 | 
			
		||||
            } else if (f->poff > entry->off) {
 | 
			
		||||
                f->poff -= lfs_entry_size(entry);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (lfs_dir_t *d = lfs->dirs; d; d = d->next) {
 | 
			
		||||
        if (lfs_paircmp(d->pair, dir->pair) == 0) {
 | 
			
		||||
            if (d->off > entry->off) {
 | 
			
		||||
                d->off -= lfs_entry_size(entry);
 | 
			
		||||
                d->pos -= lfs_entry_size(entry);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int lfs_dir_next(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) {
 | 
			
		||||
| 
						 | 
				
			
			@ -894,11 +911,23 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
 | 
			
		|||
    dir->head[1] = dir->pair[1];
 | 
			
		||||
    dir->pos = sizeof(dir->d) - 2;
 | 
			
		||||
    dir->off = sizeof(dir->d);
 | 
			
		||||
 | 
			
		||||
    // add to list of directories
 | 
			
		||||
    dir->next = lfs->dirs;
 | 
			
		||||
    lfs->dirs = dir;
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir) {
 | 
			
		||||
    // do nothing, dir is always synchronized
 | 
			
		||||
    // remove from list of directories
 | 
			
		||||
    for (lfs_dir_t **p = &lfs->dirs; *p; p = &(*p)->next) {
 | 
			
		||||
        if (*p == dir) {
 | 
			
		||||
            *p = dir->next;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1902,6 +1931,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
 | 
			
		|||
    lfs->root[0] = 0xffffffff;
 | 
			
		||||
    lfs->root[1] = 0xffffffff;
 | 
			
		||||
    lfs->files = NULL;
 | 
			
		||||
    lfs->dirs = NULL;
 | 
			
		||||
    lfs->deorphaned = false;
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										5
									
								
								lfs.h
								
								
								
								
							
							
						
						
									
										5
									
								
								lfs.h
								
								
								
								
							| 
						 | 
				
			
			@ -207,6 +207,7 @@ typedef struct lfs_file {
 | 
			
		|||
} lfs_file_t;
 | 
			
		||||
 | 
			
		||||
typedef struct lfs_dir {
 | 
			
		||||
    struct lfs_dir *next;
 | 
			
		||||
    lfs_block_t pair[2];
 | 
			
		||||
    lfs_off_t off;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -249,6 +250,7 @@ typedef struct lfs {
 | 
			
		|||
 | 
			
		||||
    lfs_block_t root[2];
 | 
			
		||||
    lfs_file_t *files;
 | 
			
		||||
    lfs_dir_t *dirs;
 | 
			
		||||
 | 
			
		||||
    lfs_cache_t rcache;
 | 
			
		||||
    lfs_cache_t pcache;
 | 
			
		||||
| 
						 | 
				
			
			@ -445,8 +447,5 @@ int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data);
 | 
			
		|||
// Returns a negative error code on failure.
 | 
			
		||||
int lfs_deorphan(lfs_t *lfs);
 | 
			
		||||
 | 
			
		||||
// TODO doc
 | 
			
		||||
int lfs_deduplicate(lfs_t *lfs);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -282,6 +282,49 @@ tests/test.py << TEST
 | 
			
		|||
    lfs_unmount(&lfs) => 0;
 | 
			
		||||
TEST
 | 
			
		||||
 | 
			
		||||
echo "--- Recursive remove ---"
 | 
			
		||||
tests/test.py << TEST
 | 
			
		||||
    lfs_mount(&lfs, &cfg) => 0;
 | 
			
		||||
    lfs_remove(&lfs, "coldpotato") => LFS_ERR_INVAL;
 | 
			
		||||
 | 
			
		||||
    lfs_dir_open(&lfs, &dir[0], "coldpotato") => 0;
 | 
			
		||||
    lfs_dir_read(&lfs, &dir[0], &info) => 1;
 | 
			
		||||
    lfs_dir_read(&lfs, &dir[0], &info) => 1;
 | 
			
		||||
 | 
			
		||||
    while (true) {
 | 
			
		||||
        int err = lfs_dir_read(&lfs, &dir[0], &info);
 | 
			
		||||
        err >= 0 => 1;
 | 
			
		||||
        if (err == 0) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        strcpy((char*)buffer, "coldpotato/");
 | 
			
		||||
        strcat((char*)buffer, info.name);
 | 
			
		||||
        lfs_remove(&lfs, (char*)buffer) => 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    lfs_remove(&lfs, "coldpotato") => 0;
 | 
			
		||||
TEST
 | 
			
		||||
tests/test.py << TEST
 | 
			
		||||
    lfs_mount(&lfs, &cfg) => 0;
 | 
			
		||||
    lfs_dir_open(&lfs, &dir[0], "/") => 0;
 | 
			
		||||
    lfs_dir_read(&lfs, &dir[0], &info) => 1;
 | 
			
		||||
    strcmp(info.name, ".") => 0;
 | 
			
		||||
    info.type => LFS_TYPE_DIR;
 | 
			
		||||
    lfs_dir_read(&lfs, &dir[0], &info) => 1;
 | 
			
		||||
    strcmp(info.name, "..") => 0;
 | 
			
		||||
    info.type => LFS_TYPE_DIR;
 | 
			
		||||
    lfs_dir_read(&lfs, &dir[0], &info) => 1;
 | 
			
		||||
    strcmp(info.name, "burito") => 0;
 | 
			
		||||
    info.type => LFS_TYPE_REG;
 | 
			
		||||
    lfs_dir_read(&lfs, &dir[0], &info) => 1;
 | 
			
		||||
    strcmp(info.name, "cactus") => 0;
 | 
			
		||||
    info.type => LFS_TYPE_DIR;
 | 
			
		||||
    lfs_dir_read(&lfs, &dir[0], &info) => 0;
 | 
			
		||||
    lfs_dir_close(&lfs, &dir[0]) => 0;
 | 
			
		||||
    lfs_unmount(&lfs) => 0;
 | 
			
		||||
TEST
 | 
			
		||||
 | 
			
		||||
echo "--- Multi-block remove ---"
 | 
			
		||||
tests/test.py << TEST
 | 
			
		||||
    lfs_mount(&lfs, &cfg) => 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -307,9 +350,6 @@ tests/test.py << TEST
 | 
			
		|||
    lfs_dir_read(&lfs, &dir[0], &info) => 1;
 | 
			
		||||
    strcmp(info.name, "burito") => 0;
 | 
			
		||||
    info.type => LFS_TYPE_REG;
 | 
			
		||||
    lfs_dir_read(&lfs, &dir[0], &info) => 1;
 | 
			
		||||
    strcmp(info.name, "coldpotato") => 0;
 | 
			
		||||
    info.type => LFS_TYPE_DIR;
 | 
			
		||||
    lfs_dir_read(&lfs, &dir[0], &info) => 0;
 | 
			
		||||
    lfs_dir_close(&lfs, &dir[0]) => 0;
 | 
			
		||||
    lfs_unmount(&lfs) => 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue