diff options
Diffstat (limited to 'firmware/common/fileobj_mgr.c')
-rw-r--r-- | firmware/common/fileobj_mgr.c | 114 |
1 files changed, 27 insertions, 87 deletions
diff --git a/firmware/common/fileobj_mgr.c b/firmware/common/fileobj_mgr.c index 37452fbbe1..e34a460e10 100644 --- a/firmware/common/fileobj_mgr.c +++ b/firmware/common/fileobj_mgr.c @@ -20,13 +20,12 @@ ****************************************************************************/ #include "config.h" #include "system.h" -#include <errno.h> #include "debug.h" #include "file.h" #include "dir.h" #include "disk_cache.h" #include "fileobj_mgr.h" -#include "rb_namespace.h" +#include "dircache_redirect.h" /** * Manages file and directory streams on all volumes @@ -35,8 +34,8 @@ */ -/* there will always be enough of these for all user handles, thus most of - these functions don't return failure codes */ +/* there will always be enough of these for all user handles, thus these + functions don't return failure codes */ #define MAX_FILEOBJS (MAX_OPEN_HANDLES + AUX_FILEOBJS) /* describes the file as an image on the storage medium */ @@ -85,15 +84,6 @@ static struct ll_head busy_bindings[NUM_VOLUMES]; for (struct filestr_base *s = STREAM_##what(start); \ s; s = STREAM_NEXT(s)) -/* once a file/directory, always a file/directory; such a change - is a bug */ -#define CHECK_FO_DIRECTORY(callflags, fobp) \ - if (((callflags) ^ (fobp)->flags) & FO_DIRECTORY) \ - { \ - DEBUGF("%s - FO_DIRECTORY flag does not match: %p %u\n", \ - __func__, (fobp), (callflags)); \ - } - /* syncs information for the stream's old and new parent directory if any are currently opened */ @@ -106,10 +96,6 @@ static void fileobj_sync_parent(const struct file_base_info *infop[], continue; /* not directory or removed can't be parent of anything */ struct filestr_base *parentstrp = STREAM_FIRST(fobp); - - if (!parentstrp) - continue; - struct fat_file *parentfilep = &parentstrp->infop->fatfile; for (int i = 0; i < count; i++) @@ -125,7 +111,8 @@ static void fileobj_sync_parent(const struct file_base_info *infop[], } /* see if this file has open streams and return that fileobj_binding if so, - else grab a new one from the free list; returns true if this is new */ + else grab a new one from the free list; returns true if this stream is + the only open one */ static bool binding_assign(const struct file_base_info *srcinfop, struct fileobj_binding **fobpp) { @@ -136,7 +123,7 @@ static bool binding_assign(const struct file_base_info *srcinfop, if (fat_file_is_same(&srcinfop->fatfile, &fobp->bind.info.fatfile)) { - /* already has open streams/mounts */ + /* already has open streams */ *fobpp = fobp; return false; } @@ -156,23 +143,6 @@ static void binding_add_to_free_list(struct fileobj_binding *fobp) ll_insert_last(FREE_BINDINGS(), &fobp->bind.node); } -static void bind_source_info(const struct file_base_info *srcinfop, - struct fileobj_binding **fobpp) -{ - if (!binding_assign(srcinfop, fobpp)) - return; /* already in use */ - - /* is new */ - (*fobpp)->bind.info = *srcinfop; - fileobj_bind_file(&(*fobpp)->bind); -} - -static void release_binding(struct fileobj_binding *fobp) -{ - fileobj_unbind_file(&fobp->bind); - binding_add_to_free_list(fobp); -} - /** File and directory internal interface **/ void file_binding_insert_last(struct file_base_binding *bindp) @@ -199,41 +169,6 @@ void file_binding_remove_next(struct file_base_binding *prevp, } #endif /* HAVE_DIRCACHE */ -/* mounts a file object as a target from elsewhere */ -bool fileobj_mount(const struct file_base_info *srcinfop, - unsigned int callflags, - struct file_base_binding **bindpp) -{ - struct fileobj_binding *fobp; - bind_source_info(srcinfop, &fobp); - - CHECK_FO_DIRECTORY(callflags, fobp); - - if (fobp->flags & FO_MOUNTTARGET) - return false; /* already mounted */ - - fobp->flags |= FDO_BUSY | FO_MOUNTTARGET | - (callflags & FO_DIRECTORY); - - *bindpp = &fobp->bind; - - return true; -} - -/* unmounts the file object and frees it if now unusued */ -void fileobj_unmount(struct file_base_binding *bindp) -{ - struct fileobj_binding *fobp = (struct fileobj_binding *)bindp; - - if (!(fobp->flags & FO_MOUNTTARGET)) - return; /* not mounted */ - - if (STREAM_FIRST(fobp) == NULL) - release_binding(fobp); /* no longer in use */ - else - fobp->flags &= ~FO_MOUNTTARGET; -} - /* opens the file object for a new stream and sets up the caches; * the stream must already be opened at the FS driver level and *stream * initialized. @@ -245,14 +180,10 @@ void fileobj_fileop_open(struct filestr_base *stream, const struct file_base_info *srcinfop, unsigned int callflags) { - /* assign base file information */ struct fileobj_binding *fobp; - bind_source_info(srcinfop, &fobp); - - unsigned int foflags = fobp->flags; + bool first = binding_assign(srcinfop, &fobp); /* add stream to this file's list */ - bool first = STREAM_FIRST(fobp) == NULL; ll_insert_last(&fobp->list, &stream->node); /* initiate the new stream into the enclave */ @@ -266,16 +197,27 @@ void fileobj_fileop_open(struct filestr_base *stream, if (first) { /* first stream for file */ - fobp->flags = foflags | FDO_BUSY | FO_SINGLE | - (callflags & (FO_DIRECTORY|FO_TRUNC)); - fobp->writers = 0; - fobp->size = 0; + fobp->bind.info = *srcinfop; + fobp->flags = FDO_BUSY | FO_SINGLE | + (callflags & (FO_DIRECTORY|FO_TRUNC)); + fobp->writers = 0; + fobp->size = 0; + + fileobj_bind_file(&fobp->bind); } else { /* additional stream for file */ - fobp->flags = (foflags & ~FO_SINGLE) | (callflags & FO_TRUNC); - CHECK_FO_DIRECTORY(callflags, fobp); + fobp->flags &= ~FO_SINGLE; + fobp->flags |= callflags & FO_TRUNC; + + /* once a file/directory, always a file/directory; such a change + is a bug */ + if ((callflags ^ fobp->flags) & FO_DIRECTORY) + { + DEBUGF("%s - FO_DIRECTORY flag does not match: %p %u\n", + __func__, stream, callflags); + } } if ((callflags & FD_WRITE) && ++fobp->writers == 1) @@ -315,14 +257,12 @@ void fileobj_fileop_close(struct filestr_base *stream) if (foflags & FO_SINGLE) { /* last stream for file; close everything */ + fileobj_unbind_file(&fobp->bind); + if (fobp->writers) file_cache_free(&fobp->cache); - /* binding must stay valid if something is mounted to here */ - if (foflags & FO_MOUNTTARGET) - fobp->flags = foflags & (FDO_BUSY|FO_DIRECTORY|FO_MOUNTTARGET); - else - release_binding(fobp); + binding_add_to_free_list(fobp); } else { |