mirror of
https://github.com/eledio-devices/thirdparty-littlefs.git
synced 2025-11-01 08:48:31 +01:00
WIP changed type to be retrieved from name not struct
This commit is contained in:
187
lfs.c
187
lfs.c
@@ -1402,27 +1402,30 @@ static int lfs_dir_getentry(lfs_t *lfs, lfs_mdir_t *dir,
|
|||||||
|
|
||||||
static int lfs_dir_getinfo(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) {
|
int16_t id, struct lfs_info *info) {
|
||||||
lfs_mattr_t attr;
|
lfs_mattr_t attr = {
|
||||||
int err = lfs_dir_getentry(lfs, dir, 0x703ff000,
|
lfs_mktag(LFS_STRUCT_NAME, id, lfs->name_size+1),
|
||||||
|
.u.buffer=info->name,
|
||||||
|
};
|
||||||
|
|
||||||
|
int err = lfs_dir_getbuffer(lfs, dir, 0x71fff000, &attr);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->type = 0x38 & lfs_tag_subtype(attr.tag);
|
||||||
|
|
||||||
|
err = lfs_dir_getentry(lfs, dir, 0x703ff000,
|
||||||
lfs_mktag(LFS_SCOPE_STRUCT, id, 0), &attr);
|
lfs_mktag(LFS_SCOPE_STRUCT, id, 0), &attr);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->type = lfs_tag_subtype(attr.tag);
|
|
||||||
if (lfs_tag_struct(attr.tag) == LFS_STRUCT_CTZ) {
|
if (lfs_tag_struct(attr.tag) == LFS_STRUCT_CTZ) {
|
||||||
info->size = attr.u.ctz.size;
|
info->size = attr.u.ctz.size;
|
||||||
} else if (lfs_tag_struct(attr.tag) == LFS_STRUCT_INLINE) {
|
} else if (lfs_tag_struct(attr.tag) == LFS_STRUCT_INLINE) {
|
||||||
info->size = lfs_tag_size(attr.tag);
|
info->size = lfs_tag_size(attr.tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = lfs_dir_getbuffer(lfs, dir, 0x71fff000, &(lfs_mattr_t){
|
|
||||||
lfs_mktag(LFS_STRUCT_NAME, id, lfs->name_size+1),
|
|
||||||
.u.buffer=info->name});
|
|
||||||
if (err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1431,6 +1434,8 @@ struct lfs_dir_find {
|
|||||||
uint16_t len;
|
uint16_t len;
|
||||||
int16_t id;
|
int16_t id;
|
||||||
int16_t tempid;
|
int16_t tempid;
|
||||||
|
uint8_t findtype;
|
||||||
|
uint8_t tempfindtype;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int lfs_dir_findscan(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
static int lfs_dir_findscan(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
||||||
@@ -1447,6 +1452,7 @@ static int lfs_dir_findscan(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
|||||||
if (res) {
|
if (res) {
|
||||||
// found a match
|
// found a match
|
||||||
find->tempid = lfs_tag_id(attr.tag);
|
find->tempid = lfs_tag_id(attr.tag);
|
||||||
|
find->tempfindtype = 0x38 & lfs_tag_subtype(attr.tag);
|
||||||
}
|
}
|
||||||
} else if (lfs_tag_type(attr.tag) == LFS_STRUCT_DELETE) {
|
} else if (lfs_tag_type(attr.tag) == LFS_STRUCT_DELETE) {
|
||||||
if (lfs_tag_id(attr.tag) == find->tempid) {
|
if (lfs_tag_id(attr.tag) == find->tempid) {
|
||||||
@@ -1456,6 +1462,7 @@ static int lfs_dir_findscan(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
|||||||
}
|
}
|
||||||
} else if (lfs_tag_type(attr.tag) == LFS_TYPE_CRC) {
|
} else if (lfs_tag_type(attr.tag) == LFS_TYPE_CRC) {
|
||||||
find->id = find->tempid;
|
find->id = find->tempid;
|
||||||
|
find->findtype = find->tempfindtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1463,7 +1470,7 @@ static int lfs_dir_findscan(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
|||||||
|
|
||||||
// TODO drop others, make this only return id, also make get take in only entry to populate (with embedded tag)
|
// TODO drop others, make this only return id, also make get take in only entry to populate (with embedded tag)
|
||||||
static int lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir,
|
static int lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir,
|
||||||
const char **path, uint16_t *id) {
|
const char **path, uint16_t *id, uint8_t *type) {
|
||||||
lfs_mattr_t attr = {
|
lfs_mattr_t attr = {
|
||||||
.u.pair[0] = lfs->root[0],
|
.u.pair[0] = lfs->root[0],
|
||||||
.u.pair[1] = lfs->root[1],
|
.u.pair[1] = lfs->root[1],
|
||||||
@@ -1482,6 +1489,8 @@ static int lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir,
|
|||||||
// special case for root dir
|
// special case for root dir
|
||||||
if (find.name[0] == '\0') {
|
if (find.name[0] == '\0') {
|
||||||
// Return ISDIR when we hit root
|
// Return ISDIR when we hit root
|
||||||
|
// TODO change this to -1 or 0x3ff?
|
||||||
|
*type = LFS_TYPE_DIR;
|
||||||
return LFS_ERR_ISDIR;
|
return LFS_ERR_ISDIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1544,12 +1553,19 @@ static int lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir,
|
|||||||
}
|
}
|
||||||
|
|
||||||
*id = find.id;
|
*id = find.id;
|
||||||
|
*type = find.findtype;
|
||||||
find.name += find.len;
|
find.name += find.len;
|
||||||
find.name += strspn(find.name, "/");
|
find.name += strspn(find.name, "/");
|
||||||
if (find.name[0] == '\0') {
|
if (find.name[0] == '\0') {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// don't continue on if we didn't hit a directory
|
||||||
|
// TODO update with what's on master?
|
||||||
|
if (find.findtype != LFS_TYPE_DIR) {
|
||||||
|
return LFS_ERR_NOTDIR;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO optimize grab for inline files and like?
|
// TODO optimize grab for inline files and like?
|
||||||
// TODO would this mean more code?
|
// TODO would this mean more code?
|
||||||
// grab the entry data
|
// grab the entry data
|
||||||
@@ -1558,12 +1574,6 @@ static int lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir,
|
|||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// continue on if we hit a directory
|
|
||||||
// TODO update with what's on master?
|
|
||||||
if (lfs_tag_subtype(attr.tag) != LFS_TYPE_DIR) {
|
|
||||||
return LFS_ERR_NOTDIR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1578,7 +1588,7 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lfs_mdir_t cwd;
|
lfs_mdir_t cwd;
|
||||||
int err = lfs_dir_find(lfs, &cwd, &path, &(uint16_t){0});
|
int err = lfs_dir_find(lfs, &cwd, &path, &(uint16_t){0}, &(uint8_t){0});
|
||||||
if (err != LFS_ERR_NOENT || strchr(path, '/') != NULL) {
|
if (err != LFS_ERR_NOENT || strchr(path, '/') != NULL) {
|
||||||
if (!err || err == LFS_ERR_ISDIR) {
|
if (!err || err == LFS_ERR_ISDIR) {
|
||||||
return LFS_ERR_EXIST;
|
return LFS_ERR_EXIST;
|
||||||
@@ -1618,7 +1628,7 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
|
|||||||
err = lfs_dir_commit(lfs, &cwd, &(lfs_mattrlist_t){
|
err = lfs_dir_commit(lfs, &cwd, &(lfs_mattrlist_t){
|
||||||
{lfs_mktag(LFS_STRUCT_NAME | LFS_TYPE_DIR, id, nlen),
|
{lfs_mktag(LFS_STRUCT_NAME | LFS_TYPE_DIR, id, nlen),
|
||||||
.u.buffer=(void*)path}, &(lfs_mattrlist_t){
|
.u.buffer=(void*)path}, &(lfs_mattrlist_t){
|
||||||
{lfs_mktag(LFS_STRUCT_DIR | LFS_TYPE_DIR, id, sizeof(dir.pair)),
|
{lfs_mktag(LFS_STRUCT_DIR, id, sizeof(dir.pair)),
|
||||||
.u.buffer=dir.pair}, &(lfs_mattrlist_t){
|
.u.buffer=dir.pair}, &(lfs_mattrlist_t){
|
||||||
{lfs_mktag(LFS_TYPE_SOFTTAIL, 0x3ff, sizeof(cwd.tail)),
|
{lfs_mktag(LFS_TYPE_SOFTTAIL, 0x3ff, sizeof(cwd.tail)),
|
||||||
.u.buffer=cwd.tail}}}});
|
.u.buffer=cwd.tail}}}});
|
||||||
@@ -1630,11 +1640,16 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
|
|||||||
|
|
||||||
int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
|
int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
|
||||||
uint16_t id;
|
uint16_t id;
|
||||||
int err = lfs_dir_find(lfs, &dir->m, &path, &id);
|
uint8_t type;
|
||||||
|
int err = lfs_dir_find(lfs, &dir->m, &path, &id, &type);
|
||||||
if (err && err != LFS_ERR_ISDIR) {
|
if (err && err != LFS_ERR_ISDIR) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type != LFS_TYPE_DIR) {
|
||||||
|
return LFS_ERR_NOTDIR;
|
||||||
|
}
|
||||||
|
|
||||||
lfs_mattr_t attr;
|
lfs_mattr_t attr;
|
||||||
if (err == LFS_ERR_ISDIR) {
|
if (err == LFS_ERR_ISDIR) {
|
||||||
// handle root dir separately
|
// handle root dir separately
|
||||||
@@ -1647,10 +1662,6 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
|
|||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lfs_tag_subtype(attr.tag) != LFS_TYPE_DIR) {
|
|
||||||
return LFS_ERR_NOTDIR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch first pair
|
// fetch first pair
|
||||||
@@ -1982,8 +1993,10 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
|
|||||||
// allocate entry for file if it doesn't exist
|
// allocate entry for file if it doesn't exist
|
||||||
lfs_mdir_t cwd;
|
lfs_mdir_t cwd;
|
||||||
uint16_t id;
|
uint16_t id;
|
||||||
int err = lfs_dir_find(lfs, &cwd, &path, &id);
|
uint8_t type;
|
||||||
if (err && (err != LFS_ERR_NOENT || strchr(path, '/') != NULL)) {
|
int err = lfs_dir_find(lfs, &cwd, &path, &id, &type);
|
||||||
|
if (err && (err != LFS_ERR_NOENT || strchr(path, '/') != NULL) &&
|
||||||
|
err != LFS_ERR_ISDIR) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2009,7 +2022,7 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
|
|||||||
err = lfs_dir_commit(lfs, &cwd, &(lfs_mattrlist_t){
|
err = lfs_dir_commit(lfs, &cwd, &(lfs_mattrlist_t){
|
||||||
{lfs_mktag(LFS_STRUCT_NAME | LFS_TYPE_REG, id, nlen),
|
{lfs_mktag(LFS_STRUCT_NAME | LFS_TYPE_REG, id, nlen),
|
||||||
.u.buffer=(void*)path}, &(lfs_mattrlist_t){
|
.u.buffer=(void*)path}, &(lfs_mattrlist_t){
|
||||||
{lfs_mktag(LFS_STRUCT_INLINE | LFS_TYPE_REG, id, 0)}}});
|
{lfs_mktag(LFS_STRUCT_INLINE, id, 0)}}});
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -2022,9 +2035,9 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
|
|||||||
cwd.pair[1] = cwd.tail[1];
|
cwd.pair[1] = cwd.tail[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
attr.tag = lfs_mktag(LFS_STRUCT_INLINE | LFS_TYPE_REG, id, 0);
|
attr.tag = lfs_mktag(LFS_STRUCT_INLINE, id, 0);
|
||||||
} else {
|
} else {
|
||||||
if (id == -1) {
|
if (type != LFS_TYPE_REG) {
|
||||||
return LFS_ERR_ISDIR;
|
return LFS_ERR_ISDIR;
|
||||||
} else if (flags & LFS_O_EXCL) {
|
} else if (flags & LFS_O_EXCL) {
|
||||||
return LFS_ERR_EXIST;
|
return LFS_ERR_EXIST;
|
||||||
@@ -2035,10 +2048,6 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
|
|||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lfs_tag_subtype(attr.tag) != LFS_TYPE_REG) {
|
|
||||||
return LFS_ERR_ISDIR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup file struct
|
// setup file struct
|
||||||
@@ -2267,7 +2276,7 @@ int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) {
|
|||||||
// either update the references or inline the whole file
|
// either update the references or inline the whole file
|
||||||
if (!(file->flags & LFS_F_INLINE)) {
|
if (!(file->flags & LFS_F_INLINE)) {
|
||||||
int err = lfs_dir_commit(lfs, &cwd, &(lfs_mattrlist_t){
|
int err = lfs_dir_commit(lfs, &cwd, &(lfs_mattrlist_t){
|
||||||
{lfs_mktag(LFS_STRUCT_CTZ | LFS_TYPE_REG,
|
{lfs_mktag(LFS_STRUCT_CTZ,
|
||||||
file->id, 2*sizeof(uint32_t)), .u.buffer=&file->head},
|
file->id, 2*sizeof(uint32_t)), .u.buffer=&file->head},
|
||||||
file->attrs});
|
file->attrs});
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -2275,7 +2284,7 @@ int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int err = lfs_dir_commit(lfs, &cwd, &(lfs_mattrlist_t){
|
int err = lfs_dir_commit(lfs, &cwd, &(lfs_mattrlist_t){
|
||||||
{lfs_mktag(LFS_STRUCT_INLINE | LFS_TYPE_REG,
|
{lfs_mktag(LFS_STRUCT_INLINE,
|
||||||
file->id, file->size), .u.buffer=file->cache.buffer},
|
file->id, file->size), .u.buffer=file->cache.buffer},
|
||||||
file->attrs});
|
file->attrs});
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -2660,7 +2669,8 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) {
|
|||||||
int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) {
|
int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) {
|
||||||
lfs_mdir_t cwd;
|
lfs_mdir_t cwd;
|
||||||
uint16_t id;
|
uint16_t id;
|
||||||
int err = lfs_dir_find(lfs, &cwd, &path, &id);
|
// TODO pass to getinfo?
|
||||||
|
int err = lfs_dir_find(lfs, &cwd, &path, &id, &(uint8_t){0});
|
||||||
if (err && err != LFS_ERR_ISDIR) {
|
if (err && err != LFS_ERR_ISDIR) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -2691,12 +2701,15 @@ int lfs_remove(lfs_t *lfs, const char *path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint16_t id;
|
uint16_t id;
|
||||||
err = lfs_dir_find(lfs, &cwd, &path, &id);
|
uint8_t type;
|
||||||
|
err = lfs_dir_find(lfs, &cwd, &path, &id, &type);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// grab entry to see if we're dealing with a dir
|
lfs_mdir_t dir;
|
||||||
|
if (type == LFS_TYPE_DIR) {
|
||||||
|
// must be empty before removal
|
||||||
lfs_mattr_t attr;
|
lfs_mattr_t attr;
|
||||||
err = lfs_dir_getentry(lfs, &cwd, 0x703ff000,
|
err = lfs_dir_getentry(lfs, &cwd, 0x703ff000,
|
||||||
lfs_mktag(LFS_SCOPE_STRUCT, id, 0), &attr);
|
lfs_mktag(LFS_SCOPE_STRUCT, id, 0), &attr);
|
||||||
@@ -2704,9 +2717,6 @@ int lfs_remove(lfs_t *lfs, const char *path) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
lfs_mdir_t dir;
|
|
||||||
if (lfs_tag_subtype(attr.tag) == LFS_TYPE_DIR) {
|
|
||||||
// must be empty before removal
|
|
||||||
err = lfs_dir_fetch(lfs, &dir, attr.u.pair);
|
err = lfs_dir_fetch(lfs, &dir, attr.u.pair);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
@@ -2716,38 +2726,6 @@ int lfs_remove(lfs_t *lfs, const char *path) {
|
|||||||
if (dir.count > 0 || dir.split) {
|
if (dir.count > 0 || dir.split) {
|
||||||
return LFS_ERR_NOTEMPTY;
|
return LFS_ERR_NOTEMPTY;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// // unlink from tail chain and create move to fix
|
|
||||||
// lfs->diff.move.pair[0] = cwd.pair[0] ^ lfs->globals.move.pair[0];
|
|
||||||
// lfs->diff.move.pair[1] = cwd.pair[1] ^ lfs->globals.move.pair[1];
|
|
||||||
// lfs->diff.move.id = id ^ lfs->globals.move.id;
|
|
||||||
//
|
|
||||||
// // xor over our child's global state
|
|
||||||
// lfs->diff = lfs_globals_xor(&lfs->diff, &dir.globals);
|
|
||||||
// lfs->globals = lfs_globals_xor(&lfs->globals, &dir.globals);
|
|
||||||
//
|
|
||||||
// // find pred and remove
|
|
||||||
// // TODO handle dropped block?
|
|
||||||
// lfs_mdir_t pred;
|
|
||||||
// int res = lfs_pred(lfs, dir.pair, &pred);
|
|
||||||
// if (res < 0) {
|
|
||||||
// return res;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// LFS_ASSERT(res); // must have pred
|
|
||||||
// pred.tail[0] = dir.tail[0];
|
|
||||||
// pred.tail[1] = dir.tail[1];
|
|
||||||
// err = lfs_dir_commit(lfs, &pred, &(lfs_mattrlist_t){
|
|
||||||
// {lfs_mktag(LFS_TYPE_SOFTTAIL, 0x3ff, sizeof(pred.tail)),
|
|
||||||
// .u.buffer=pred.tail}});
|
|
||||||
// if (err) {
|
|
||||||
// return err;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // mark global state to clear move entry
|
|
||||||
// lfs->diff.move.pair[0] = 0xffffffff ^ lfs->globals.move.pair[0];
|
|
||||||
// lfs->diff.move.pair[1] = 0xffffffff ^ lfs->globals.move.pair[1];
|
|
||||||
// lfs->diff.move.id = 0x3ff ^ lfs->globals.move.id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the entry
|
// delete the entry
|
||||||
@@ -2756,15 +2734,7 @@ int lfs_remove(lfs_t *lfs, const char *path) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// // if we were a directory, fix the move we just created
|
if (type == LFS_TYPE_DIR) {
|
||||||
// if (lfs_tag_subtype(attr.tag) == LFS_TYPE_DIR) {
|
|
||||||
// err = lfs_deorphan(lfs);
|
|
||||||
// if (err) {
|
|
||||||
// return err;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (lfs_tag_subtype(attr.tag) == LFS_TYPE_DIR) {
|
|
||||||
int res = lfs_pred(lfs, dir.pair, &cwd);
|
int res = lfs_pred(lfs, dir.pair, &cwd);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return res;
|
return res;
|
||||||
@@ -2793,14 +2763,8 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
|
|||||||
// find old entry
|
// find old entry
|
||||||
lfs_mdir_t oldcwd;
|
lfs_mdir_t oldcwd;
|
||||||
uint16_t oldid;
|
uint16_t oldid;
|
||||||
int err = lfs_dir_find(lfs, &oldcwd, &oldpath, &oldid);
|
uint8_t oldtype;
|
||||||
if (err) {
|
int err = lfs_dir_find(lfs, &oldcwd, &oldpath, &oldid, &oldtype);
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
lfs_mattr_t oldattr;
|
|
||||||
err = lfs_dir_getentry(lfs, &oldcwd, 0x703ff000,
|
|
||||||
lfs_mktag(LFS_SCOPE_STRUCT, oldid, 0), &oldattr);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -2808,7 +2772,8 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
|
|||||||
// find new entry
|
// find new entry
|
||||||
lfs_mdir_t newcwd;
|
lfs_mdir_t newcwd;
|
||||||
uint16_t newid;
|
uint16_t newid;
|
||||||
err = lfs_dir_find(lfs, &newcwd, &newpath, &newid);
|
uint8_t prevtype;
|
||||||
|
err = lfs_dir_find(lfs, &newcwd, &newpath, &newid, &prevtype);
|
||||||
if (err && err != LFS_ERR_NOENT) {
|
if (err && err != LFS_ERR_NOENT) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -2816,21 +2781,22 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
|
|||||||
bool prevexists = (err != LFS_ERR_NOENT);
|
bool prevexists = (err != LFS_ERR_NOENT);
|
||||||
//bool samepair = (lfs_paircmp(oldcwd.pair, newcwd.pair) == 0);
|
//bool samepair = (lfs_paircmp(oldcwd.pair, newcwd.pair) == 0);
|
||||||
|
|
||||||
lfs_mattr_t prevattr;
|
|
||||||
lfs_mdir_t prevdir;
|
lfs_mdir_t prevdir;
|
||||||
if (prevexists) {
|
if (prevexists) {
|
||||||
// get prev entry, check that we have same type
|
// check that we have same type
|
||||||
|
if (prevtype != oldtype) {
|
||||||
|
return LFS_ERR_ISDIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prevtype == LFS_TYPE_DIR) {
|
||||||
|
// must be empty before removal
|
||||||
|
lfs_mattr_t prevattr;
|
||||||
err = lfs_dir_getentry(lfs, &newcwd, 0x703ff000,
|
err = lfs_dir_getentry(lfs, &newcwd, 0x703ff000,
|
||||||
lfs_mktag(LFS_SCOPE_STRUCT, newid, 0), &prevattr);
|
lfs_mktag(LFS_SCOPE_STRUCT, newid, 0), &prevattr);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lfs_tag_subtype(prevattr.tag) != lfs_tag_subtype(oldattr.tag)) {
|
|
||||||
return LFS_ERR_ISDIR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lfs_tag_subtype(prevattr.tag) == LFS_TYPE_DIR) {
|
|
||||||
// must be empty before removal
|
// must be empty before removal
|
||||||
err = lfs_dir_fetch(lfs, &prevdir, prevattr.u.pair);
|
err = lfs_dir_fetch(lfs, &prevdir, prevattr.u.pair);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -2862,8 +2828,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
|
|||||||
|
|
||||||
// move over all attributes
|
// move over all attributes
|
||||||
err = lfs_dir_commit(lfs, &newcwd, &(lfs_mattrlist_t){
|
err = lfs_dir_commit(lfs, &newcwd, &(lfs_mattrlist_t){
|
||||||
{lfs_mktag(LFS_STRUCT_NAME | lfs_tag_subtype(oldattr.tag),
|
{lfs_mktag(LFS_STRUCT_NAME | oldtype, newid, strlen(newpath)),
|
||||||
newid, strlen(newpath)),
|
|
||||||
.u.buffer=(void*)newpath}, &(lfs_mattrlist_t){
|
.u.buffer=(void*)newpath}, &(lfs_mattrlist_t){
|
||||||
{lfs_mktag(LFS_FROM_MOVE, newid, oldid),
|
{lfs_mktag(LFS_FROM_MOVE, newid, oldid),
|
||||||
.u.dir=&oldcwd}}});
|
.u.dir=&oldcwd}}});
|
||||||
@@ -2877,7 +2842,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prevexists && lfs_tag_subtype(prevattr.tag) == LFS_TYPE_DIR) {
|
if (prevexists && prevtype == LFS_TYPE_DIR) {
|
||||||
int res = lfs_pred(lfs, prevdir.pair, &newcwd);
|
int res = lfs_pred(lfs, prevdir.pair, &newcwd);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return res;
|
return res;
|
||||||
@@ -3104,8 +3069,6 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
|
|
||||||
// write one superblock
|
// write one superblock
|
||||||
lfs_superblock_t superblock = {
|
lfs_superblock_t superblock = {
|
||||||
.root[0] = lfs->root[0],
|
|
||||||
.root[1] = lfs->root[1],
|
|
||||||
.magic = {"littlefs"},
|
.magic = {"littlefs"},
|
||||||
.version = LFS_DISK_VERSION,
|
.version = LFS_DISK_VERSION,
|
||||||
|
|
||||||
@@ -3118,8 +3081,10 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
|
|
||||||
dir.count += 1;
|
dir.count += 1;
|
||||||
err = lfs_dir_commit(lfs, &dir, &(lfs_mattrlist_t){
|
err = lfs_dir_commit(lfs, &dir, &(lfs_mattrlist_t){
|
||||||
{lfs_mktag(LFS_TYPE_SUPERBLOCK | LFS_STRUCT_DIR,
|
{lfs_mktag(LFS_TYPE_SUPERBLOCK, 0, sizeof(superblock)),
|
||||||
0, sizeof(superblock)), .u.buffer=&superblock}});
|
.u.buffer=&superblock}, &(lfs_mattrlist_t){
|
||||||
|
{lfs_mktag(LFS_STRUCT_DIR, 0, sizeof(lfs->root)),
|
||||||
|
.u.buffer=lfs->root}}});
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -3156,7 +3121,7 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lfs_superblock_t superblock;
|
lfs_superblock_t superblock;
|
||||||
err = lfs_dir_getbuffer(lfs, &dir, 0x7e3ff000, &(lfs_mattr_t){
|
err = lfs_dir_getbuffer(lfs, &dir, 0x7ffff000, &(lfs_mattr_t){
|
||||||
lfs_mktag(LFS_TYPE_SUPERBLOCK, 0, sizeof(superblock)),
|
lfs_mktag(LFS_TYPE_SUPERBLOCK, 0, sizeof(superblock)),
|
||||||
.u.buffer=&superblock});
|
.u.buffer=&superblock});
|
||||||
if (err && err != LFS_ERR_RANGE) {
|
if (err && err != LFS_ERR_RANGE) {
|
||||||
@@ -3176,6 +3141,13 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
return LFS_ERR_INVAL;
|
return LFS_ERR_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = lfs_dir_getbuffer(lfs, &dir, 0x7ffff000, &(lfs_mattr_t){
|
||||||
|
lfs_mktag(LFS_STRUCT_DIR, 0, sizeof(lfs->root)),
|
||||||
|
.u.buffer=lfs->root});
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (superblock.inline_size) {
|
if (superblock.inline_size) {
|
||||||
if (superblock.inline_size > lfs->inline_size) {
|
if (superblock.inline_size > lfs->inline_size) {
|
||||||
LFS_ERROR("Unsupported inline size (%d > %d)",
|
LFS_ERROR("Unsupported inline size (%d > %d)",
|
||||||
@@ -3206,9 +3178,6 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
lfs->name_size = superblock.name_size;
|
lfs->name_size = superblock.name_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
lfs->root[0] = superblock.root[0];
|
|
||||||
lfs->root[1] = superblock.root[1];
|
|
||||||
|
|
||||||
err = lfs_scan(lfs);
|
err = lfs_scan(lfs);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
5
lfs.h
5
lfs.h
@@ -98,7 +98,7 @@ enum lfs_type {
|
|||||||
// file types
|
// file types
|
||||||
LFS_TYPE_REG = 0x008,
|
LFS_TYPE_REG = 0x008,
|
||||||
LFS_TYPE_DIR = 0x010,
|
LFS_TYPE_DIR = 0x010,
|
||||||
LFS_TYPE_SUPERBLOCK = 0x038,
|
LFS_TYPE_SUPERBLOCK = 0x042,
|
||||||
|
|
||||||
// internally used entry structures
|
// internally used entry structures
|
||||||
LFS_STRUCT_CTZ = 0x001,
|
LFS_STRUCT_CTZ = 0x001,
|
||||||
@@ -316,8 +316,8 @@ typedef struct lfs_mdir {
|
|||||||
uint16_t count;
|
uint16_t count;
|
||||||
bool erased;
|
bool erased;
|
||||||
bool split;
|
bool split;
|
||||||
lfs_globals_t globals;
|
|
||||||
bool stop_at_commit; // TODO hmmm
|
bool stop_at_commit; // TODO hmmm
|
||||||
|
lfs_globals_t globals;
|
||||||
} lfs_mdir_t;
|
} lfs_mdir_t;
|
||||||
|
|
||||||
typedef struct lfs_cache {
|
typedef struct lfs_cache {
|
||||||
@@ -352,7 +352,6 @@ typedef struct lfs_dir {
|
|||||||
} lfs_dir_t;
|
} lfs_dir_t;
|
||||||
|
|
||||||
typedef struct lfs_superblock {
|
typedef struct lfs_superblock {
|
||||||
lfs_block_t root[2];
|
|
||||||
char magic[8];
|
char magic[8];
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user