1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Amaury Pouly 2010-02-01 23:00:35 +00:00
parent fb680535f6
commit 1459bbc45f

View file

@ -71,7 +71,7 @@ static unsigned long entry_count = 0;
static unsigned long reserve_used = 0; static unsigned long reserve_used = 0;
static unsigned int cache_build_ticks = 0; static unsigned int cache_build_ticks = 0;
static unsigned long appflags = 0; static unsigned long appflags = 0;
static char dircache_cur_path[MAX_PATH*2]; static char dircache_cur_path[MAX_PATH];
static struct event_queue dircache_queue; static struct event_queue dircache_queue;
static long dircache_stack[(DEFAULT_STACK_SIZE + 0x900)/sizeof(long)]; static 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
* path: Absolute path to a file or directory (see comment) * path: Absolute path to a file or directory (see comment)
* go_down: Returns the first entry of the directory given by the path (see comment) * go_down: Returns the first entry of the directory given by the path (see comment)
* *
* As a a special case to handle buggy code, accept path="" as an alias for "/" * As a a special case, accept path="" as an alias for "/".
* Also if the path omits the first '/', it will be accepted.
* *
* * If get_down=true: * * If get_down=true:
* If path="/", the returned entry is the first of root directory (ie dircache_root) * 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)
bool at_root = true; bool at_root = true;
struct dircache_entry *cache_entry = dircache_root; struct dircache_entry *cache_entry = dircache_root;
/* check that the path is absolute (accept empty path also) */ strlcpy(namecopy, path, sizeof(namecopy));
if(path[0] != '/' && path[0] != 0)
return NULL;
/* make a copy of the path because strok_r modifies the path */
/* also handle the weird "" alias for "/" */
if(path[0] != 0)
strlcpy(namecopy, path, sizeof(namecopy));
else
strlcpy(namecopy, "/", sizeof(namecopy));
for(part = strtok_r(namecopy, "/", &end); part; part = strtok_r(NULL, "/", &end)) for(part = strtok_r(namecopy, "/", &end); part; part = strtok_r(NULL, "/", &end))
{ {
@ -913,31 +905,39 @@ const struct dircache_entry *dircache_get_entry_ptr(const char *filename)
*/ */
void dircache_copy_path(const struct dircache_entry *entry, char *buf, int size) void dircache_copy_path(const struct dircache_entry *entry, char *buf, int size)
{ {
const struct dircache_entry *down[MAX_SCAN_DEPTH]; int path_size = 0;
int depth = 0; int idx;
const struct dircache_entry *temp = entry;
if (size <= 0) if (size <= 0)
return ; return ;
buf[0] = '\0'; /* first compute the necessary size */
while(temp != NULL)
if (entry == NULL)
return ;
do {
down[depth] = entry;
entry = entry->up;
depth++;
} while (entry != NULL && depth < MAX_SCAN_DEPTH);
while (--depth >= 0)
{ {
snprintf(buf, size, "/%s", down[depth]->d_name); path_size += temp->name_len; /* '/' + d_name */
buf += down[depth]->name_len; /* '/' + d_name */ temp = temp->up;
size -= down[depth]->name_len;
if (size <= 0)
break ;
} }
/* now copy the path */
/* doesn't matter with trailing 0 because it's added later */
idx = path_size;
while(entry != NULL)
{
idx -= entry->name_len;
/* available size */
int rem = size - idx;
if(rem >= 1)
{
buf[idx] = '/';
memcpy(buf + idx + 1, entry->d_name, MIN((size_t)(rem - 1), (size_t)(entry->name_len - 1)));
}
entry = entry->up;
}
/* add trailing 0 */
buf[MIN(path_size, size-1)] = 0;
} }
/* --- Directory cache live updating functions --- */ /* --- Directory cache live updating functions --- */
@ -1060,7 +1060,7 @@ void dircache_update_filesize(int fd, long newsize, long startcluster)
if (fd_bindings[fd] == NULL) if (fd_bindings[fd] == NULL)
{ {
logf("dircache fd access error"); logf("dircache fd(%d) access error", fd);
dircache_initialized = false; dircache_initialized = false;
return ; return ;
} }