mirror of https://github.com/ARMmbed/mbed-os.git
Merge commit '3eb2f38279aadb35234c5df1fb8e54fd2a035be1'
commit
ad07da0da0
|
@ -11,6 +11,8 @@ ASM := $(SRC:.c=.s)
|
||||||
|
|
||||||
TEST := $(patsubst tests/%.sh,%,$(wildcard tests/test_*))
|
TEST := $(patsubst tests/%.sh,%,$(wildcard tests/test_*))
|
||||||
|
|
||||||
|
SHELL = /bin/bash -o pipefail
|
||||||
|
|
||||||
ifdef DEBUG
|
ifdef DEBUG
|
||||||
CFLAGS += -O0 -g3
|
CFLAGS += -O0 -g3
|
||||||
else
|
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_alloc test_paths test_orphan test_move test_corrupt
|
||||||
test_%: tests/test_%.sh
|
test_%: tests/test_%.sh
|
||||||
ifdef QUIET
|
ifdef QUIET
|
||||||
./$< | sed '/^[^-=]/d'
|
./$< | sed -n '/^[-=]/p'
|
||||||
else
|
else
|
||||||
./$<
|
./$<
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -569,7 +569,18 @@ relocate:
|
||||||
// update references if we relocated
|
// update references if we relocated
|
||||||
LFS_DEBUG("Relocating %ld %ld to %ld %ld",
|
LFS_DEBUG("Relocating %ld %ld to %ld %ld",
|
||||||
oldpair[0], oldpair[1], dir->pair[0], dir->pair[1]);
|
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;
|
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) {
|
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
|
if ((dir->d.size & 0x7fffffff) == sizeof(dir->d)+4
|
||||||
+ lfs_entry_size(entry)) {
|
+ lfs_entry_size(entry)) {
|
||||||
lfs_dir_t pdir;
|
lfs_dir_t pdir;
|
||||||
|
@ -637,17 +648,15 @@ static int lfs_dir_remove(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(pdir.d.size & 0x80000000)) {
|
if (pdir.d.size & 0x80000000) {
|
||||||
return lfs_dir_commit(lfs, dir, (struct lfs_region[]){
|
|
||||||
{entry->off, lfs_entry_size(entry), NULL, 0},
|
|
||||||
}, 1);
|
|
||||||
} else {
|
|
||||||
pdir.d.size &= dir->d.size | 0x7fffffff;
|
pdir.d.size &= dir->d.size | 0x7fffffff;
|
||||||
pdir.d.tail[0] = dir->d.tail[0];
|
pdir.d.tail[0] = dir->d.tail[0];
|
||||||
pdir.d.tail[1] = dir->d.tail[1];
|
pdir.d.tail[1] = dir->d.tail[1];
|
||||||
return lfs_dir_commit(lfs, &pdir, NULL, 0);
|
return lfs_dir_commit(lfs, &pdir, NULL, 0);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
// shift out the entry
|
||||||
int err = lfs_dir_commit(lfs, dir, (struct lfs_region[]){
|
int err = lfs_dir_commit(lfs, dir, (struct lfs_region[]){
|
||||||
{entry->off, lfs_entry_size(entry), NULL, 0},
|
{entry->off, lfs_entry_size(entry), NULL, 0},
|
||||||
}, 1);
|
}, 1);
|
||||||
|
@ -655,7 +664,7 @@ static int lfs_dir_remove(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// shift over any files that are affected
|
// shift over any files/directories that are affected
|
||||||
for (lfs_file_t *f = lfs->files; f; f = f->next) {
|
for (lfs_file_t *f = lfs->files; f; f = f->next) {
|
||||||
if (lfs_paircmp(f->pair, dir->pair) == 0) {
|
if (lfs_paircmp(f->pair, dir->pair) == 0) {
|
||||||
if (f->poff == entry->off) {
|
if (f->poff == entry->off) {
|
||||||
|
@ -667,8 +676,16 @@ static int lfs_dir_remove(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *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) {
|
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->head[1] = dir->pair[1];
|
||||||
dir->pos = sizeof(dir->d) - 2;
|
dir->pos = sizeof(dir->d) - 2;
|
||||||
dir->off = sizeof(dir->d);
|
dir->off = sizeof(dir->d);
|
||||||
|
|
||||||
|
// add to list of directories
|
||||||
|
dir->next = lfs->dirs;
|
||||||
|
lfs->dirs = dir;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1902,6 +1931,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
|
||||||
lfs->root[0] = 0xffffffff;
|
lfs->root[0] = 0xffffffff;
|
||||||
lfs->root[1] = 0xffffffff;
|
lfs->root[1] = 0xffffffff;
|
||||||
lfs->files = NULL;
|
lfs->files = NULL;
|
||||||
|
lfs->dirs = NULL;
|
||||||
lfs->deorphaned = false;
|
lfs->deorphaned = false;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -207,6 +207,7 @@ typedef struct lfs_file {
|
||||||
} lfs_file_t;
|
} lfs_file_t;
|
||||||
|
|
||||||
typedef struct lfs_dir {
|
typedef struct lfs_dir {
|
||||||
|
struct lfs_dir *next;
|
||||||
lfs_block_t pair[2];
|
lfs_block_t pair[2];
|
||||||
lfs_off_t off;
|
lfs_off_t off;
|
||||||
|
|
||||||
|
@ -249,6 +250,7 @@ typedef struct lfs {
|
||||||
|
|
||||||
lfs_block_t root[2];
|
lfs_block_t root[2];
|
||||||
lfs_file_t *files;
|
lfs_file_t *files;
|
||||||
|
lfs_dir_t *dirs;
|
||||||
|
|
||||||
lfs_cache_t rcache;
|
lfs_cache_t rcache;
|
||||||
lfs_cache_t pcache;
|
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.
|
// Returns a negative error code on failure.
|
||||||
int lfs_deorphan(lfs_t *lfs);
|
int lfs_deorphan(lfs_t *lfs);
|
||||||
|
|
||||||
// TODO doc
|
|
||||||
int lfs_deduplicate(lfs_t *lfs);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -282,6 +282,49 @@ tests/test.py << TEST
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
TEST
|
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 ---"
|
echo "--- Multi-block remove ---"
|
||||||
tests/test.py << TEST
|
tests/test.py << TEST
|
||||||
lfs_mount(&lfs, &cfg) => 0;
|
lfs_mount(&lfs, &cfg) => 0;
|
||||||
|
@ -307,9 +350,6 @@ tests/test.py << TEST
|
||||||
lfs_dir_read(&lfs, &dir[0], &info) => 1;
|
lfs_dir_read(&lfs, &dir[0], &info) => 1;
|
||||||
strcmp(info.name, "burito") => 0;
|
strcmp(info.name, "burito") => 0;
|
||||||
info.type => LFS_TYPE_REG;
|
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_read(&lfs, &dir[0], &info) => 0;
|
||||||
lfs_dir_close(&lfs, &dir[0]) => 0;
|
lfs_dir_close(&lfs, &dir[0]) => 0;
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
Loading…
Reference in New Issue