From f850bbbbc4b7345bebde241f651bad1c5c28df66 Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Thu, 20 Aug 2020 21:54:00 -0400 Subject: Revert root_redirect :( This reverts commit 31fc46ded69be7438cca2ba2c2b93c1f200165a6. Change-Id: Ia78618c0e8b25ca65f7c8ae0db1cb9c9b321bad9 --- firmware/common/file_internal.c | 95 +++++++++++++++++++++++++++++------------ 1 file changed, 68 insertions(+), 27 deletions(-) (limited to 'firmware/common/file_internal.c') diff --git a/firmware/common/file_internal.c b/firmware/common/file_internal.c index 45f412e166..fe18f90056 100644 --- a/firmware/common/file_internal.c +++ b/firmware/common/file_internal.c @@ -26,7 +26,9 @@ #include "pathfuncs.h" #include "disk_cache.h" #include "fileobj_mgr.h" -#include "rb_namespace.h" +#include "dir.h" +#include "dircache_redirect.h" +#include "dircache.h" #include "string-extra.h" #include "rbunicode.h" @@ -85,10 +87,9 @@ void file_cache_free(struct filestr_cache *cachep) /** Stream base APIs **/ -static inline void filestr_clear(struct filestr_base *stream, - unsigned int flags) +static inline void filestr_clear(struct filestr_base *stream) { - stream->flags = flags; + stream->flags = 0; stream->bindp = NULL; #if 0 stream->mtx = NULL; @@ -152,7 +153,7 @@ void filestr_discard_cache(struct filestr_base *stream) /* Initialize the base descriptor */ void filestr_base_init(struct filestr_base *stream) { - filestr_clear(stream, FD_VALID); + filestr_clear(stream); file_cache_init(&stream->cache); stream->cachep = &stream->cache; } @@ -160,7 +161,7 @@ void filestr_base_init(struct filestr_base *stream) /* free base descriptor resources */ void filestr_base_destroy(struct filestr_base *stream) { - filestr_clear(stream, 0); + filestr_clear(stream); filestr_free_cache(stream); } @@ -292,7 +293,7 @@ struct pathwalk_component #define WALK_RC_NOT_FOUND 0 /* successfully not found (aid for file creation) */ #define WALK_RC_FOUND 1 /* found and opened */ -#define WALK_RC_FOUND_ROOT 2 /* found and opened sys root */ +#define WALK_RC_FOUND_ROOT 2 /* found and opened sys/volume root */ #define WALK_RC_CONT_AT_ROOT 3 /* continue at root level */ /* return another struct pathwalk_component from the pool, or NULL if the @@ -396,10 +397,10 @@ static int walk_open_info(struct pathwalk *walkp, /* make open official if not simply probing for presence - must do it here or compp->info on stack will get destroyed before it was copied */ - if (!(callflags & (FF_PROBE|FF_NOFS))) + if (!(callflags & FF_PROBE)) fileop_onopen_internal(stream, &compp->info, callflags); - return compp->attr == ATTR_SYSTEM_ROOT ? WALK_RC_FOUND_ROOT : WALK_RC_FOUND; + return compp->nextp ? WALK_RC_FOUND : WALK_RC_FOUND_ROOT; } /* check the component against the prefix test info */ @@ -506,10 +507,6 @@ walk_path(struct pathwalk *walkp, struct pathwalk_component *compp, if (len > MAX_COMPNAME) return -ENAMETOOLONG; - /* no filesystem is mounted here */ - if (walkp->callflags & FF_NOFS) - return -ENOENT; - /* check for "." and ".." */ if (name[0] == '.') { @@ -578,7 +575,7 @@ int open_stream_internal(const char *path, unsigned int callflags, callflags &= ~(FF_INFO | FF_PARENTINFO | FF_CHECKPREFIX); /* This lets it be passed quietly to directory scanning */ - stream->flags |= callflags & FF_MASK; + stream->flags = callflags & FF_MASK; struct pathwalk walk; walk.path = path; @@ -588,36 +585,80 @@ int open_stream_internal(const char *path, unsigned int callflags, struct pathwalk_component *rootp = pathwalk_comp_alloc(NULL); rootp->nextp = NULL; + rootp->attr = ATTR_SYSTEM_ROOT; + +#ifdef HAVE_MULTIVOLUME + int volume = 0, rootrc = WALK_RC_FOUND; +#endif /* HAVE_MULTIVOLUME */ while (1) { - rc = ns_parse_root(walk.path, &rootp->name, &rootp->length); - if (rc < 0) - break; + const char *pathptr = walk.path; + + #ifdef HAVE_MULTIVOLUME + /* this seamlessly integrates secondary filesystems into the + root namespace (e.g. "/<0>/../../<1>/../foo/." :<=> "/foo") */ + const char *p; + volume = path_strip_volume(pathptr, &p, false); + if (!CHECK_VOL(volume)) + { + DEBUGF("No such device or address: %d\n", volume); + FILE_ERROR(ENXIO, -2); + } + + if (p == pathptr) + { + /* the root of this subpath is the system root */ + rootp->attr = ATTR_SYSTEM_ROOT; + rootrc = WALK_RC_FOUND_ROOT; + } + else + { + /* this subpath specifies a mount point */ + rootp->attr = ATTR_MOUNT_POINT; + rootrc = WALK_RC_FOUND; + } - rc = ns_open_root(IF_MV(rc,) &walk.callflags, &rootp->info, &rootp->attr); + walk.path = p; + #endif /* HAVE_MULTIVOLUME */ + + /* set name to start at last leading separator; names of volume + specifiers will be returned as "/" */ + rootp->name = GOBBLE_PATH_SEPCH(pathptr) - 1; + rootp->length = + IF_MV( rootrc == WALK_RC_FOUND ? p - rootp->name : ) 1; + + rc = fat_open_rootdir(IF_MV(volume,) &rootp->info.fatfile); if (rc < 0) + { + /* not mounted */ + DEBUGF("No such device or address: %d\n", IF_MV_VOL(volume)); + rc = -ENXIO; break; + } - walk.path = rootp->name + rootp->length; - + get_rootinfo_internal(&rootp->info); rc = walk_path(&walk, rootp, stream); if (rc != WALK_RC_CONT_AT_ROOT) break; } - if (rc >= 0) + switch (rc) { + case WALK_RC_FOUND_ROOT: + IF_MV( rc = rootrc; ) + case WALK_RC_NOT_FOUND: + case WALK_RC_FOUND: /* FF_PROBE leaves nothing for caller to clean up */ - if (walk.callflags & FF_PROBE) + if (callflags & FF_PROBE) filestr_base_destroy(stream); - } - else - { - /* utter, abject failure :`( */ + + break; + + default: /* utter, abject failure :`( */ DEBUGF("Open failed: rc=%d, errno=%d\n", rc, errno); filestr_base_destroy(stream); - FILE_ERROR(-rc, -1); + FILE_ERROR(-rc, -3); } file_error: -- cgit v1.2.3