summaryrefslogtreecommitdiff
path: root/firmware/common/dircache.c
diff options
context:
space:
mode:
authorAmaury Pouly <pamaury@rockbox.org>2010-02-01 23:00:35 +0000
committerAmaury Pouly <pamaury@rockbox.org>2010-02-01 23:00:35 +0000
commit1459bbc45f728c610daba7c4b51d9494cb34760a (patch)
treef285738d5feee25659e8230e703eb700c956d9be /firmware/common/dircache.c
parentfb680535f6ffe3f37043c634c6db588adb5d817d (diff)
downloadrockbox-1459bbc45f728c610daba7c4b51d9494cb34760a.tar.gz
rockbox-1459bbc45f728c610daba7c4b51d9494cb34760a.zip
Various dircache improvements: reduce size of a path buffer to MAX_PATH and rewrote copy_path to improve stack usage. Also simplified get_entry.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24445 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/common/dircache.c')
-rw-r--r--firmware/common/dircache.c64
1 files changed, 32 insertions, 32 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index 7ff497790e..66189c48a8 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -71,7 +71,7 @@ static unsigned long entry_count = 0;
71static unsigned long reserve_used = 0; 71static unsigned long reserve_used = 0;
72static unsigned int cache_build_ticks = 0; 72static unsigned int cache_build_ticks = 0;
73static unsigned long appflags = 0; 73static unsigned long appflags = 0;
74static char dircache_cur_path[MAX_PATH*2]; 74static char dircache_cur_path[MAX_PATH];
75 75
76static struct event_queue dircache_queue; 76static struct event_queue dircache_queue;
77static long dircache_stack[(DEFAULT_STACK_SIZE + 0x900)/sizeof(long)]; 77static long dircache_stack[(DEFAULT_STACK_SIZE + 0x900)/sizeof(long)];
@@ -393,7 +393,8 @@ static int dircache_travel(IF_MV2(int volume,) struct fat_dir *dir, struct dirca
393 * path: Absolute path to a file or directory (see comment) 393 * path: Absolute path to a file or directory (see comment)
394 * go_down: Returns the first entry of the directory given by the path (see comment) 394 * go_down: Returns the first entry of the directory given by the path (see comment)
395 * 395 *
396 * As a a special case to handle buggy code, accept path="" as an alias for "/" 396 * As a a special case, accept path="" as an alias for "/".
397 * Also if the path omits the first '/', it will be accepted.
397 * 398 *
398 * * If get_down=true: 399 * * If get_down=true:
399 * If path="/", the returned entry is the first of root directory (ie dircache_root) 400 * If path="/", the returned entry is the first of root directory (ie dircache_root)
@@ -420,16 +421,7 @@ static struct dircache_entry* dircache_get_entry(const char *path, bool go_down)
420 bool at_root = true; 421 bool at_root = true;
421 struct dircache_entry *cache_entry = dircache_root; 422 struct dircache_entry *cache_entry = dircache_root;
422 423
423 /* check that the path is absolute (accept empty path also) */ 424 strlcpy(namecopy, path, sizeof(namecopy));
424 if(path[0] != '/' && path[0] != 0)
425 return NULL;
426
427 /* make a copy of the path because strok_r modifies the path */
428 /* also handle the weird "" alias for "/" */
429 if(path[0] != 0)
430 strlcpy(namecopy, path, sizeof(namecopy));
431 else
432 strlcpy(namecopy, "/", sizeof(namecopy));
433 425
434 for(part = strtok_r(namecopy, "/", &end); part; part = strtok_r(NULL, "/", &end)) 426 for(part = strtok_r(namecopy, "/", &end); part; part = strtok_r(NULL, "/", &end))
435 { 427 {
@@ -913,31 +905,39 @@ const struct dircache_entry *dircache_get_entry_ptr(const char *filename)
913 */ 905 */
914void dircache_copy_path(const struct dircache_entry *entry, char *buf, int size) 906void dircache_copy_path(const struct dircache_entry *entry, char *buf, int size)
915{ 907{
916 const struct dircache_entry *down[MAX_SCAN_DEPTH]; 908 int path_size = 0;
917 int depth = 0; 909 int idx;
910 const struct dircache_entry *temp = entry;
918 911
919 if (size <= 0) 912 if (size <= 0)
920 return ; 913 return ;
914
915 /* first compute the necessary size */
916 while(temp != NULL)
917 {
918 path_size += temp->name_len; /* '/' + d_name */
919 temp = temp->up;
920 }
921 921
922 buf[0] = '\0'; 922 /* now copy the path */
923 923 /* doesn't matter with trailing 0 because it's added later */
924 if (entry == NULL) 924 idx = path_size;
925 return ; 925 while(entry != NULL)
926
927 do {
928 down[depth] = entry;
929 entry = entry->up;
930 depth++;
931 } while (entry != NULL && depth < MAX_SCAN_DEPTH);
932
933 while (--depth >= 0)
934 { 926 {
935 snprintf(buf, size, "/%s", down[depth]->d_name); 927 idx -= entry->name_len;
936 buf += down[depth]->name_len; /* '/' + d_name */ 928 /* available size */
937 size -= down[depth]->name_len; 929 int rem = size - idx;
938 if (size <= 0) 930
939 break ; 931 if(rem >= 1)
932 {
933 buf[idx] = '/';
934 memcpy(buf + idx + 1, entry->d_name, MIN((size_t)(rem - 1), (size_t)(entry->name_len - 1)));
935 }
936 entry = entry->up;
940 } 937 }
938
939 /* add trailing 0 */
940 buf[MIN(path_size, size-1)] = 0;
941} 941}
942 942
943/* --- Directory cache live updating functions --- */ 943/* --- Directory cache live updating functions --- */
@@ -1060,7 +1060,7 @@ void dircache_update_filesize(int fd, long newsize, long startcluster)
1060 1060
1061 if (fd_bindings[fd] == NULL) 1061 if (fd_bindings[fd] == NULL)
1062 { 1062 {
1063 logf("dircache fd access error"); 1063 logf("dircache fd(%d) access error", fd);
1064 dircache_initialized = false; 1064 dircache_initialized = false;
1065 return ; 1065 return ;
1066 } 1066 }