diff --git a/apps/playlist.c b/apps/playlist.c index dcf2fe1118..ea183d7552 100644 --- a/apps/playlist.c +++ b/apps/playlist.c @@ -575,7 +575,7 @@ static int add_indices_to_playlist(struct playlist_info* playlist, playlist->indices[ playlist->amount ] = i+count; #ifdef HAVE_DIRCACHE if (playlist->filenames) - playlist->filenames[ playlist->amount ] = NULL; + playlist->filenames[ playlist->amount ] = -1; #endif playlist->amount++; } @@ -816,7 +816,7 @@ static int add_track_to_playlist(struct playlist_info* playlist, #ifdef HAVE_DIRCACHE if (playlist->filenames) - playlist->filenames[insert_position] = NULL; + playlist->filenames[insert_position] = -1; #endif playlist->amount++; @@ -958,9 +958,9 @@ static int randomise_playlist(struct playlist_info* playlist, #ifdef HAVE_DIRCACHE if (playlist->filenames) { - store = (long)playlist->filenames[candidate]; + store = playlist->filenames[candidate]; playlist->filenames[candidate] = playlist->filenames[count]; - playlist->filenames[count] = (struct dircache_entry *)store; + playlist->filenames[count] = store; } #endif } @@ -1298,7 +1298,7 @@ static void playlist_thread(void) && queue_empty(&playlist_queue); index++) { /* Process only pointers that are not already loaded. */ - if (playlist->filenames[index]) + if (playlist->filenames[index] >= 0) continue ; control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK; @@ -1310,7 +1310,7 @@ static void playlist_thread(void) break ; /* Set the dircache entry pointer. */ - playlist->filenames[index] = dircache_get_entry_ptr(tmp); + playlist->filenames[index] = dircache_get_entry_id(tmp); /* And be on background so user doesn't notice any delays. */ yield(); @@ -1351,7 +1351,7 @@ static int get_filename(struct playlist_info* playlist, int index, int seek, #ifdef HAVE_DIRCACHE if (dircache_is_enabled() && playlist->filenames) { - if (playlist->filenames[index] != NULL) + if (playlist->filenames[index] >= 0) { max = dircache_copy_path(playlist->filenames[index], tmp_buf, sizeof(tmp_buf)-1); @@ -2389,7 +2389,7 @@ int playlist_add(const char *filename) playlist->indices[playlist->amount] = playlist->buffer_end_pos; #ifdef HAVE_DIRCACHE - playlist->filenames[playlist->amount] = NULL; + playlist->filenames[playlist->amount] = -1; #endif playlist->amount++; @@ -2713,8 +2713,7 @@ int playlist_create_ex(struct playlist_info* playlist, playlist->max_playlist_size = num_indices; playlist->indices = index_buffer; #ifdef HAVE_DIRCACHE - playlist->filenames = (const struct dircache_entry **) - &playlist->indices[num_indices]; + playlist->filenames = (int*)&playlist->indices[num_indices]; #endif playlist->buffer_size = 0; diff --git a/apps/playlist.h b/apps/playlist.h index 9c45769981..d994f6e800 100644 --- a/apps/playlist.h +++ b/apps/playlist.h @@ -81,7 +81,7 @@ struct playlist_info bool control_created; /* has control file been created? */ int dirlen; /* Length of the path to the playlist file */ unsigned long *indices; /* array of indices */ - const struct dircache_entry **filenames; /* Entries from dircache */ + int *filenames; /* Array of dircache indices */ int max_playlist_size; /* Max number of files in playlist. Mirror of global_settings.max_files_in_playlist */ bool in_ram; /* playlist stored in ram (dirplay) */ diff --git a/apps/tagcache.c b/apps/tagcache.c index 080f4198c3..c5a8dcbae5 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c @@ -383,8 +383,9 @@ static bool do_timed_yield(void) #endif #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) -static long find_entry_ram(const char *filename, - const struct dircache_entry *dc) +/* find the ramcache entry corresponding to the file indicated by + * filename and dc (it's corresponding dircache id). */ +static long find_entry_ram(const char *filename, int dc) { static long last_pos = 0; int i; @@ -393,10 +394,10 @@ static long find_entry_ram(const char *filename, if (!tc_stat.ramcache) return -1; - if (dc == NULL) - dc = dircache_get_entry_ptr(filename); + if (dc < 0) + dc = dircache_get_entry_id(filename); - if (dc == NULL) + if (dc < 0) { logf("tagcache: file not found."); return -1; @@ -411,7 +412,7 @@ static long find_entry_ram(const char *filename, for (; i < current_tcmh.tch.entry_count; i++) { - if (hdr->indices[i].tag_seek[tag_filename] == (long)dc) + if (hdr->indices[i].tag_seek[tag_filename] == dc) { last_pos = MAX(0, i - 3); return i; @@ -539,7 +540,7 @@ static int find_index(const char *filename) #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) if (tc_stat.ramcache && is_dircache_intact()) - idx_id = find_entry_ram(filename, NULL); + idx_id = find_entry_ram(filename, -1); #endif if (idx_id < 0) @@ -723,8 +724,8 @@ static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx, if (tag == tag_filename && (idx->flag & FLAG_DIRCACHE) && is_dircache_intact()) { - dircache_copy_path((struct dircache_entry *)seek, - buf, size); + /* for tag_filename, seek is a dircache index */ + dircache_copy_path(seek, buf, size); return true; } else @@ -1481,8 +1482,7 @@ static bool get_next(struct tagcache_search *tcs) if (tcs->type == tag_filename && (flag & FLAG_DIRCACHE) && is_dircache_intact()) { - size_t len = dircache_copy_path((struct dircache_entry *)tcs->position, - buf, sizeof buf); + size_t len = dircache_copy_path(tcs->position, buf, sizeof buf); tcs->result_len = len + 1; tcs->result = buf; tcs->ramresult = false; @@ -1599,29 +1599,6 @@ static bool update_master_header(void) return true; } -#if 0 - -void tagcache_modify(struct tagcache_search *tcs, int type, const char *text) -{ - struct tagentry *entry; - - if (tcs->type != tag_title) - return ; - - /* We will need reserve buffer for this. */ - if (tcs->ramcache) - { - struct tagfile_entry *ep; - - ep = (struct tagfile_entry *)&hdr->tags[tcs->type][tcs->result_seek]; - tcs->seek_list[tcs->seek_list_count]; - } - - entry = find_entry_ram(); - -} -#endif - void tagcache_search_finish(struct tagcache_search *tcs) { int i; @@ -1677,7 +1654,7 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename) return false; /* Find the corresponding entry in tagcache. */ - idx_id = find_entry_ram(filename, NULL); + idx_id = find_entry_ram(filename, -1); if (idx_id < 0) return false; @@ -1761,7 +1738,7 @@ static int check_if_empty(char **tag) static void __attribute__ ((noinline)) add_tagcache(char *path, unsigned long mtime #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) - ,const struct dircache_entry *dc + ,int dc #endif ) { @@ -4017,7 +3994,7 @@ static bool load_tagcache(void) if (tag == tag_filename) { # ifdef HAVE_DIRCACHE - const struct dircache_entry *dc; + int dc; # endif // FIXME: This is wrong! @@ -4064,8 +4041,8 @@ static bool load_tagcache(void) # ifdef HAVE_DIRCACHE if (dircache_is_enabled()) { - dc = dircache_get_entry_ptr(buf); - if (dc == NULL) + dc = dircache_get_entry_id(buf); + if (dc < 0) { logf("Entry no longer valid."); logf("-> %s", buf); @@ -4075,7 +4052,7 @@ static bool load_tagcache(void) } idx->flag |= FLAG_DIRCACHE; - idx->tag_seek[tag_filename] = (long)dc; + idx->tag_seek[tag_filename] = dc; } else # endif diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index 0f3c453ee7..bff9c2f4e7 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c @@ -57,7 +57,23 @@ #else #define MAX_OPEN_DIRS 8 #endif -static DIR_CACHED opendirs[MAX_OPEN_DIRS]; + +#define MAX_PENDING_BINDINGS 2 +struct fdbind_queue { + char path[MAX_PATH]; + int fd; +}; + +/* Exported structures. */ +struct dircache_entry { + struct dirinfo info; + struct dircache_entry *next; + struct dircache_entry *up; + struct dircache_entry *down; + long startcluster; + char *d_name; +}; + /* Cache Layout: * * x - array of struct dircache_entry @@ -75,7 +91,6 @@ static DIR_CACHED opendirs[MAX_OPEN_DIRS]; * total allocation size grows * |xxxxxxxx|rrrrrrrrr|dddddddd| */ -static struct dircache_entry *fd_bindings[MAX_OPEN_FILES]; /* this points to the beginnging of the buffer and the first entry */ static struct dircache_entry *dircache_root; /* these point to the start and end of the name buffer (d above) */ @@ -86,6 +101,9 @@ static char *dot, *dotdot; static struct dircache_entry *append_position; #endif +static DIR_CACHED opendirs[MAX_OPEN_DIRS]; +static struct dircache_entry *fd_bindings[MAX_OPEN_FILES]; + static bool dircache_initialized = false; static bool dircache_initializing = false; static bool thread_enabled = false; @@ -105,6 +123,11 @@ static int fdbind_idx = 0; /* --- Internal cache structure control functions --- */ +static inline struct dircache_entry* get_entry(int id) +{ + return &dircache_root[id]; +} + #ifdef HAVE_EEPROM_SETTINGS /** * Open the dircache file to save a snapshot on disk @@ -1012,14 +1035,36 @@ void dircache_disable(void) } /** - * Usermode function to return dircache_entry pointer to the given path. + * Usermode function to return dircache_entry index to the given path. */ -const struct dircache_entry *dircache_get_entry_ptr(const char *filename) +static int dircache_get_entry_id_ex(const char *filename, bool go_down) { if (!dircache_initialized || filename == NULL) - return NULL; + return -1; - return dircache_get_entry(filename, false); + struct dircache_entry* res = dircache_get_entry(filename, go_down); + return res ? res - dircache_root : -1; +} + +int dircache_get_entry_id(const char* filename) +{ + return dircache_get_entry_id_ex(filename, false); +} + +/** + * Internal: Get the startcluster for the index + */ +long _dircache_get_entry_startcluster(int id) +{ + return get_entry(id)->startcluster; +} + +/** + * Internal: Get the struct dirinfo for the index + */ +struct dirinfo* _dircache_get_entry_dirinfo(int id) +{ + return &get_entry(id)->info; } /* @@ -1050,13 +1095,13 @@ static size_t copy_path_helper(const struct dircache_entry *entry, char *buf, si * * Returns the size of the resulting string, or 0 if an error occured */ -size_t dircache_copy_path(const struct dircache_entry *entry, char *buf, size_t size) +size_t dircache_copy_path(int index, char *buf, size_t size) { - if (!size || !buf) + if (!size || !buf || index < 0) return 0; buf[0] = '/'; - size_t res = copy_path_helper(entry, buf, size); + size_t res = copy_path_helper(&dircache_root[index], buf, size); /* fixup trailing '/' */ buf[res] = '\0'; return res; @@ -1373,17 +1418,17 @@ DIR_CACHED* opendir_cached(const char* name) if (!dircache_initialized || is_disable_msg_pending()) { - pdir->internal_entry = NULL; + pdir->internal_entry = -1; pdir->regulardir = opendir_uncached(name); } else { pdir->regulardir = NULL; - pdir->internal_entry = dircache_get_entry(name, true); + pdir->internal_entry = dircache_get_entry_id_ex(name, true); pdir->theent.info.attribute = -1; /* used to make readdir_cached aware of the first call */ } - if (pdir->internal_entry == NULL && pdir->regulardir == NULL) + if (pdir->internal_entry == -1 && pdir->regulardir == NULL) { pdir->busy = false; return NULL; @@ -1394,7 +1439,7 @@ DIR_CACHED* opendir_cached(const char* name) struct dirent_cached* readdir_cached(DIR_CACHED* dir) { - struct dircache_entry *ce = dir->internal_entry; + struct dircache_entry *ce = get_entry(dir->internal_entry); struct dirent_uncached *regentry; if (!dir->busy) @@ -1430,7 +1475,7 @@ struct dirent_cached* readdir_cached(DIR_CACHED* dir) because that modifies the d_name pointer. */ dir->theent.startcluster = ce->startcluster; dir->theent.info = ce->info; - dir->internal_entry = ce; + dir->internal_entry = ce - dircache_root; //logf("-> %s", ce->d_name); return &dir->theent; diff --git a/firmware/common/file.c b/firmware/common/file.c index 8f6bfa051b..cfebd0622f 100644 --- a/firmware/common/file.c +++ b/firmware/common/file.c @@ -108,25 +108,26 @@ static int open_internal(const char* pathname, int flags, bool use_cache) #ifdef HAVE_DIRCACHE if (dircache_is_enabled() && !file->write && use_cache) { - const struct dircache_entry *ce; # ifdef HAVE_MULTIVOLUME int volume = strip_volume(pathname, pathnamecopy); # endif - ce = dircache_get_entry_ptr(pathname); - if (!ce) + int ce = dircache_get_entry_id(pathname); + if (ce < 0) { errno = ENOENT; file->busy = false; return -7; } + long startcluster = _dircache_get_entry_startcluster(ce); fat_open(IF_MV2(volume,) - ce->startcluster, + startcluster, &(file->fatfile), NULL); - file->size = ce->info.size; - file->attr = ce->info.attribute; + struct dirinfo *info = _dircache_get_entry_dirinfo(ce); + file->size = info->size; + file->attr = info->attribute; file->cacheoffset = -1; file->fileoffset = 0; diff --git a/firmware/common/filefuncs.c b/firmware/common/filefuncs.c index 6eb2bafa40..fd33f3c6f9 100644 --- a/firmware/common/filefuncs.c +++ b/firmware/common/filefuncs.c @@ -70,7 +70,7 @@ bool file_exists(const char *file) #ifdef HAVE_DIRCACHE if (dircache_is_enabled()) - return (dircache_get_entry_ptr(file) != NULL); + return (dircache_get_entry_id(file) >= 0); #endif fd = open(file, O_RDONLY); diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h index 908165cf3c..585bb10fbc 100644 --- a/firmware/include/dircache.h +++ b/firmware/include/dircache.h @@ -47,22 +47,6 @@ struct travel_data { int pathpos; }; -#define MAX_PENDING_BINDINGS 2 -struct fdbind_queue { - char path[MAX_PATH]; - int fd; -}; - -/* Exported structures. */ -struct dircache_entry { - struct dirinfo info; - struct dircache_entry *next; - struct dircache_entry *up; - struct dircache_entry *down; - long startcluster; - char *d_name; -}; - struct dirent_cached { struct dirinfo info; char *d_name; @@ -72,7 +56,7 @@ struct dirent_cached { typedef struct { bool busy; struct dirent_cached theent; /* .attribute is set to -1 on init(opendir) */ - struct dircache_entry *internal_entry; /* the current entry in the directory */ + int internal_entry; /* the current entry in the directory */ DIR_UNCACHED *regulardir; } DIR_CACHED; @@ -90,8 +74,12 @@ int dircache_get_cache_size(void); int dircache_get_reserve_used(void); int dircache_get_build_ticks(void); void dircache_disable(void); -const struct dircache_entry *dircache_get_entry_ptr(const char *filename); -size_t dircache_copy_path(const struct dircache_entry *entry, char *buf, size_t size); +int dircache_get_entry_id(const char *filename); +size_t dircache_copy_path(int index, char *buf, size_t size); + +/* the next two are internal for file.c */ +long _dircache_get_entry_startcluster(int id); +struct dirinfo* _dircache_get_entry_dirinfo(int id); void dircache_bind(int fd, const char *path); void dircache_update_filesize(int fd, long newsize, long startcluster); diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c index d094feee6b..71da4fc2ce 100644 --- a/uisimulator/common/io.c +++ b/uisimulator/common/io.c @@ -148,8 +148,7 @@ extern int _wrmdir(const wchar_t*); #ifdef HAVE_DIRCACHE -struct dircache_entry; -const struct dircache_entry *dircache_get_entry_ptr(const char *filename); +int dircache_get_entry_id(const char *filename); void dircache_add_file(const char *name, long startcluster); void dircache_remove(const char *name); void dircache_rename(const char *oldname, const char *newname); @@ -409,7 +408,7 @@ int sim_open(const char *name, int o, ...) mode_t mode = va_arg(ap, unsigned int); ret = OPEN(get_sim_pathname(name), opts, mode); #ifdef HAVE_DIRCACHE - if (ret >= 0 && !dircache_get_entry_ptr(name)) + if (ret >= 0 && (dircache_get_entry_id(name) < 0)) dircache_add_file(name, 0); #endif va_end(ap); @@ -436,7 +435,7 @@ int sim_creat(const char *name, mode_t mode) int ret = OPEN(get_sim_pathname(name), O_BINARY | O_WRONLY | O_CREAT | O_TRUNC, mode); #ifdef HAVE_DIRCACHE - if (ret >= 0 && !dircache_get_entry_ptr(name)) + if (ret >= 0 && (dircache_get_entry_id(name) < 0)) dircache_add_file(name, 0); #endif return ret;