Skip to content

Commit ccd51a1

Browse files
committed
WIP Fixed issue with creating files named "littlefs"
1 parent 17331fe commit ccd51a1

File tree

4 files changed

+50
-40
lines changed

4 files changed

+50
-40
lines changed

lfs.c

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ static inline uint16_t lfs_tag_type(lfs_tag_t tag) {
287287
}
288288

289289
static inline uint16_t lfs_tag_subtype(lfs_tag_t tag) {
290-
return ((tag & 0x7c000000) >> 26) << 4;
290+
return ((tag & 0x78000000) >> 26) << 4;
291291
}
292292

293293
static inline uint16_t lfs_tag_id(lfs_tag_t tag) {
@@ -531,7 +531,7 @@ static int lfs_dir_traverse(lfs_t *lfs,
531531
}
532532
}
533533

534-
if (lfs_tag_subtype(tag) == LFS_TYPE_NAME) {
534+
if (lfs_tag_subtype(tag) == LFS_TYPE_CREATE) {
535535
// found where something was created
536536
if (lfs_tag_id(tag) == lfs_tag_id(matchtag - matchdiff)) {
537537
break;
@@ -673,7 +673,7 @@ static lfs_stag_t lfs_dir_fetchmatch(lfs_t *lfs,
673673
}
674674

675675
// check for special tags
676-
if (lfs_tag_subtype(tag) == LFS_TYPE_NAME) {
676+
if (lfs_tag_subtype(tag) == LFS_TYPE_CREATE) {
677677
temp.count += 1;
678678

679679
if (tempfoundtag &&
@@ -822,7 +822,7 @@ static lfs_stag_t lfs_dir_get(lfs_t *lfs, const lfs_mdir_t *dir,
822822
static int lfs_dir_getglobals(lfs_t *lfs, const lfs_mdir_t *dir,
823823
struct lfs_globals *globals) {
824824
struct lfs_globals locals;
825-
lfs_stag_t res = lfs_dir_get(lfs, dir, 0x7c000000,
825+
lfs_stag_t res = lfs_dir_get(lfs, dir, 0x78000000,
826826
LFS_MKTAG(LFS_TYPE_GLOBALS, 0, 10), &locals);
827827
if (res < 0 && res != LFS_ERR_NOENT) {
828828
return res;
@@ -848,15 +848,15 @@ static int lfs_dir_getinfo(lfs_t *lfs, lfs_mdir_t *dir,
848848
}
849849

850850
lfs_stag_t tag = lfs_dir_get(lfs, dir, 0x7c3fe000,
851-
LFS_MKTAG(LFS_TYPE_NAME, id, lfs->name_max+1), info->name);
851+
LFS_MKTAG(LFS_TYPE_DIR, id, lfs->name_max+1), info->name);
852852
if (tag < 0) {
853853
return tag;
854854
}
855855

856856
info->type = lfs_tag_type(tag);
857857

858858
struct lfs_ctz ctz;
859-
tag = lfs_dir_get(lfs, dir, 0x7c3fe000,
859+
tag = lfs_dir_get(lfs, dir, 0x783fe000,
860860
LFS_MKTAG(LFS_TYPE_STRUCT, id, sizeof(ctz)), &ctz);
861861
if (tag < 0) {
862862
return tag;
@@ -893,13 +893,12 @@ static int lfs_dir_find_match(void *data,
893893
}
894894

895895
// found match?
896-
if (res == 0 && (name->size == lfs_tag_size(tag) ||
897-
lfs_tag_type(tag) == LFS_TYPE_SUPERBLOCK)) {
896+
if (res == 0 && name->size == lfs_tag_size(tag)) {
898897
return tag;
899898
}
900899

901900
// a greater name found, exit early
902-
if (res == 2 && lfs_tag_type(tag) != LFS_TYPE_SUPERBLOCK) {
901+
if (res > 1 && lfs_tag_type(tag) != LFS_TYPE_SUPERBLOCK) {
903902
return tag | 0x1fff;
904903
}
905904

@@ -969,7 +968,7 @@ static int lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir,
969968

970969
// grab the entry data
971970
if (lfs_tag_id(tag) != 0x1ff) {
972-
lfs_stag_t res = lfs_dir_get(lfs, dir, 0x7c3fe000,
971+
lfs_stag_t res = lfs_dir_get(lfs, dir, 0x783fe000,
973972
LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), dir->tail);
974973
if (res < 0) {
975974
return res;
@@ -980,7 +979,7 @@ static int lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir,
980979
// find entry matching name
981980
while (true) {
982981
tag = lfs_dir_fetchmatch(lfs, dir, dir->tail,
983-
0x7c000000, LFS_MKTAG(LFS_TYPE_NAME, 0, namelen),
982+
0x7c000000, LFS_MKTAG(LFS_TYPE_DIR, 0, namelen),
984983
lfs_dir_find_match, &(struct lfs_dir_find_match){
985984
lfs, name, namelen});
986985
if (tag < 0) {
@@ -1059,7 +1058,7 @@ static int lfs_commit_move_match(void *data,
10591058
struct lfs_commit *commit = move->commit;
10601059

10611060
if (move->pass == 0) {
1062-
if (lfs_tag_subtype(tag) != LFS_TYPE_NAME) {
1061+
if (lfs_tag_subtype(tag) != LFS_TYPE_CREATE) {
10631062
return 0;
10641063
}
10651064
} else {
@@ -1068,7 +1067,7 @@ static int lfs_commit_move_match(void *data,
10681067
.pair[0] = commit->block,
10691068
.off = commit->off,
10701069
.etag = commit->ptag}, NULL,
1071-
lfs_tag_isuser(tag) ? 0x7fffe000 : 0x7c3fe000, tag, 0,
1070+
lfs_tag_isuser(tag) ? 0x7fffe000 : 0x783fe000, tag, 0,
10721071
lfs_dir_get_match, &(struct lfs_dir_get_match){
10731072
lfs, NULL, 0, true});
10741073
if (res < 0 && res != LFS_ERR_NOENT) {
@@ -1578,7 +1577,7 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir,
15781577
lfs_tag_t createtag = 0xffffffff;
15791578
int attrcount = 0;
15801579
for (const struct lfs_mattr *a = attrs; a; a = a->next) {
1581-
if (lfs_tag_subtype(a->tag) == LFS_TYPE_NAME) {
1580+
if (lfs_tag_subtype(a->tag) == LFS_TYPE_CREATE) {
15821581
dir->count += 1;
15831582
createtag = a->tag;
15841583
} else if (lfs_tag_subtype(a->tag) == LFS_TYPE_DELETE) {
@@ -1795,7 +1794,7 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
17951794
pair[1] = lfs->root[1];
17961795
} else {
17971796
// get dir pair from parent
1798-
lfs_stag_t res = lfs_dir_get(lfs, &dir->m, 0x7c3fe000,
1797+
lfs_stag_t res = lfs_dir_get(lfs, &dir->m, 0x783fe000,
17991798
LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), pair);
18001799
if (res < 0) {
18011800
return res;
@@ -2190,7 +2189,7 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
21902189
file->flags |= LFS_F_DIRTY;
21912190
} else {
21922191
// try to load what's on disk, if it's inlined we'll fix it later
2193-
tag = lfs_dir_get(lfs, &file->m, 0x7c3fe000,
2192+
tag = lfs_dir_get(lfs, &file->m, 0x783fe000,
21942193
LFS_MKTAG(LFS_TYPE_STRUCT, file->id, 8), &file->ctz);
21952194
if (tag < 0) {
21962195
err = tag;
@@ -2245,7 +2244,7 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
22452244

22462245
// don't always read (may be new/trunc file)
22472246
if (file->ctz.size > 0) {
2248-
lfs_stag_t res = lfs_dir_get(lfs, &file->m, 0x7c3fe000,
2247+
lfs_stag_t res = lfs_dir_get(lfs, &file->m, 0x783fe000,
22492248
LFS_MKTAG(LFS_TYPE_STRUCT, file->id, file->ctz.size),
22502249
file->cache.buffer);
22512250
if (res < 0) {
@@ -2800,7 +2799,7 @@ int lfs_remove(lfs_t *lfs, const char *path) {
28002799
if (lfs_tag_type(tag) == LFS_TYPE_DIR) {
28012800
// must be empty before removal
28022801
lfs_block_t pair[2];
2803-
lfs_stag_t res = lfs_dir_get(lfs, &cwd, 0x7c3fe000,
2802+
lfs_stag_t res = lfs_dir_get(lfs, &cwd, 0x783fe000,
28042803
LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), pair);
28052804
if (res < 0) {
28062805
return res;
@@ -2880,7 +2879,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
28802879
} else if (lfs_tag_type(prevtag) == LFS_TYPE_DIR) {
28812880
// must be empty before removal
28822881
lfs_block_t prevpair[2];
2883-
lfs_stag_t res = lfs_dir_get(lfs, &newcwd, 0x7c3fe000,
2882+
lfs_stag_t res = lfs_dir_get(lfs, &newcwd, 0x783fe000,
28842883
LFS_MKTAG(LFS_TYPE_STRUCT, newid, 8), prevpair);
28852884
if (res < 0) {
28862885
return res;
@@ -3139,9 +3138,7 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
31393138

31403139
// write one superblock
31413140
lfs_superblock_t superblock = {
3142-
.magic = {"littlefs"},
3143-
.version = LFS_DISK_VERSION,
3144-
3141+
.version = LFS_DISK_VERSION,
31453142
.block_size = lfs->cfg->block_size,
31463143
.block_count = lfs->cfg->block_count,
31473144
.name_max = lfs->name_max,
@@ -3151,8 +3148,10 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
31513148

31523149
lfs_superblock_tole32(&superblock);
31533150
err = lfs_dir_commit(lfs, &root,
3154-
LFS_MKATTR(LFS_TYPE_SUPERBLOCK, 0, &superblock, sizeof(superblock),
3155-
NULL));
3151+
LFS_MKATTR(LFS_TYPE_INLINESTRUCT, 0,
3152+
&superblock, sizeof(superblock),
3153+
LFS_MKATTR(LFS_TYPE_SUPERBLOCK, 0, "littlefs", 8,
3154+
NULL)));
31563155
if (err) {
31573156
goto cleanup;
31583157
}
@@ -3178,7 +3177,7 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
31783177
lfs_mdir_t dir = {.tail = {0, 1}};
31793178
while (!lfs_pair_isnull(dir.tail)) {
31803179
// fetch next block in tail list
3181-
lfs_stag_t tag = lfs_dir_fetchmatch(lfs, &dir, dir.tail, 0x7fc00000,
3180+
lfs_stag_t tag = lfs_dir_fetchmatch(lfs, &dir, dir.tail, 0x7fffe000,
31823181
LFS_MKTAG(LFS_TYPE_SUPERBLOCK, 0, 8),
31833182
lfs_dir_find_match, &(struct lfs_dir_find_match){
31843183
lfs, "littlefs", 8});
@@ -3195,8 +3194,8 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
31953194

31963195
// grab superblock
31973196
lfs_superblock_t superblock;
3198-
tag = lfs_dir_get(lfs, &dir, 0x7f800000,
3199-
LFS_MKTAG(LFS_TYPE_SUPERBLOCK, 0, sizeof(superblock)),
3197+
tag = lfs_dir_get(lfs, &dir, 0x7fffe000,
3198+
LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
32003199
&superblock);
32013200
if (tag < 0) {
32023201
err = tag;
@@ -3248,7 +3247,6 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
32483247

32493248
lfs->attr_max = superblock.attr_max;
32503249
}
3251-
32523250
}
32533251

32543252
// has globals?
@@ -3258,6 +3256,12 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
32583256
}
32593257
}
32603258

3259+
// found superblock?
3260+
if (lfs_pair_isnull(lfs->root)) {
3261+
err = LFS_ERR_INVAL;
3262+
goto cleanup;
3263+
}
3264+
32613265
// update littlefs with globals
32623266
lfs_global_fromle32(&lfs->locals);
32633267
lfs_global_xor(&lfs->globals, &lfs->locals);
@@ -3306,7 +3310,7 @@ int lfs_fs_traverse(lfs_t *lfs,
33063310

33073311
for (uint16_t id = 0; id < dir.count; id++) {
33083312
struct lfs_ctz ctz;
3309-
lfs_stag_t tag = lfs_dir_get(lfs, &dir, 0x7c3fe000,
3313+
lfs_stag_t tag = lfs_dir_get(lfs, &dir, 0x783fe000,
33103314
LFS_MKTAG(LFS_TYPE_STRUCT, id, sizeof(ctz)), &ctz);
33113315
if (tag < 0) {
33123316
if (tag == LFS_ERR_NOENT) {

lfs.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,12 @@ enum lfs_error {
8888
// File types
8989
enum lfs_type {
9090
// file types
91-
LFS_TYPE_REG = 0x002,
92-
LFS_TYPE_DIR = 0x003,
91+
LFS_TYPE_REG = 0x011,
92+
LFS_TYPE_DIR = 0x010,
9393

9494
// internally used types
9595
LFS_TYPE_USERATTR = 0x100,
96-
LFS_TYPE_NAME = 0x000,
96+
LFS_TYPE_CREATE = 0x000,
9797
LFS_TYPE_DELETE = 0x020,
9898
LFS_TYPE_STRUCT = 0x040,
9999
LFS_TYPE_TAIL = 0x080,
@@ -110,8 +110,8 @@ enum lfs_type {
110110
// internal chip sources
111111
LFS_FROM_MEM = 0x000,
112112
LFS_FROM_DISK = 0x200,
113-
LFS_FROM_MOVE = 0x0c1,
114-
LFS_FROM_USERATTRS = 0x0c2,
113+
LFS_FROM_MOVE = 0x061,
114+
LFS_FROM_USERATTRS = 0x062,
115115
};
116116

117117
// File open flags
@@ -339,9 +339,7 @@ typedef struct lfs_file {
339339
} lfs_file_t;
340340

341341
typedef struct lfs_superblock {
342-
char magic[8];
343342
uint32_t version;
344-
345343
lfs_size_t block_size;
346344
lfs_size_t block_count;
347345

tests/debug.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
import binascii
55

66
TYPES = {
7-
(0x1ff, 0x002): 'reg',
8-
(0x1ff, 0x003): 'dir',
7+
(0x1ff, 0x011): 'create reg',
8+
(0x1ff, 0x010): 'create dir',
99
(0x1ff, 0x001): 'superblock',
1010
(0x1ff, 0x020): 'delete',
1111
(0x1f0, 0x0e0): 'globals',
@@ -23,10 +23,10 @@ def typeof(type):
2323
mask = 0x1ff & ~((1 << prefix)-1)
2424
if (mask, type & mask) in TYPES:
2525
return TYPES[mask, type & mask] + (
26-
' [%0*x]' % (prefix/4, type & ((1 << prefix)-1))
26+
' %0*x' % (prefix/4, type & ((1 << prefix)-1))
2727
if prefix else '')
2828
else:
29-
return '[%02x]' % type
29+
return '%02x' % type
3030

3131
def main(*blocks):
3232
# find most recent block

tests/test_paths.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,14 @@ tests/test.py << TEST
139139
lfs_unmount(&lfs) => 0;
140140
TEST
141141

142+
echo "--- Superblock conflict test ---"
143+
tests/test.py << TEST
144+
lfs_mount(&lfs, &cfg) => 0;
145+
lfs_mkdir(&lfs, "littlefs") => 0;
146+
lfs_remove(&lfs, "littlefs") => 0;
147+
lfs_unmount(&lfs) => 0;
148+
TEST
149+
142150
echo "--- Max path test ---"
143151
tests/test.py << TEST
144152
lfs_mount(&lfs, &cfg) => 0;

0 commit comments

Comments
 (0)