diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2008-03-11 19:39:26 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2008-03-11 19:39:26 +0000 |
commit | 52d827a26dec8bc4967cf3c2984a10ace114fa21 (patch) | |
tree | 83b9660b904934a62df38ee0ed138c66f3cdebb1 /firmware/common/dircache.c | |
parent | afde7f74d4325c3a5a6883167c1f74f4fb689f90 (diff) | |
download | rockbox-52d827a26dec8bc4967cf3c2984a10ace114fa21.tar.gz rockbox-52d827a26dec8bc4967cf3c2984a10ace114fa21.zip |
FS#7598 - Dircache support for multivolume targets (by Phil Light).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16632 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/common/dircache.c')
-rw-r--r-- | firmware/common/dircache.c | 106 |
1 files changed, 77 insertions, 29 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index ed392d6186..bf8ff45cff 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "usb.h" | 37 | #include "usb.h" |
38 | #include "file.h" | 38 | #include "file.h" |
39 | #include "buffer.h" | 39 | #include "buffer.h" |
40 | #include "dir.h" | ||
40 | #if CONFIG_RTC | 41 | #if CONFIG_RTC |
41 | #include "time.h" | 42 | #include "time.h" |
42 | #include "timefuncs.h" | 43 | #include "timefuncs.h" |
@@ -51,6 +52,9 @@ DIR_CACHED opendirs[MAX_OPEN_DIRS]; | |||
51 | 52 | ||
52 | static struct dircache_entry *fd_bindings[MAX_OPEN_FILES]; | 53 | static struct dircache_entry *fd_bindings[MAX_OPEN_FILES]; |
53 | static struct dircache_entry *dircache_root; | 54 | static struct dircache_entry *dircache_root; |
55 | #ifdef HAVE_MULTIVOLUME | ||
56 | static struct dircache_entry *append_position; | ||
57 | #endif | ||
54 | 58 | ||
55 | static bool dircache_initialized = false; | 59 | static bool dircache_initialized = false; |
56 | static bool dircache_initializing = false; | 60 | static bool dircache_initializing = false; |
@@ -155,6 +159,9 @@ static bool check_event_queue(void) | |||
155 | { | 159 | { |
156 | case DIRCACHE_STOP: | 160 | case DIRCACHE_STOP: |
157 | case SYS_USB_CONNECTED: | 161 | case SYS_USB_CONNECTED: |
162 | #ifdef HAVE_HOTSWAP | ||
163 | case SYS_FS_CHANGED: | ||
164 | #endif | ||
158 | /* Put the event back into the queue. */ | 165 | /* Put the event back into the queue. */ |
159 | queue_post(&dircache_queue, ev.id, ev.data); | 166 | queue_post(&dircache_queue, ev.id, ev.data); |
160 | return true; | 167 | return true; |
@@ -166,7 +173,7 @@ static bool check_event_queue(void) | |||
166 | /** | 173 | /** |
167 | * Internal function to iterate a path. | 174 | * Internal function to iterate a path. |
168 | */ | 175 | */ |
169 | static int dircache_scan(struct travel_data *td) | 176 | static int dircache_scan(IF_MV2(int volume,) struct travel_data *td) |
170 | { | 177 | { |
171 | #ifdef SIMULATOR | 178 | #ifdef SIMULATOR |
172 | while ( ( td->entry = readdir_uncached(td->dir) ) ) | 179 | while ( ( td->entry = readdir_uncached(td->dir) ) ) |
@@ -273,22 +280,37 @@ static int dircache_scan(struct travel_data *td) | |||
273 | * Recursively scan the hard disk and build the cache. | 280 | * Recursively scan the hard disk and build the cache. |
274 | */ | 281 | */ |
275 | #ifdef SIMULATOR | 282 | #ifdef SIMULATOR |
276 | static int dircache_travel(DIR_UNCACHED *dir, struct dircache_entry *ce) | 283 | static int dircache_travel(IF_MV2(int volume,) DIR_UNCACHED *dir, struct dircache_entry *ce) |
277 | #else | 284 | #else |
278 | static int dircache_travel(struct fat_dir *dir, struct dircache_entry *ce) | 285 | static int dircache_travel(IF_MV2(int volume,) struct fat_dir *dir, struct dircache_entry *ce) |
279 | #endif | 286 | #endif |
280 | { | 287 | { |
281 | int depth = 0; | 288 | int depth = 0; |
282 | int result; | 289 | int result; |
283 | 290 | ||
284 | memset(ce, 0, sizeof(struct dircache_entry)); | 291 | memset(ce, 0, sizeof(struct dircache_entry)); |
292 | |||
293 | #if defined(HAVE_MULTIVOLUME) && !defined(SIMULATOR) | ||
294 | if (volume > 0) | ||
295 | { | ||
296 | ce->d_name = ((char *)dircache_root+dircache_size); | ||
297 | snprintf(ce->d_name, VOL_ENUM_POS + 3, VOL_NAMES, volume); | ||
298 | ce->name_len = VOL_ENUM_POS + 3; | ||
299 | dircache_size += ce->name_len; | ||
300 | ce->attribute = FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME; | ||
301 | ce->size = 0; | ||
302 | append_position = dircache_gen_next(ce); | ||
303 | ce = dircache_gen_down(ce); | ||
304 | } | ||
305 | #endif | ||
306 | |||
285 | dir_recursion[0].dir = dir; | 307 | dir_recursion[0].dir = dir; |
286 | dir_recursion[0].ce = ce; | 308 | dir_recursion[0].ce = ce; |
287 | dir_recursion[0].first = ce; | 309 | dir_recursion[0].first = ce; |
288 | 310 | ||
289 | do { | 311 | do { |
290 | //logf("=> %s", dircache_cur_path); | 312 | //logf("=> %s", dircache_cur_path); |
291 | result = dircache_scan(&dir_recursion[depth]); | 313 | result = dircache_scan(IF_MV2(volume,) &dir_recursion[depth]); |
292 | switch (result) { | 314 | switch (result) { |
293 | case 0: /* Leaving the current directory. */ | 315 | case 0: /* Leaving the current directory. */ |
294 | /* Add the standard . and .. entries. */ | 316 | /* Add the standard . and .. entries. */ |
@@ -536,37 +558,57 @@ static int dircache_do_rebuild(void) | |||
536 | start_tick = current_tick; | 558 | start_tick = current_tick; |
537 | dircache_initializing = true; | 559 | dircache_initializing = true; |
538 | appflags = 0; | 560 | appflags = 0; |
561 | entry_count = 0; | ||
539 | 562 | ||
540 | #ifdef SIMULATOR | ||
541 | pdir = opendir_uncached("/"); | ||
542 | if (pdir == NULL) | ||
543 | { | ||
544 | logf("Failed to open rootdir"); | ||
545 | dircache_initializing = false; | ||
546 | return -3; | ||
547 | } | ||
548 | #else | ||
549 | if ( fat_opendir(IF_MV2(volume,) &dir, 0, NULL) < 0 ) { | ||
550 | logf("Failed opening root dir"); | ||
551 | dircache_initializing = false; | ||
552 | return -3; | ||
553 | } | ||
554 | pdir = &dir; | ||
555 | #endif | ||
556 | |||
557 | memset(dircache_cur_path, 0, sizeof(dircache_cur_path)); | 563 | memset(dircache_cur_path, 0, sizeof(dircache_cur_path)); |
558 | dircache_size = sizeof(struct dircache_entry); | 564 | dircache_size = sizeof(struct dircache_entry); |
559 | 565 | ||
560 | cpu_boost(true); | 566 | #ifdef HAVE_MULTIVOLUME |
561 | if (dircache_travel(pdir, dircache_root) < 0) | 567 | append_position = dircache_root; |
568 | |||
569 | for (i = NUM_VOLUMES; i >= 0; i--) | ||
562 | { | 570 | { |
563 | logf("dircache_travel failed"); | 571 | if (fat_ismounted(i)) |
564 | cpu_boost(false); | 572 | { |
565 | dircache_size = 0; | 573 | #endif |
566 | dircache_initializing = false; | 574 | #ifdef SIMULATOR |
567 | return -2; | 575 | pdir = opendir_uncached("/"); |
576 | if (pdir == NULL) | ||
577 | { | ||
578 | logf("Failed to open rootdir"); | ||
579 | dircache_initializing = false; | ||
580 | return -3; | ||
581 | } | ||
582 | #else | ||
583 | #ifdef HAVE_MULTIVOLUME | ||
584 | if ( fat_opendir(IF_MV2(i,) &dir, 0, NULL) < 0 ) { | ||
585 | #else | ||
586 | if ( fat_opendir(IF_MV2(0,) &dir, 0, NULL) < 0 ) { | ||
587 | #endif /* HAVE_MULTIVOLUME */ | ||
588 | logf("Failed opening root dir"); | ||
589 | dircache_initializing = false; | ||
590 | return -3; | ||
591 | } | ||
592 | pdir = &dir; | ||
593 | #endif | ||
594 | cpu_boost(true); | ||
595 | #ifdef HAVE_MULTIVOLUME | ||
596 | if (dircache_travel(IF_MV2(i,) pdir, append_position) < 0) | ||
597 | #else | ||
598 | if (dircache_travel(IF_MV2(0,) pdir, dircache_root) < 0) | ||
599 | #endif /* HAVE_MULTIVOLUME */ | ||
600 | { | ||
601 | logf("dircache_travel failed"); | ||
602 | cpu_boost(false); | ||
603 | dircache_size = 0; | ||
604 | dircache_initializing = false; | ||
605 | return -2; | ||
606 | } | ||
607 | cpu_boost(false); | ||
608 | #ifdef HAVE_MULTIVOLUME | ||
609 | } | ||
568 | } | 610 | } |
569 | cpu_boost(false); | 611 | #endif |
570 | 612 | ||
571 | logf("Done, %ld KiB used", dircache_size / 1024); | 613 | logf("Done, %ld KiB used", dircache_size / 1024); |
572 | 614 | ||
@@ -610,6 +652,12 @@ static void dircache_thread(void) | |||
610 | 652 | ||
611 | switch (ev.id) | 653 | switch (ev.id) |
612 | { | 654 | { |
655 | #ifdef HAVE_HOTSWAP | ||
656 | case SYS_FS_CHANGED: | ||
657 | if (!dircache_initialized) | ||
658 | break; | ||
659 | dircache_initialized = false; | ||
660 | #endif | ||
613 | case DIRCACHE_BUILD: | 661 | case DIRCACHE_BUILD: |
614 | thread_enabled = true; | 662 | thread_enabled = true; |
615 | dircache_do_rebuild(); | 663 | dircache_do_rebuild(); |