summaryrefslogtreecommitdiff
path: root/firmware/common/dircache.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/common/dircache.c')
-rw-r--r--firmware/common/dircache.c51
1 files changed, 45 insertions, 6 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index 873e0f9cf4..efab37b5c4 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -52,6 +52,7 @@ static struct dircache_entry *fd_bindings[MAX_OPEN_FILES];
52static struct dircache_entry *dircache_root; 52static struct dircache_entry *dircache_root;
53 53
54static bool dircache_initialized = false; 54static bool dircache_initialized = false;
55static bool dircache_initializing = false;
55static bool thread_enabled = false; 56static bool thread_enabled = false;
56static unsigned long allocated_size = DIRCACHE_LIMIT; 57static unsigned long allocated_size = DIRCACHE_LIMIT;
57static unsigned long dircache_size = 0; 58static unsigned long dircache_size = 0;
@@ -64,6 +65,9 @@ static struct event_queue dircache_queue;
64static long dircache_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; 65static long dircache_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)];
65static const char dircache_thread_name[] = "dircache"; 66static const char dircache_thread_name[] = "dircache";
66 67
68static struct fdbind_queue fdbind_cache[MAX_PENDING_BINDINGS];
69static int fdbind_idx = 0;
70
67/* --- Internal cache structure control functions --- */ 71/* --- Internal cache structure control functions --- */
68 72
69/** 73/**
@@ -446,12 +450,15 @@ static int dircache_do_rebuild(void)
446{ 450{
447 struct fat_dir dir; 451 struct fat_dir dir;
448 unsigned int start_tick; 452 unsigned int start_tick;
453 int i;
449 454
450 /* Measure how long it takes build the cache. */ 455 /* Measure how long it takes build the cache. */
451 start_tick = current_tick; 456 start_tick = current_tick;
457 dircache_initializing = true;
452 458
453 if ( fat_opendir(IF_MV2(volume,) &dir, 0, NULL) < 0 ) { 459 if ( fat_opendir(IF_MV2(volume,) &dir, 0, NULL) < 0 ) {
454 logf("Failed opening root dir"); 460 logf("Failed opening root dir");
461 dircache_initializing = false;
455 return -3; 462 return -3;
456 } 463 }
457 464
@@ -472,14 +479,22 @@ static int dircache_do_rebuild(void)
472 logf("dircache_travel failed"); 479 logf("dircache_travel failed");
473 cpu_boost(false); 480 cpu_boost(false);
474 dircache_size = 0; 481 dircache_size = 0;
482 dircache_initializing = false;
475 return -2; 483 return -2;
476 } 484 }
477 cpu_boost(false); 485 cpu_boost(false);
478 486
479 logf("Done, %d KiB used", dircache_size / 1024); 487 logf("Done, %d KiB used", dircache_size / 1024);
488
480 dircache_initialized = true; 489 dircache_initialized = true;
490 dircache_initializing = false;
481 cache_build_ticks = current_tick - start_tick; 491 cache_build_ticks = current_tick - start_tick;
482 492
493 /* Initialized fd bindings. */
494 memset(fd_bindings, 0, sizeof(fd_bindings));
495 for (i = 0; i < fdbind_idx; i++)
496 dircache_bind(fdbind_cache[i].fd, fdbind_cache[i].path);
497
483 if (thread_enabled) 498 if (thread_enabled)
484 { 499 {
485 if (allocated_size - dircache_size < DIRCACHE_RESERVE) 500 if (allocated_size - dircache_size < DIRCACHE_RESERVE)
@@ -710,6 +725,18 @@ void dircache_copy_path(const struct dircache_entry *entry, char *buf, int size)
710} 725}
711 726
712/* --- Directory cache live updating functions --- */ 727/* --- Directory cache live updating functions --- */
728static int block_until_ready(void)
729{
730 /* Block until dircache has been built. */
731 while (!dircache_initialized && dircache_initializing)
732 sleep(1);
733
734 if (!dircache_initialized)
735 return -1;
736
737 return 0;
738}
739
713static struct dircache_entry* dircache_new_entry(const char *path, int attribute) 740static struct dircache_entry* dircache_new_entry(const char *path, int attribute)
714{ 741{
715 struct dircache_entry *entry; 742 struct dircache_entry *entry;
@@ -783,6 +810,18 @@ void dircache_bind(int fd, const char *path)
783{ 810{
784 struct dircache_entry *entry; 811 struct dircache_entry *entry;
785 812
813 /* Queue requests until dircache has been built. */
814 if (!dircache_initialized && dircache_initializing)
815 {
816 if (fdbind_idx >= MAX_PENDING_BINDINGS)
817 return ;
818 strncpy(fdbind_cache[fdbind_idx].path, path,
819 sizeof(fdbind_cache[fdbind_idx].path)-1);
820 fdbind_cache[fdbind_idx].fd = fd;
821 fdbind_idx++;
822 return ;
823 }
824
786 if (!dircache_initialized) 825 if (!dircache_initialized)
787 return ; 826 return ;
788 827
@@ -816,7 +855,7 @@ void dircache_update_filesize(int fd, long newsize, long startcluster)
816 855
817void dircache_mkdir(const char *path) 856void dircache_mkdir(const char *path)
818{ /* Test ok. */ 857{ /* Test ok. */
819 if (!dircache_initialized) 858 if (block_until_ready())
820 return ; 859 return ;
821 860
822 logf("mkdir: %s", path); 861 logf("mkdir: %s", path);
@@ -827,7 +866,7 @@ void dircache_rmdir(const char *path)
827{ /* Test ok. */ 866{ /* Test ok. */
828 struct dircache_entry *entry; 867 struct dircache_entry *entry;
829 868
830 if (!dircache_initialized) 869 if (block_until_ready())
831 return ; 870 return ;
832 871
833 logf("rmdir: %s", path); 872 logf("rmdir: %s", path);
@@ -848,7 +887,7 @@ void dircache_remove(const char *name)
848{ /* Test ok. */ 887{ /* Test ok. */
849 struct dircache_entry *entry; 888 struct dircache_entry *entry;
850 889
851 if (!dircache_initialized) 890 if (block_until_ready())
852 return ; 891 return ;
853 892
854 logf("remove: %s", name); 893 logf("remove: %s", name);
@@ -872,7 +911,7 @@ void dircache_rename(const char *oldpath, const char *newpath)
872 char absolute_path[MAX_PATH]; 911 char absolute_path[MAX_PATH];
873 char *p; 912 char *p;
874 913
875 if (!dircache_initialized) 914 if (block_until_ready())
876 return ; 915 return ;
877 916
878 logf("rename: %s->%s", oldpath, newpath); 917 logf("rename: %s->%s", oldpath, newpath);
@@ -927,9 +966,9 @@ void dircache_add_file(const char *path, long startcluster)
927{ 966{
928 struct dircache_entry *entry; 967 struct dircache_entry *entry;
929 968
930 if (!dircache_initialized) 969 if (block_until_ready())
931 return ; 970 return ;
932 971
933 logf("add file: %s", path); 972 logf("add file: %s", path);
934 entry = dircache_new_entry(path, 0); 973 entry = dircache_new_entry(path, 0);
935 if (entry == NULL) 974 if (entry == NULL)