Adopted upstream path-parsing changes, trailing-slashes, etc

Fortunately, while these two code bases have almost completely diverged
at this point, we can at least reuse the reworked test_paths tests.

Mostly involving corner-cases related to trailing-slashes, these changes
gives us better alignment with POSIX and hopefully fewer surprises for
users. The full details of what's changed is in the v2.10 release notes/
commits.

---

Implementing these changes here required a little bit of backpedaling.

Something that worked quite well upstream was the use of trailing junk
in the path to tell if a parent was not found, path must be dir, etc.
This is a bit more awkward with lfsr_mtree_pathlookup, with everything
taking an explicit name_size, but it greatly simplifies the mess that
was lfsr_mtree_pathlookup's error codes.

Now it's just:

- 0                                      => file found
- 0, lfsr_path_isdir(path)               => dir found
- 0, mdir.mid=-1                         => root found
- LFS_ERR_NOENT, lfsr_path_islast(path)  => file not found
- LFS_ERR_NOENT, !lfsr_path_islast(path) => parent not found
- LFS_ERR_NOTDIR                         => parent not a dir

Note the special mdir.mid=-1 case for the root. This was needed since
lfsr_mtree_pathlookup can now return LFS_ERR_INVAL (for empty paths, dot
dots above root, etc).

In theory we could've gotten away with a different error code, but none
of them really make sense for this case.

---

The impact on code size is a bit funny. Modifying the path in-place _is_
a cheaper API, at the cost of being a bit more convoluted, but the extra
logic added for POSIX-alignment cancels this out:

           code          stack          ctx
  before: 38100 (-0.1%)   2624 (+0.0%)  752 (+0.0%)
  after:  38120 (+0.0%)   2624 (+0.0%)  752 (+0.0%)
This commit is contained in:
Christopher Haster
2024-12-20 03:22:09 -06:00
parent 1d8d0785fc
commit 2751317ec2
3 changed files with 7453 additions and 365 deletions
+4 -6
View File
@@ -925,17 +925,15 @@ code = '''
// change a file's type to something unknown
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
const char *path = "b";
lfsr_mdir_t mdir;
lfsr_did_t did;
const char *name;
lfs_size_t name_size;
lfsr_mtree_pathlookup(&lfs, "b",
&mdir, NULL,
&did, &name, &name_size) => LFS_ERR_EXIST;
lfsr_mtree_pathlookup(&lfs, &path,
&mdir, NULL, &did) => 0;
lfsr_mdir_commit(&lfs, &mdir, LFSR_RATTRS(
LFSR_RATTR_NAME(
LFSR_TAG_SUB | (LFSR_TAG_NAME + 0x13), 0,
did, name, name_size))) => 0;
did, path, lfsr_path_namelen(path)))) => 0;
lfsr_unmount(&lfs) => 0;
// mount should now fail
+7289 -216
View File
File diff suppressed because it is too large Load Diff