More safety checks to dircache to block updates until cache is ready.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9339 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
029ff80235
commit
6ce466ea2c
2 changed files with 51 additions and 6 deletions
|
@ -52,6 +52,7 @@ static struct dircache_entry *fd_bindings[MAX_OPEN_FILES];
|
||||||
static struct dircache_entry *dircache_root;
|
static struct dircache_entry *dircache_root;
|
||||||
|
|
||||||
static bool dircache_initialized = false;
|
static bool dircache_initialized = false;
|
||||||
|
static bool dircache_initializing = false;
|
||||||
static bool thread_enabled = false;
|
static bool thread_enabled = false;
|
||||||
static unsigned long allocated_size = DIRCACHE_LIMIT;
|
static unsigned long allocated_size = DIRCACHE_LIMIT;
|
||||||
static unsigned long dircache_size = 0;
|
static unsigned long dircache_size = 0;
|
||||||
|
@ -64,6 +65,9 @@ static struct event_queue dircache_queue;
|
||||||
static long dircache_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)];
|
static long dircache_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)];
|
||||||
static const char dircache_thread_name[] = "dircache";
|
static const char dircache_thread_name[] = "dircache";
|
||||||
|
|
||||||
|
static struct fdbind_queue fdbind_cache[MAX_PENDING_BINDINGS];
|
||||||
|
static int fdbind_idx = 0;
|
||||||
|
|
||||||
/* --- Internal cache structure control functions --- */
|
/* --- Internal cache structure control functions --- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -446,12 +450,15 @@ static int dircache_do_rebuild(void)
|
||||||
{
|
{
|
||||||
struct fat_dir dir;
|
struct fat_dir dir;
|
||||||
unsigned int start_tick;
|
unsigned int start_tick;
|
||||||
|
int i;
|
||||||
|
|
||||||
/* Measure how long it takes build the cache. */
|
/* Measure how long it takes build the cache. */
|
||||||
start_tick = current_tick;
|
start_tick = current_tick;
|
||||||
|
dircache_initializing = true;
|
||||||
|
|
||||||
if ( fat_opendir(IF_MV2(volume,) &dir, 0, NULL) < 0 ) {
|
if ( fat_opendir(IF_MV2(volume,) &dir, 0, NULL) < 0 ) {
|
||||||
logf("Failed opening root dir");
|
logf("Failed opening root dir");
|
||||||
|
dircache_initializing = false;
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,14 +479,22 @@ static int dircache_do_rebuild(void)
|
||||||
logf("dircache_travel failed");
|
logf("dircache_travel failed");
|
||||||
cpu_boost(false);
|
cpu_boost(false);
|
||||||
dircache_size = 0;
|
dircache_size = 0;
|
||||||
|
dircache_initializing = false;
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
cpu_boost(false);
|
cpu_boost(false);
|
||||||
|
|
||||||
logf("Done, %d KiB used", dircache_size / 1024);
|
logf("Done, %d KiB used", dircache_size / 1024);
|
||||||
|
|
||||||
dircache_initialized = true;
|
dircache_initialized = true;
|
||||||
|
dircache_initializing = false;
|
||||||
cache_build_ticks = current_tick - start_tick;
|
cache_build_ticks = current_tick - start_tick;
|
||||||
|
|
||||||
|
/* Initialized fd bindings. */
|
||||||
|
memset(fd_bindings, 0, sizeof(fd_bindings));
|
||||||
|
for (i = 0; i < fdbind_idx; i++)
|
||||||
|
dircache_bind(fdbind_cache[i].fd, fdbind_cache[i].path);
|
||||||
|
|
||||||
if (thread_enabled)
|
if (thread_enabled)
|
||||||
{
|
{
|
||||||
if (allocated_size - dircache_size < DIRCACHE_RESERVE)
|
if (allocated_size - dircache_size < DIRCACHE_RESERVE)
|
||||||
|
@ -710,6 +725,18 @@ void dircache_copy_path(const struct dircache_entry *entry, char *buf, int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- Directory cache live updating functions --- */
|
/* --- Directory cache live updating functions --- */
|
||||||
|
static int block_until_ready(void)
|
||||||
|
{
|
||||||
|
/* Block until dircache has been built. */
|
||||||
|
while (!dircache_initialized && dircache_initializing)
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
if (!dircache_initialized)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct dircache_entry* dircache_new_entry(const char *path, int attribute)
|
static struct dircache_entry* dircache_new_entry(const char *path, int attribute)
|
||||||
{
|
{
|
||||||
struct dircache_entry *entry;
|
struct dircache_entry *entry;
|
||||||
|
@ -783,6 +810,18 @@ void dircache_bind(int fd, const char *path)
|
||||||
{
|
{
|
||||||
struct dircache_entry *entry;
|
struct dircache_entry *entry;
|
||||||
|
|
||||||
|
/* Queue requests until dircache has been built. */
|
||||||
|
if (!dircache_initialized && dircache_initializing)
|
||||||
|
{
|
||||||
|
if (fdbind_idx >= MAX_PENDING_BINDINGS)
|
||||||
|
return ;
|
||||||
|
strncpy(fdbind_cache[fdbind_idx].path, path,
|
||||||
|
sizeof(fdbind_cache[fdbind_idx].path)-1);
|
||||||
|
fdbind_cache[fdbind_idx].fd = fd;
|
||||||
|
fdbind_idx++;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
if (!dircache_initialized)
|
if (!dircache_initialized)
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
|
@ -816,7 +855,7 @@ void dircache_update_filesize(int fd, long newsize, long startcluster)
|
||||||
|
|
||||||
void dircache_mkdir(const char *path)
|
void dircache_mkdir(const char *path)
|
||||||
{ /* Test ok. */
|
{ /* Test ok. */
|
||||||
if (!dircache_initialized)
|
if (block_until_ready())
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
logf("mkdir: %s", path);
|
logf("mkdir: %s", path);
|
||||||
|
@ -827,7 +866,7 @@ void dircache_rmdir(const char *path)
|
||||||
{ /* Test ok. */
|
{ /* Test ok. */
|
||||||
struct dircache_entry *entry;
|
struct dircache_entry *entry;
|
||||||
|
|
||||||
if (!dircache_initialized)
|
if (block_until_ready())
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
logf("rmdir: %s", path);
|
logf("rmdir: %s", path);
|
||||||
|
@ -848,7 +887,7 @@ void dircache_remove(const char *name)
|
||||||
{ /* Test ok. */
|
{ /* Test ok. */
|
||||||
struct dircache_entry *entry;
|
struct dircache_entry *entry;
|
||||||
|
|
||||||
if (!dircache_initialized)
|
if (block_until_ready())
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
logf("remove: %s", name);
|
logf("remove: %s", name);
|
||||||
|
@ -872,7 +911,7 @@ void dircache_rename(const char *oldpath, const char *newpath)
|
||||||
char absolute_path[MAX_PATH];
|
char absolute_path[MAX_PATH];
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
if (!dircache_initialized)
|
if (block_until_ready())
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
logf("rename: %s->%s", oldpath, newpath);
|
logf("rename: %s->%s", oldpath, newpath);
|
||||||
|
@ -927,9 +966,9 @@ void dircache_add_file(const char *path, long startcluster)
|
||||||
{
|
{
|
||||||
struct dircache_entry *entry;
|
struct dircache_entry *entry;
|
||||||
|
|
||||||
if (!dircache_initialized)
|
if (block_until_ready())
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
logf("add file: %s", path);
|
logf("add file: %s", path);
|
||||||
entry = dircache_new_entry(path, 0);
|
entry = dircache_new_entry(path, 0);
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
|
|
|
@ -46,6 +46,12 @@ struct dircache_maindata {
|
||||||
struct dircache_entry *root_entry;
|
struct dircache_entry *root_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_PENDING_BINDINGS 2
|
||||||
|
struct fdbind_queue {
|
||||||
|
char path[MAX_PATH];
|
||||||
|
int fd;
|
||||||
|
};
|
||||||
|
|
||||||
/* Exported structures. */
|
/* Exported structures. */
|
||||||
struct dircache_entry {
|
struct dircache_entry {
|
||||||
struct dircache_entry *next;
|
struct dircache_entry *next;
|
||||||
|
|
Loading…
Reference in a new issue