diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2017-01-18 04:39:35 -0500 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2017-02-10 05:05:23 -0500 |
commit | 7373cf518f4d4c47f49693690c2ab8ec29bb8510 (patch) | |
tree | 0a3c025749be24561e952078e83c5f2e8b838900 /apps/tagcache.c | |
parent | abd75a17d18c0779b59f64a612f9226b62af5823 (diff) | |
download | rockbox-7373cf518f4d4c47f49693690c2ab8ec29bb8510.tar.gz rockbox-7373cf518f4d4c47f49693690c2ab8ec29bb8510.zip |
Restore dircache hookup in the database ramcache.
Do a few other changes to dircache and file code flags to
accomodate its demands.
Change-Id: I4742a54e8cfbe4d8b9cffb75faaf920dd907cf8a
Diffstat (limited to 'apps/tagcache.c')
-rw-r--r-- | apps/tagcache.c | 837 |
1 files changed, 434 insertions, 403 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c index 2b3c7212a2..be4686679b 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c | |||
@@ -82,18 +82,15 @@ | |||
82 | #include "pathfuncs.h" | 82 | #include "pathfuncs.h" |
83 | #include "structec.h" | 83 | #include "structec.h" |
84 | #include "debug.h" | 84 | #include "debug.h" |
85 | #ifdef HAVE_DIRCACHE | ||
86 | #include "dircache.h" | ||
87 | #endif | ||
85 | 88 | ||
86 | #ifndef __PCTOOL__ | 89 | #ifndef __PCTOOL__ |
87 | #include "lang.h" | 90 | #include "lang.h" |
88 | #include "eeprom_settings.h" | 91 | #include "eeprom_settings.h" |
89 | #endif | 92 | #endif |
90 | 93 | ||
91 | #undef HAVE_DIRCACHE | ||
92 | |||
93 | #ifdef HAVE_DIRCACHE | ||
94 | #include "dircache.h" | ||
95 | #endif | ||
96 | |||
97 | #ifdef __PCTOOL__ | 94 | #ifdef __PCTOOL__ |
98 | #define yield() do { } while(0) | 95 | #define yield() do { } while(0) |
99 | #define sim_sleep(timeout) do { } while(0) | 96 | #define sim_sleep(timeout) do { } while(0) |
@@ -213,27 +210,60 @@ static const char * const master_header_ec = "llllll"; | |||
213 | static struct master_header current_tcmh; | 210 | static struct master_header current_tcmh; |
214 | 211 | ||
215 | #ifdef HAVE_TC_RAMCACHE | 212 | #ifdef HAVE_TC_RAMCACHE |
213 | |||
214 | #define TC_ALIGN_PTR(p, gap_out_p) \ | ||
215 | ({ typeof (p) __p = (p); \ | ||
216 | typeof (p) __palgn = ALIGN_UP(__p, sizeof (intptr_t)); \ | ||
217 | *(gap_out_p) = __palgn - __p; \ | ||
218 | __palgn; }) | ||
219 | |||
220 | #define IF_TCRCDC(...) IF_DIRCACHE(__VA_ARGS__) | ||
221 | |||
222 | #ifdef HAVE_DIRCACHE | ||
223 | #define tcrc_dcfrefs \ | ||
224 | ((struct dircache_fileref *)(tcramcache.hdr->tags[tag_filename] + \ | ||
225 | sizeof (struct tagcache_header))) | ||
226 | #endif /* HAVE_DIRCACHE */ | ||
227 | |||
216 | /* Header is created when loading database to ram. */ | 228 | /* Header is created when loading database to ram. */ |
217 | struct ramcache_header { | 229 | struct ramcache_header { |
218 | char *tags[TAG_COUNT]; /* Tag file content (not including filename tag) */ | 230 | char *tags[TAG_COUNT]; /* Tag file content (dcfrefs if tag_filename) */ |
219 | int entry_count[TAG_COUNT]; /* Number of entries in the indices. */ | 231 | int entry_count[TAG_COUNT]; /* Number of entries in the indices. */ |
220 | struct index_entry indices[0]; /* Master index file content */ | 232 | struct index_entry indices[0]; /* Master index file content */ |
221 | }; | 233 | }; |
222 | 234 | ||
223 | # ifdef HAVE_EEPROM_SETTINGS | 235 | #ifdef HAVE_EEPROM_SETTINGS |
224 | struct statefile_header { | 236 | struct statefile_header { |
225 | int32_t magic; /* Statefile version number */ | 237 | int32_t magic; /* Statefile version number */ |
226 | struct master_header mh; /* Header from the master index */ | 238 | struct master_header mh; /* Header from the master index */ |
227 | struct ramcache_header *hdr; /* Old load address of hdr for relocation */ | 239 | struct ramcache_header *hdr; /* Old load address of hdr for relocation */ |
228 | struct tagcache_stat tc_stat; | 240 | struct tagcache_stat tc_stat; |
229 | }; | 241 | }; |
230 | # endif | 242 | #endif /* HAVE_EEPROM_SETTINGS */ |
231 | 243 | ||
232 | /* Pointer to allocated ramcache_header */ | 244 | /* In-RAM ramcache structure (not persisted) */ |
233 | static struct ramcache_header *ramcache_hdr; | 245 | static struct tcramcache |
234 | /* lock entity to temporarily prevent ramcache_hdr from moving */ | 246 | { |
235 | static int move_lock; | 247 | struct ramcache_header *hdr; /* allocated ramcache_header */ |
236 | #endif | 248 | int handle; /* buffer handle */ |
249 | int move_lock; | ||
250 | } tcramcache; | ||
251 | |||
252 | static inline void tcrc_buffer_lock(void) | ||
253 | { | ||
254 | tcramcache.move_lock++; | ||
255 | } | ||
256 | |||
257 | static inline void tcrc_buffer_unlock(void) | ||
258 | { | ||
259 | tcramcache.move_lock--; | ||
260 | } | ||
261 | |||
262 | #else /* ndef HAVE_TC_RAMCACHE */ | ||
263 | |||
264 | #define IF_TCRCDC(...) | ||
265 | |||
266 | #endif /* HAVE_TC_RAMCACHE */ | ||
237 | 267 | ||
238 | /** | 268 | /** |
239 | * Full tag entries stored in a temporary file waiting | 269 | * Full tag entries stored in a temporary file waiting |
@@ -275,6 +305,41 @@ static volatile int read_lock; | |||
275 | 305 | ||
276 | static bool delete_entry(long idx_id); | 306 | static bool delete_entry(long idx_id); |
277 | 307 | ||
308 | static void allocate_tempbuf(void) | ||
309 | { | ||
310 | /* Yeah, malloc would be really nice now :) */ | ||
311 | size_t size; | ||
312 | tempbuf_size = 0; | ||
313 | |||
314 | #ifdef __PCTOOL__ | ||
315 | size = 32*1024*1024; | ||
316 | tempbuf = malloc(size); | ||
317 | if (tempbuf) | ||
318 | tempbuf_size = size; | ||
319 | #else /* !__PCTOOL__ */ | ||
320 | tempbuf_handle = core_alloc_maximum("tc tempbuf", &size, NULL); | ||
321 | if (tempbuf_handle > 0) | ||
322 | { | ||
323 | tempbuf = core_get_data(tempbuf_handle); | ||
324 | tempbuf_size = size; | ||
325 | } | ||
326 | #endif /* __PCTOOL__ */ | ||
327 | } | ||
328 | |||
329 | static void free_tempbuf(void) | ||
330 | { | ||
331 | if (tempbuf_size == 0) | ||
332 | return ; | ||
333 | |||
334 | #ifdef __PCTOOL__ | ||
335 | free(tempbuf); | ||
336 | #else | ||
337 | tempbuf_handle = core_free(tempbuf_handle); | ||
338 | #endif | ||
339 | tempbuf = NULL; | ||
340 | tempbuf_size = 0; | ||
341 | } | ||
342 | |||
278 | const char* tagcache_tag_to_str(int tag) | 343 | const char* tagcache_tag_to_str(int tag) |
279 | { | 344 | { |
280 | return tags_str[tag]; | 345 | return tags_str[tag]; |
@@ -381,51 +446,64 @@ static bool do_timed_yield(void) | |||
381 | } | 446 | } |
382 | return false; | 447 | return false; |
383 | } | 448 | } |
384 | #endif | 449 | #endif /* __PCTOOL__ */ |
385 | 450 | ||
386 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | 451 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) |
387 | /* find the ramcache entry corresponding to the file indicated by | 452 | /* find the ramcache entry corresponding to the file indicated by |
388 | * filename and dc (it's corresponding dircache id). */ | 453 | * filename and dc (it's corresponding dircache id). */ |
389 | static long find_entry_ram(const char *filename, int dc) | 454 | static long find_entry_ram(const char *filename) |
390 | { | 455 | { |
391 | static long last_pos = 0; | 456 | static long last_pos = 0; |
392 | int i; | 457 | struct dircache_fileref dcfref; |
393 | 458 | ||
394 | /* Check if tagcache is loaded into ram. */ | 459 | /* Check if tagcache is loaded into ram. */ |
395 | if (!tc_stat.ramcache || !is_dircache_intact()) | 460 | if (!tc_stat.ramcache) |
396 | return -1; | 461 | return -1; |
397 | 462 | ||
398 | if (dc < 0) | 463 | if (dircache_search(DCS_CACHED_PATH | DCS_UPDATE_FILEREF, &dcfref, |
399 | dc = dircache_get_entry_id(filename); | 464 | filename) <= 0) |
400 | |||
401 | if (dc < 0) | ||
402 | { | 465 | { |
403 | logf("tagcache: file not found."); | 466 | logf("tagcache: file not found."); |
404 | return -1; | 467 | return -1; |
405 | } | 468 | } |
406 | 469 | ||
407 | try_again: | 470 | /* Search references */ |
408 | 471 | int end_pos = current_tcmh.tch.entry_count; | |
409 | if (last_pos > 0) | 472 | while (1) |
410 | i = last_pos; | ||
411 | else | ||
412 | i = 0; | ||
413 | |||
414 | for (; i < current_tcmh.tch.entry_count; i++) | ||
415 | { | 473 | { |
416 | if (ramcache_hdr->indices[i].tag_seek[tag_filename] == dc) | 474 | for (int i = last_pos; i < end_pos; i++) |
417 | { | 475 | { |
418 | last_pos = MAX(0, i - 3); | 476 | if (tcramcache.hdr->indices[i].flag & FLAG_DIRCACHE) |
419 | return i; | 477 | { |
478 | int cmp = dircache_fileref_cmp(&tcrc_dcfrefs[i], &dcfref); | ||
479 | if (cmp > 0) | ||
480 | { | ||
481 | if (cmp < 3) | ||
482 | { | ||
483 | if (dircache_search(DCS_CACHED_PATH | DCS_UPDATE_FILEREF, | ||
484 | &dcfref, filename) <= 0) | ||
485 | return -1; | ||
486 | |||
487 | if (dircache_fileref_cmp(&tcrc_dcfrefs[i], &dcfref) < 3) | ||
488 | return -1; | ||
489 | } | ||
490 | |||
491 | last_pos = MAX(0, i - 3); | ||
492 | return i; | ||
493 | } | ||
494 | } | ||
495 | |||
496 | do_timed_yield(); | ||
420 | } | 497 | } |
421 | |||
422 | do_timed_yield(); | ||
423 | } | ||
424 | 498 | ||
425 | if (last_pos > 0) | 499 | if (last_pos == 0) |
426 | { | 500 | { |
501 | last_pos = MAX(0, end_pos - 3); | ||
502 | break; | ||
503 | } | ||
504 | |||
505 | end_pos = last_pos; | ||
427 | last_pos = 0; | 506 | last_pos = 0; |
428 | goto try_again; | ||
429 | } | 507 | } |
430 | 508 | ||
431 | return -1; | 509 | return -1; |
@@ -450,7 +528,7 @@ static long find_entry_disk(const char *filename_raw, bool localfd) | |||
450 | char pathbuf[PATH_MAX]; /* Note: Don't use MAX_PATH here, it's too small */ | 528 | char pathbuf[PATH_MAX]; /* Note: Don't use MAX_PATH here, it's too small */ |
451 | if (realpath(filename, pathbuf) == pathbuf) | 529 | if (realpath(filename, pathbuf) == pathbuf) |
452 | filename = pathbuf; | 530 | filename = pathbuf; |
453 | #endif | 531 | #endif /* APPLICATION */ |
454 | 532 | ||
455 | if (!tc_stat.ready) | 533 | if (!tc_stat.ready) |
456 | return -2; | 534 | return -2; |
@@ -540,7 +618,7 @@ static int find_index(const char *filename) | |||
540 | long idx_id = -1; | 618 | long idx_id = -1; |
541 | 619 | ||
542 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | 620 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) |
543 | idx_id = find_entry_ram(filename, -1); | 621 | idx_id = find_entry_ram(filename); |
544 | #endif | 622 | #endif |
545 | 623 | ||
546 | if (idx_id < 0) | 624 | if (idx_id < 0) |
@@ -583,19 +661,13 @@ static bool get_index(int masterfd, int idxid, | |||
583 | #ifdef HAVE_TC_RAMCACHE | 661 | #ifdef HAVE_TC_RAMCACHE |
584 | if (tc_stat.ramcache && use_ram) | 662 | if (tc_stat.ramcache && use_ram) |
585 | { | 663 | { |
586 | if (ramcache_hdr->indices[idxid].flag & FLAG_DELETED) | 664 | if (tcramcache.hdr->indices[idxid].flag & FLAG_DELETED) |
587 | return false; | 665 | return false; |
588 | 666 | ||
589 | #ifdef HAVE_DIRCACHE | 667 | *idx = tcramcache.hdr->indices[idxid]; |
590 | if (!(ramcache_hdr->indices[idxid].flag & FLAG_DIRCACHE) | 668 | return true; |
591 | || is_dircache_intact()) | ||
592 | #endif | ||
593 | { | ||
594 | memcpy(idx, &ramcache_hdr->indices[idxid], sizeof(struct index_entry)); | ||
595 | return true; | ||
596 | } | ||
597 | } | 669 | } |
598 | #endif | 670 | #endif /* HAVE_TC_RAMCACHE */ |
599 | 671 | ||
600 | if (masterfd < 0) | 672 | if (masterfd < 0) |
601 | { | 673 | { |
@@ -647,10 +719,9 @@ static bool write_index(int masterfd, int idxid, struct index_entry *idx) | |||
647 | */ | 719 | */ |
648 | if (tc_stat.ramcache) | 720 | if (tc_stat.ramcache) |
649 | { | 721 | { |
650 | int tag; | 722 | struct index_entry *idx_ram = &tcramcache.hdr->indices[idxid]; |
651 | struct index_entry *idx_ram = &ramcache_hdr->indices[idxid]; | ||
652 | 723 | ||
653 | for (tag = 0; tag < TAG_COUNT; tag++) | 724 | for (int tag = 0; tag < TAG_COUNT; tag++) |
654 | { | 725 | { |
655 | if (TAGCACHE_IS_NUMERIC(tag)) | 726 | if (TAGCACHE_IS_NUMERIC(tag)) |
656 | { | 727 | { |
@@ -662,7 +733,7 @@ static bool write_index(int masterfd, int idxid, struct index_entry *idx) | |||
662 | idx_ram->flag = (idx->flag & 0x0000ffff) | 733 | idx_ram->flag = (idx->flag & 0x0000ffff) |
663 | | (idx_ram->flag & (0xffff0000 | FLAG_DIRCACHE)); | 734 | | (idx_ram->flag & (0xffff0000 | FLAG_DIRCACHE)); |
664 | } | 735 | } |
665 | #endif | 736 | #endif /* HAVE_TC_RAMCACHE */ |
666 | 737 | ||
667 | lseek(masterfd, idxid * sizeof(struct index_entry) | 738 | lseek(masterfd, idxid * sizeof(struct index_entry) |
668 | + sizeof(struct master_header), SEEK_SET); | 739 | + sizeof(struct master_header), SEEK_SET); |
@@ -697,8 +768,8 @@ static bool open_files(struct tagcache_search *tcs, int tag) | |||
697 | return true; | 768 | return true; |
698 | } | 769 | } |
699 | 770 | ||
700 | static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx, | 771 | static bool retrieve(struct tagcache_search *tcs, int idx_id, |
701 | int tag, char *buf, long size) | 772 | struct index_entry *idx, int tag, char *buf, long size) |
702 | { | 773 | { |
703 | struct tagfile_entry tfe; | 774 | struct tagfile_entry tfe; |
704 | long seek; | 775 | long seek; |
@@ -718,39 +789,24 @@ static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx, | |||
718 | #ifdef HAVE_TC_RAMCACHE | 789 | #ifdef HAVE_TC_RAMCACHE |
719 | if (tcs->ramsearch) | 790 | if (tcs->ramsearch) |
720 | { | 791 | { |
721 | struct tagfile_entry *ep; | ||
722 | |||
723 | #ifdef HAVE_DIRCACHE | 792 | #ifdef HAVE_DIRCACHE |
724 | if (tag == tag_filename && (idx->flag & FLAG_DIRCACHE)) | 793 | if (tag == tag_filename && (idx->flag & FLAG_DIRCACHE)) |
725 | { | 794 | { |
726 | /* for tag_filename, seek is a dircache index */ | 795 | if (dircache_get_fileref_path(&tcrc_dcfrefs[idx_id], buf, size) >= 0) |
727 | if (is_dircache_intact()) | ||
728 | { | ||
729 | dircache_copy_path(seek, buf, size); | ||
730 | return true; | 796 | return true; |
731 | } | ||
732 | else | ||
733 | { | ||
734 | /* The seek is useless now, there's nothing we can return. */ | ||
735 | logf("retrieve: dircache gone, cannot read file name"); | ||
736 | tagcache_unload_ramcache(); | ||
737 | // XXX do this when there's a way to not trigger an | ||
738 | // update before reloading: | ||
739 | // tagcache_start_scan(); | ||
740 | return false; | ||
741 | } | ||
742 | } | 797 | } |
743 | else | 798 | else |
744 | #endif /* HAVE_DIRCACHE */ | 799 | #endif /* HAVE_DIRCACHE */ |
745 | if (tag != tag_filename) | 800 | if (tag != tag_filename) |
746 | { | 801 | { |
747 | ep = (struct tagfile_entry *)&ramcache_hdr->tags[tag][seek]; | 802 | struct tagfile_entry *ep = |
803 | (struct tagfile_entry *)&tcramcache.hdr->tags[tag][seek]; | ||
748 | strlcpy(buf, ep->tag_data, size); | 804 | strlcpy(buf, ep->tag_data, size); |
749 | 805 | ||
750 | return true; | 806 | return true; |
751 | } | 807 | } |
752 | } | 808 | } |
753 | #endif | 809 | #endif /* HAVE_TC_RAMCACHE */ |
754 | 810 | ||
755 | if (!open_files(tcs, tag)) | 811 | if (!open_files(tcs, tag)) |
756 | return false; | 812 | return false; |
@@ -777,7 +833,7 @@ static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx, | |||
777 | } | 833 | } |
778 | 834 | ||
779 | buf[tfe.tag_length] = '\0'; | 835 | buf[tfe.tag_length] = '\0'; |
780 | 836 | ||
781 | return true; | 837 | return true; |
782 | } | 838 | } |
783 | 839 | ||
@@ -1031,12 +1087,13 @@ static bool check_clauses(struct tagcache_search *tcs, | |||
1031 | if (clause->tag == tag_filename | 1087 | if (clause->tag == tag_filename |
1032 | || clause->tag == tag_virt_basename) | 1088 | || clause->tag == tag_virt_basename) |
1033 | { | 1089 | { |
1034 | retrieve(tcs, idx, tag_filename, buf, sizeof buf); | 1090 | retrieve(tcs, tcs->idx_id, idx, tag_filename, buf, |
1091 | sizeof buf); | ||
1035 | } | 1092 | } |
1036 | else | 1093 | else |
1037 | { | 1094 | { |
1038 | tfe = (struct tagfile_entry *) | 1095 | tfe = (struct tagfile_entry *) |
1039 | &ramcache_hdr->tags[clause->tag][seek]; | 1096 | &tcramcache.hdr->tags[clause->tag][seek]; |
1040 | /* str points to movable data, but no locking required here, | 1097 | /* str points to movable data, but no locking required here, |
1041 | * as no yield() is following */ | 1098 | * as no yield() is following */ |
1042 | str = tfe->tag_data; | 1099 | str = tfe->tag_data; |
@@ -1044,7 +1101,7 @@ static bool check_clauses(struct tagcache_search *tcs, | |||
1044 | } | 1101 | } |
1045 | } | 1102 | } |
1046 | else | 1103 | else |
1047 | #endif | 1104 | #endif /* HAVE_TC_RAMCACHE */ |
1048 | { | 1105 | { |
1049 | struct tagfile_entry tfe; | 1106 | struct tagfile_entry tfe; |
1050 | 1107 | ||
@@ -1147,18 +1204,15 @@ static bool build_lookup_list(struct tagcache_search *tcs) | |||
1147 | tcs->seek_list_count = 0; | 1204 | tcs->seek_list_count = 0; |
1148 | 1205 | ||
1149 | #ifdef HAVE_TC_RAMCACHE | 1206 | #ifdef HAVE_TC_RAMCACHE |
1150 | if (tcs->ramsearch | 1207 | if (tcs->ramsearch) |
1151 | # ifdef HAVE_DIRCACHE | ||
1152 | && (tcs->type != tag_filename || is_dircache_intact()) | ||
1153 | # endif | ||
1154 | ) | ||
1155 | { | 1208 | { |
1156 | move_lock++; /* lock because below makes a pointer to movable data */ | 1209 | tcrc_buffer_lock(); /* lock because below makes a pointer to movable data */ |
1210 | |||
1157 | for (i = tcs->seek_pos; i < current_tcmh.tch.entry_count; i++) | 1211 | for (i = tcs->seek_pos; i < current_tcmh.tch.entry_count; i++) |
1158 | { | 1212 | { |
1159 | struct tagcache_seeklist_entry *seeklist; | 1213 | struct tagcache_seeklist_entry *seeklist; |
1160 | /* idx points to movable data, don't yield or reload */ | 1214 | /* idx points to movable data, don't yield or reload */ |
1161 | struct index_entry *idx = &ramcache_hdr->indices[i]; | 1215 | struct index_entry *idx = &tcramcache.hdr->indices[i]; |
1162 | if (tcs->seek_list_count == SEEK_LIST_SIZE) | 1216 | if (tcs->seek_list_count == SEEK_LIST_SIZE) |
1163 | break ; | 1217 | break ; |
1164 | 1218 | ||
@@ -1192,13 +1246,14 @@ static bool build_lookup_list(struct tagcache_search *tcs) | |||
1192 | seeklist->idx_id = i; | 1246 | seeklist->idx_id = i; |
1193 | tcs->seek_list_count++; | 1247 | tcs->seek_list_count++; |
1194 | } | 1248 | } |
1195 | move_lock--; | 1249 | |
1196 | 1250 | tcrc_buffer_unlock(); | |
1251 | |||
1197 | tcs->seek_pos = i; | 1252 | tcs->seek_pos = i; |
1198 | 1253 | ||
1199 | return tcs->seek_list_count > 0; | 1254 | return tcs->seek_list_count > 0; |
1200 | } | 1255 | } |
1201 | #endif | 1256 | #endif /* HAVE_TC_RAMCACHE */ |
1202 | 1257 | ||
1203 | if (tcs->masterfd < 0) | 1258 | if (tcs->masterfd < 0) |
1204 | { | 1259 | { |
@@ -1339,7 +1394,7 @@ bool tagcache_search(struct tagcache_search *tcs, int tag) | |||
1339 | tcs->ramsearch = tc_stat.ramcache; | 1394 | tcs->ramsearch = tc_stat.ramcache; |
1340 | if (tcs->ramsearch) | 1395 | if (tcs->ramsearch) |
1341 | { | 1396 | { |
1342 | tcs->entry_count = ramcache_hdr->entry_count[tcs->type]; | 1397 | tcs->entry_count = tcramcache.hdr->entry_count[tcs->type]; |
1343 | } | 1398 | } |
1344 | else | 1399 | else |
1345 | #endif | 1400 | #endif |
@@ -1510,34 +1565,24 @@ static bool get_next(struct tagcache_search *tcs) | |||
1510 | #ifdef HAVE_DIRCACHE | 1565 | #ifdef HAVE_DIRCACHE |
1511 | if (tcs->type == tag_filename && (flag & FLAG_DIRCACHE)) | 1566 | if (tcs->type == tag_filename && (flag & FLAG_DIRCACHE)) |
1512 | { | 1567 | { |
1513 | if (is_dircache_intact()) | 1568 | ssize_t len = dircache_get_fileref_path(&tcrc_dcfrefs[tcs->idx_id], |
1569 | buf, sizeof (buf)); | ||
1570 | if (len >= 0) | ||
1514 | { | 1571 | { |
1515 | size_t len = dircache_copy_path(tcs->position, buf, sizeof buf); | ||
1516 | tcs->result_len = len + 1; | 1572 | tcs->result_len = len + 1; |
1517 | tcs->result = buf; | 1573 | tcs->result = buf; |
1518 | tcs->ramresult = false; | 1574 | tcs->ramresult = false; |
1519 | |||
1520 | return true; | 1575 | return true; |
1521 | } | 1576 | } |
1522 | else | 1577 | /* else do it the hard way */ |
1523 | { | ||
1524 | /* The seek is useless now, there's nothing we can return. */ | ||
1525 | logf("get_next: dircache gone, cannot read file name"); | ||
1526 | tagcache_unload_ramcache(); | ||
1527 | // XXX do this when there's a way to not trigger an | ||
1528 | // update before reloading: | ||
1529 | // tagcache_start_scan(); | ||
1530 | tcs->valid = false; | ||
1531 | return false; | ||
1532 | } | ||
1533 | } | 1578 | } |
1534 | else | ||
1535 | #endif /* HAVE_DIRCACHE */ | 1579 | #endif /* HAVE_DIRCACHE */ |
1580 | |||
1536 | if (tcs->type != tag_filename) | 1581 | if (tcs->type != tag_filename) |
1537 | { | 1582 | { |
1538 | struct tagfile_entry *ep; | 1583 | struct tagfile_entry *ep; |
1539 | 1584 | ||
1540 | ep = (struct tagfile_entry *)&ramcache_hdr->tags[tcs->type][tcs->position]; | 1585 | ep = (struct tagfile_entry *)&tcramcache.hdr->tags[tcs->type][tcs->position]; |
1541 | /* don't return ep->tag_data directly as it may move */ | 1586 | /* don't return ep->tag_data directly as it may move */ |
1542 | tcs->result_len = strlcpy(buf, ep->tag_data, sizeof(buf)) + 1; | 1587 | tcs->result_len = strlcpy(buf, ep->tag_data, sizeof(buf)) + 1; |
1543 | tcs->result = buf; | 1588 | tcs->result = buf; |
@@ -1550,7 +1595,7 @@ static bool get_next(struct tagcache_search *tcs) | |||
1550 | return true; | 1595 | return true; |
1551 | } | 1596 | } |
1552 | } | 1597 | } |
1553 | #endif | 1598 | #endif /* HAVE_TC_RAMCACHE */ |
1554 | 1599 | ||
1555 | if (!open_files(tcs, tcs->type)) | 1600 | if (!open_files(tcs, tcs->type)) |
1556 | { | 1601 | { |
@@ -1616,7 +1661,7 @@ bool tagcache_retrieve(struct tagcache_search *tcs, int idxid, | |||
1616 | if (!get_index(tcs->masterfd, idxid, &idx, true)) | 1661 | if (!get_index(tcs->masterfd, idxid, &idx, true)) |
1617 | return false; | 1662 | return false; |
1618 | 1663 | ||
1619 | return retrieve(tcs, &idx, tag, buf, size); | 1664 | return retrieve(tcs, idxid, &idx, tag, buf, size); |
1620 | } | 1665 | } |
1621 | 1666 | ||
1622 | static bool update_master_header(void) | 1667 | static bool update_master_header(void) |
@@ -1674,7 +1719,7 @@ void tagcache_search_finish(struct tagcache_search *tcs) | |||
1674 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | 1719 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) |
1675 | static struct tagfile_entry *get_tag(const struct index_entry *entry, int tag) | 1720 | static struct tagfile_entry *get_tag(const struct index_entry *entry, int tag) |
1676 | { | 1721 | { |
1677 | return (struct tagfile_entry *)&ramcache_hdr->tags[tag][entry->tag_seek[tag]]; | 1722 | return (struct tagfile_entry *)&tcramcache.hdr->tags[tag][entry->tag_seek[tag]]; |
1678 | } | 1723 | } |
1679 | 1724 | ||
1680 | static long get_tag_numeric(const struct index_entry *entry, int tag, int idx_id) | 1725 | static long get_tag_numeric(const struct index_entry *entry, int tag, int idx_id) |
@@ -1697,11 +1742,11 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename) | |||
1697 | return false; | 1742 | return false; |
1698 | 1743 | ||
1699 | /* Find the corresponding entry in tagcache. */ | 1744 | /* Find the corresponding entry in tagcache. */ |
1700 | idx_id = find_entry_ram(filename, -1); | 1745 | idx_id = find_entry_ram(filename); |
1701 | if (idx_id < 0) | 1746 | if (idx_id < 0) |
1702 | return false; | 1747 | return false; |
1703 | 1748 | ||
1704 | entry = &ramcache_hdr->indices[idx_id]; | 1749 | entry = &tcramcache.hdr->indices[idx_id]; |
1705 | 1750 | ||
1706 | memset(id3, 0, sizeof(struct mp3entry)); | 1751 | memset(id3, 0, sizeof(struct mp3entry)); |
1707 | char* buf = id3->id3v2buf; | 1752 | char* buf = id3->id3v2buf; |
@@ -1761,14 +1806,7 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename) | |||
1761 | 1806 | ||
1762 | return true; | 1807 | return true; |
1763 | } | 1808 | } |
1764 | #elif defined (HAVE_TC_RAMCACHE) | 1809 | #endif /* defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) */ |
1765 | /* temporary dummy function until integration is sorted out --jethead71 */ | ||
1766 | bool tagcache_fill_tags(struct mp3entry *id3, const char *filename) | ||
1767 | { | ||
1768 | return false; | ||
1769 | (void)id3; (void)filename; | ||
1770 | } | ||
1771 | #endif | ||
1772 | 1810 | ||
1773 | static inline void write_item(const char *item) | 1811 | static inline void write_item(const char *item) |
1774 | { | 1812 | { |
@@ -1799,22 +1837,18 @@ static int check_if_empty(char **tag) | |||
1799 | return length + 1; | 1837 | return length + 1; |
1800 | } | 1838 | } |
1801 | 1839 | ||
1802 | #define ADD_TAG(entry,tag,data) \ | ||
1803 | /* Adding tag */ \ | ||
1804 | entry.tag_offset[tag] = offset; \ | ||
1805 | entry.tag_length[tag] = check_if_empty(data); \ | ||
1806 | offset += entry.tag_length[tag] | ||
1807 | /* GCC 3.4.6 for Coldfire can choose to inline this function. Not a good | 1840 | /* GCC 3.4.6 for Coldfire can choose to inline this function. Not a good |
1808 | * idea, as it uses lots of stack and is called from a recursive function | 1841 | * idea, as it uses lots of stack and is called from a recursive function |
1809 | * (check_dir). | 1842 | * (check_dir). |
1810 | */ | 1843 | */ |
1811 | static void __attribute__ ((noinline)) add_tagcache(char *path, | 1844 | static void NO_INLINE add_tagcache(char *path, unsigned long mtime) |
1812 | unsigned long mtime | ||
1813 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | ||
1814 | ,int dc | ||
1815 | #endif | ||
1816 | ) | ||
1817 | { | 1845 | { |
1846 | #define ADD_TAG(entry, tag, data) \ | ||
1847 | /* Adding tag */ \ | ||
1848 | entry.tag_offset[tag] = offset; \ | ||
1849 | entry.tag_length[tag] = check_if_empty(data); \ | ||
1850 | offset += entry.tag_length[tag] | ||
1851 | |||
1818 | struct mp3entry id3; | 1852 | struct mp3entry id3; |
1819 | struct temp_file_entry entry; | 1853 | struct temp_file_entry entry; |
1820 | bool ret; | 1854 | bool ret; |
@@ -1830,12 +1864,13 @@ static void __attribute__ ((noinline)) add_tagcache(char *path, | |||
1830 | /* Crude logging for the sim - to aid in debugging */ | 1864 | /* Crude logging for the sim - to aid in debugging */ |
1831 | int logfd = open(ROCKBOX_DIR "/database.log", | 1865 | int logfd = open(ROCKBOX_DIR "/database.log", |
1832 | O_WRONLY | O_APPEND | O_CREAT, 0666); | 1866 | O_WRONLY | O_APPEND | O_CREAT, 0666); |
1833 | if (logfd >= 0) { | 1867 | if (logfd >= 0) |
1868 | { | ||
1834 | write(logfd, path, strlen(path)); | 1869 | write(logfd, path, strlen(path)); |
1835 | write(logfd, "\n", 1); | 1870 | write(logfd, "\n", 1); |
1836 | close(logfd); | 1871 | close(logfd); |
1837 | } | 1872 | } |
1838 | #endif | 1873 | #endif /* SIMULATOR */ |
1839 | 1874 | ||
1840 | if (cachefd < 0) | 1875 | if (cachefd < 0) |
1841 | return ; | 1876 | return ; |
@@ -1854,7 +1889,7 @@ static void __attribute__ ((noinline)) add_tagcache(char *path, | |||
1854 | 1889 | ||
1855 | /* Check if the file is already cached. */ | 1890 | /* Check if the file is already cached. */ |
1856 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | 1891 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) |
1857 | idx_id = find_entry_ram(path, dc); | 1892 | idx_id = find_entry_ram(path); |
1858 | #endif | 1893 | #endif |
1859 | 1894 | ||
1860 | /* Be sure the entry doesn't exist. */ | 1895 | /* Be sure the entry doesn't exist. */ |
@@ -1979,7 +2014,10 @@ static void __attribute__ ((noinline)) add_tagcache(char *path, | |||
1979 | { | 2014 | { |
1980 | write_item(id3.title); | 2015 | write_item(id3.title); |
1981 | } | 2016 | } |
1982 | total_entry_count++; | 2017 | |
2018 | total_entry_count++; | ||
2019 | |||
2020 | #undef ADD_TAG | ||
1983 | } | 2021 | } |
1984 | 2022 | ||
1985 | static bool tempbuf_insert(char *str, int id, int idx_id, bool unique) | 2023 | static bool tempbuf_insert(char *str, int id, int idx_id, bool unique) |
@@ -2302,7 +2340,7 @@ static bool build_numeric_indices(struct tagcache_header *h, int tmpfd) | |||
2302 | * Skip unless the entry is marked as being deleted | 2340 | * Skip unless the entry is marked as being deleted |
2303 | * or the data has already been resurrected. | 2341 | * or the data has already been resurrected. |
2304 | */ | 2342 | */ |
2305 | if (!(idx.flag & FLAG_DELETED) || idx.flag & FLAG_RESURRECTED) | 2343 | if (!(idx.flag & FLAG_DELETED) || (idx.flag & FLAG_RESURRECTED)) |
2306 | continue; | 2344 | continue; |
2307 | 2345 | ||
2308 | /* Now try to match the entry. */ | 2346 | /* Now try to match the entry. */ |
@@ -2938,8 +2976,6 @@ static bool commit(void) | |||
2938 | #ifdef HAVE_TC_RAMCACHE | 2976 | #ifdef HAVE_TC_RAMCACHE |
2939 | bool ramcache_buffer_stolen = false; | 2977 | bool ramcache_buffer_stolen = false; |
2940 | #endif | 2978 | #endif |
2941 | bool local_allocation = false; | ||
2942 | |||
2943 | logf("committing tagcache"); | 2979 | logf("committing tagcache"); |
2944 | 2980 | ||
2945 | while (write_lock) | 2981 | while (write_lock) |
@@ -2990,9 +3026,6 @@ static bool commit(void) | |||
2990 | read_lock++; | 3026 | read_lock++; |
2991 | 3027 | ||
2992 | /* Try to steal every buffer we can :) */ | 3028 | /* Try to steal every buffer we can :) */ |
2993 | if (tempbuf_size == 0) | ||
2994 | local_allocation = true; | ||
2995 | |||
2996 | #ifdef HAVE_DIRCACHE | 3029 | #ifdef HAVE_DIRCACHE |
2997 | if (tempbuf_size == 0) | 3030 | if (tempbuf_size == 0) |
2998 | { | 3031 | { |
@@ -3007,13 +3040,13 @@ static bool commit(void) | |||
3007 | #ifdef HAVE_TC_RAMCACHE | 3040 | #ifdef HAVE_TC_RAMCACHE |
3008 | if (tempbuf_size == 0 && tc_stat.ramcache_allocated > 0) | 3041 | if (tempbuf_size == 0 && tc_stat.ramcache_allocated > 0) |
3009 | { | 3042 | { |
3010 | tempbuf = (char *)(ramcache_hdr + 1); | 3043 | tcrc_buffer_lock(); |
3044 | tempbuf = (char *)(tcramcache.hdr + 1); | ||
3011 | tempbuf_size = tc_stat.ramcache_allocated - sizeof(struct ramcache_header) - 128; | 3045 | tempbuf_size = tc_stat.ramcache_allocated - sizeof(struct ramcache_header) - 128; |
3012 | tempbuf_size &= ~0x03; | 3046 | tempbuf_size &= ~0x03; |
3013 | move_lock++; | ||
3014 | ramcache_buffer_stolen = true; | 3047 | ramcache_buffer_stolen = true; |
3015 | } | 3048 | } |
3016 | #endif | 3049 | #endif /* HAVE_TC_RAMCACHE */ |
3017 | 3050 | ||
3018 | /* And finally fail if there are no buffers available. */ | 3051 | /* And finally fail if there are no buffers available. */ |
3019 | if (tempbuf_size == 0) | 3052 | if (tempbuf_size == 0) |
@@ -3089,75 +3122,46 @@ static bool commit(void) | |||
3089 | tc_stat.ready = check_all_headers(); | 3122 | tc_stat.ready = check_all_headers(); |
3090 | tc_stat.readyvalid = true; | 3123 | tc_stat.readyvalid = true; |
3091 | 3124 | ||
3092 | if (local_allocation) | ||
3093 | { | ||
3094 | tempbuf = NULL; | ||
3095 | tempbuf_size = 0; | ||
3096 | } | ||
3097 | |||
3098 | #ifdef HAVE_TC_RAMCACHE | 3125 | #ifdef HAVE_TC_RAMCACHE |
3099 | if (ramcache_buffer_stolen) | 3126 | if (ramcache_buffer_stolen) |
3100 | { | 3127 | { |
3128 | tempbuf = NULL; | ||
3129 | tempbuf_size = 0; | ||
3101 | ramcache_buffer_stolen = false; | 3130 | ramcache_buffer_stolen = false; |
3102 | move_lock--; | 3131 | tcrc_buffer_unlock(); |
3103 | } | 3132 | } |
3104 | 3133 | ||
3105 | /* Reload tagcache. */ | 3134 | /* Reload tagcache. */ |
3106 | if (tc_stat.ramcache_allocated > 0) | 3135 | if (tc_stat.ramcache_allocated > 0) |
3107 | tagcache_start_scan(); | 3136 | tagcache_start_scan(); |
3108 | #endif | 3137 | #endif /* HAVE_TC_RAMCACHE */ |
3109 | 3138 | ||
3110 | rc = true; | 3139 | rc = true; |
3111 | 3140 | ||
3112 | commit_error: | 3141 | commit_error: |
3113 | #ifdef HAVE_TC_RAMCACHE | 3142 | #ifdef HAVE_TC_RAMCACHE |
3114 | if (ramcache_buffer_stolen) | 3143 | if (ramcache_buffer_stolen) |
3115 | move_lock--; | 3144 | { |
3116 | #endif | 3145 | tempbuf = NULL; |
3146 | tempbuf_size = 0; | ||
3147 | tcrc_buffer_unlock(); | ||
3148 | } | ||
3149 | #endif /* HAVE_TC_RAMCACHE */ | ||
3117 | 3150 | ||
3118 | read_lock--; | 3151 | read_lock--; |
3119 | 3152 | ||
3120 | #ifdef HAVE_DIRCACHE | 3153 | #ifdef HAVE_DIRCACHE |
3121 | /* Resume the dircache, if we stole the buffer. */ | 3154 | /* Resume the dircache, if we stole the buffer. */ |
3122 | if (dircache_buffer_stolen) | 3155 | if (dircache_buffer_stolen) |
3156 | { | ||
3157 | free_tempbuf(); | ||
3123 | dircache_resume(); | 3158 | dircache_resume(); |
3124 | #endif | 3159 | } |
3160 | #endif /* HAVE_DIRCACHE */ | ||
3125 | 3161 | ||
3126 | return rc; | 3162 | return rc; |
3127 | } | 3163 | } |
3128 | 3164 | ||
3129 | static void allocate_tempbuf(void) | ||
3130 | { | ||
3131 | /* Yeah, malloc would be really nice now :) */ | ||
3132 | size_t size; | ||
3133 | tempbuf_size = 0; | ||
3134 | |||
3135 | #ifdef __PCTOOL__ | ||
3136 | size = 32*1024*1024; | ||
3137 | tempbuf = malloc(size); | ||
3138 | #else | ||
3139 | tempbuf_handle = core_alloc_maximum("tc tempbuf", &size, NULL); | ||
3140 | tempbuf = core_get_data(tempbuf_handle); | ||
3141 | #endif | ||
3142 | |||
3143 | if (tempbuf) | ||
3144 | tempbuf_size = size; | ||
3145 | } | ||
3146 | |||
3147 | static void free_tempbuf(void) | ||
3148 | { | ||
3149 | if (tempbuf_size == 0) | ||
3150 | return ; | ||
3151 | |||
3152 | #ifdef __PCTOOL__ | ||
3153 | free(tempbuf); | ||
3154 | #else | ||
3155 | tempbuf_handle = core_free(tempbuf_handle); | ||
3156 | #endif | ||
3157 | tempbuf = NULL; | ||
3158 | tempbuf_size = 0; | ||
3159 | } | ||
3160 | |||
3161 | #ifndef __PCTOOL__ | 3165 | #ifndef __PCTOOL__ |
3162 | 3166 | ||
3163 | static bool modify_numeric_entry(int masterfd, int idx_id, int tag, long data) | 3167 | static bool modify_numeric_entry(int masterfd, int idx_id, int tag, long data) |
@@ -3645,7 +3649,7 @@ static bool delete_entry(long idx_id) | |||
3645 | #ifdef HAVE_TC_RAMCACHE | 3649 | #ifdef HAVE_TC_RAMCACHE |
3646 | /* At first mark the entry removed from ram cache. */ | 3650 | /* At first mark the entry removed from ram cache. */ |
3647 | if (tc_stat.ramcache) | 3651 | if (tc_stat.ramcache) |
3648 | ramcache_hdr->indices[idx_id].flag |= FLAG_DELETED; | 3652 | tcramcache.hdr->indices[idx_id].flag |= FLAG_DELETED; |
3649 | #endif | 3653 | #endif |
3650 | 3654 | ||
3651 | if ( (masterfd = open_master_fd(&myhdr, true) ) < 0) | 3655 | if ( (masterfd = open_master_fd(&myhdr, true) ) < 0) |
@@ -3684,7 +3688,7 @@ static bool delete_entry(long idx_id) | |||
3684 | #ifdef HAVE_TC_RAMCACHE | 3688 | #ifdef HAVE_TC_RAMCACHE |
3685 | /* Use RAM DB if available for greater speed */ | 3689 | /* Use RAM DB if available for greater speed */ |
3686 | if (tc_stat.ramcache) | 3690 | if (tc_stat.ramcache) |
3687 | idxp = &ramcache_hdr->indices[i]; | 3691 | idxp = &tcramcache.hdr->indices[i]; |
3688 | else | 3692 | else |
3689 | #endif | 3693 | #endif |
3690 | { | 3694 | { |
@@ -3727,16 +3731,16 @@ static bool delete_entry(long idx_id) | |||
3727 | if (tc_stat.ramcache && tag != tag_filename) | 3731 | if (tc_stat.ramcache && tag != tag_filename) |
3728 | { | 3732 | { |
3729 | struct tagfile_entry *tfe; | 3733 | struct tagfile_entry *tfe; |
3730 | int32_t *seek = &ramcache_hdr->indices[idx_id].tag_seek[tag]; | 3734 | int32_t *seek = &tcramcache.hdr->indices[idx_id].tag_seek[tag]; |
3731 | 3735 | ||
3732 | tfe = (struct tagfile_entry *)&ramcache_hdr->tags[tag][*seek]; | 3736 | tfe = (struct tagfile_entry *)&tcramcache.hdr->tags[tag][*seek]; |
3733 | move_lock++; /* protect tfe and seek if crc_32() yield()s */ | 3737 | tcrc_buffer_lock(); /* protect tfe and seek if crc_32() yield()s */ |
3734 | *seek = crc_32(tfe->tag_data, strlen(tfe->tag_data), 0xffffffff); | 3738 | *seek = crc_32(tfe->tag_data, strlen(tfe->tag_data), 0xffffffff); |
3735 | move_lock--; | 3739 | tcrc_buffer_unlock(); |
3736 | myidx.tag_seek[tag] = *seek; | 3740 | myidx.tag_seek[tag] = *seek; |
3737 | } | 3741 | } |
3738 | else | 3742 | else |
3739 | #endif | 3743 | #endif /* HAVE_TC_RAMCACHE */ |
3740 | { | 3744 | { |
3741 | struct tagfile_entry tfe; | 3745 | struct tagfile_entry tfe; |
3742 | 3746 | ||
@@ -3777,10 +3781,10 @@ static bool delete_entry(long idx_id) | |||
3777 | if (tc_stat.ramcache && tag != tag_filename) | 3781 | if (tc_stat.ramcache && tag != tag_filename) |
3778 | { | 3782 | { |
3779 | struct tagfile_entry *tagentry = | 3783 | struct tagfile_entry *tagentry = |
3780 | (struct tagfile_entry *)&ramcache_hdr->tags[tag][oldseek]; | 3784 | (struct tagfile_entry *)&tcramcache.hdr->tags[tag][oldseek]; |
3781 | tagentry->tag_data[0] = '\0'; | 3785 | tagentry->tag_data[0] = '\0'; |
3782 | } | 3786 | } |
3783 | #endif | 3787 | #endif /* HAVE_TC_RAMCACHE */ |
3784 | 3788 | ||
3785 | /* Open the index file, which contains the tag names. */ | 3789 | /* Open the index file, which contains the tag names. */ |
3786 | if (fd < 0) | 3790 | if (fd < 0) |
@@ -3829,13 +3833,13 @@ static bool delete_entry(long idx_id) | |||
3829 | return false; | 3833 | return false; |
3830 | } | 3834 | } |
3831 | 3835 | ||
3832 | #ifndef __PCTOOL__ | ||
3833 | /** | 3836 | /** |
3834 | * Returns true if there is an event waiting in the queue | 3837 | * Returns true if there is an event waiting in the queue |
3835 | * that requires the current operation to be aborted. | 3838 | * that requires the current operation to be aborted. |
3836 | */ | 3839 | */ |
3837 | static bool check_event_queue(void) | 3840 | static bool check_event_queue(void) |
3838 | { | 3841 | { |
3842 | #ifndef __PCTOOL__ | ||
3839 | struct queue_event ev; | 3843 | struct queue_event ev; |
3840 | 3844 | ||
3841 | if(!queue_peek(&tagcache_queue, &ev)) | 3845 | if(!queue_peek(&tagcache_queue, &ev)) |
@@ -3848,10 +3852,10 @@ static bool check_event_queue(void) | |||
3848 | case SYS_USB_CONNECTED: | 3852 | case SYS_USB_CONNECTED: |
3849 | return true; | 3853 | return true; |
3850 | } | 3854 | } |
3855 | #endif /* __PCTOOL__ */ | ||
3851 | 3856 | ||
3852 | return false; | 3857 | return false; |
3853 | } | 3858 | } |
3854 | #endif | ||
3855 | 3859 | ||
3856 | #ifdef HAVE_TC_RAMCACHE | 3860 | #ifdef HAVE_TC_RAMCACHE |
3857 | 3861 | ||
@@ -3859,18 +3863,18 @@ static void fix_ramcache(void* old_addr, void* new_addr) | |||
3859 | { | 3863 | { |
3860 | ptrdiff_t offpos = new_addr - old_addr; | 3864 | ptrdiff_t offpos = new_addr - old_addr; |
3861 | for (int i = 0; i < TAG_COUNT; i++) | 3865 | for (int i = 0; i < TAG_COUNT; i++) |
3862 | ramcache_hdr->tags[i] += offpos; | 3866 | tcramcache.hdr->tags[i] += offpos; |
3863 | } | 3867 | } |
3864 | 3868 | ||
3865 | static int move_cb(int handle, void* current, void* new) | 3869 | static int move_cb(int handle, void* current, void* new) |
3866 | { | 3870 | { |
3867 | (void)handle; | 3871 | if (tcramcache.move_lock > 0) |
3868 | if (move_lock > 0) | ||
3869 | return BUFLIB_CB_CANNOT_MOVE; | 3872 | return BUFLIB_CB_CANNOT_MOVE; |
3870 | 3873 | ||
3871 | fix_ramcache(current, new); | 3874 | fix_ramcache(current, new); |
3872 | ramcache_hdr = new; | 3875 | tcramcache.hdr = new; |
3873 | return BUFLIB_CB_OK; | 3876 | return BUFLIB_CB_OK; |
3877 | (void)handle; | ||
3874 | } | 3878 | } |
3875 | 3879 | ||
3876 | static struct buflib_callbacks ops = { | 3880 | static struct buflib_callbacks ops = { |
@@ -3880,13 +3884,12 @@ static struct buflib_callbacks ops = { | |||
3880 | 3884 | ||
3881 | static bool allocate_tagcache(void) | 3885 | static bool allocate_tagcache(void) |
3882 | { | 3886 | { |
3883 | struct master_header tcmh; | ||
3884 | int fd; | ||
3885 | |||
3886 | /* Load the header. */ | 3887 | /* Load the header. */ |
3887 | if ( (fd = open_master_fd(&tcmh, false)) < 0) | 3888 | struct master_header tcmh; |
3889 | int fd = open_master_fd(&tcmh, false); | ||
3890 | if (fd < 0) | ||
3888 | { | 3891 | { |
3889 | ramcache_hdr = NULL; | 3892 | tcramcache.hdr = NULL; |
3890 | return false; | 3893 | return false; |
3891 | } | 3894 | } |
3892 | 3895 | ||
@@ -3896,22 +3899,37 @@ static bool allocate_tagcache(void) | |||
3896 | * Now calculate the required cache size plus | 3899 | * Now calculate the required cache size plus |
3897 | * some extra space for alignment fixes. | 3900 | * some extra space for alignment fixes. |
3898 | */ | 3901 | */ |
3899 | tc_stat.ramcache_allocated = tcmh.tch.datasize + 256 + TAGCACHE_RESERVE + | 3902 | tc_stat.ramcache_allocated = 0; |
3903 | |||
3904 | size_t alloc_size = tcmh.tch.datasize + 256 + TAGCACHE_RESERVE + | ||
3900 | sizeof(struct ramcache_header) + TAG_COUNT*sizeof(void *); | 3905 | sizeof(struct ramcache_header) + TAG_COUNT*sizeof(void *); |
3901 | int handle = core_alloc_ex("tc ramcache", tc_stat.ramcache_allocated, &ops); | 3906 | #ifdef HAVE_DIRCACHE |
3902 | ramcache_hdr = core_get_data(handle); | 3907 | alloc_size += tcmh.tch.entry_count*sizeof(struct dircache_fileref); |
3903 | memset(ramcache_hdr, 0, sizeof(struct ramcache_header)); | 3908 | #endif |
3909 | |||
3910 | int handle = core_alloc_ex("tc ramcache", alloc_size, &ops); | ||
3911 | if (handle <= 0) | ||
3912 | return false; | ||
3913 | |||
3914 | void *data = core_get_data(handle); | ||
3915 | |||
3916 | tcramcache.hdr = data; | ||
3917 | tc_stat.ramcache_allocated = alloc_size; | ||
3918 | |||
3919 | memset(tcramcache.hdr, 0, sizeof(struct ramcache_header)); | ||
3904 | memcpy(¤t_tcmh, &tcmh, sizeof current_tcmh); | 3920 | memcpy(¤t_tcmh, &tcmh, sizeof current_tcmh); |
3905 | logf("tagcache: %d bytes allocated.", tc_stat.ramcache_allocated); | 3921 | logf("tagcache: %lu bytes allocated.", tc_stat.ramcache_allocated); |
3906 | 3922 | ||
3907 | return true; | 3923 | return true; |
3908 | } | 3924 | } |
3909 | 3925 | ||
3910 | # ifdef HAVE_EEPROM_SETTINGS | 3926 | #ifdef HAVE_EEPROM_SETTINGS |
3911 | static bool tagcache_dumpload(void) | 3927 | static bool tagcache_dumpload(void) |
3912 | { | 3928 | { |
3913 | struct statefile_header shdr; | 3929 | struct statefile_header shdr; |
3914 | int fd, rc, handle; | 3930 | int fd, rc, handle; |
3931 | |||
3932 | tcramcache.hdr = NULL; | ||
3915 | 3933 | ||
3916 | fd = open(TAGCACHE_STATEFILE, O_RDONLY); | 3934 | fd = open(TAGCACHE_STATEFILE, O_RDONLY); |
3917 | if (fd < 0) | 3935 | if (fd < 0) |
@@ -3927,31 +3945,36 @@ static bool tagcache_dumpload(void) | |||
3927 | || shdr.mh.tch.magic != TAGCACHE_MAGIC) | 3945 | || shdr.mh.tch.magic != TAGCACHE_MAGIC) |
3928 | { | 3946 | { |
3929 | logf("incorrect statefile"); | 3947 | logf("incorrect statefile"); |
3930 | ramcache_hdr = NULL; | ||
3931 | close(fd); | 3948 | close(fd); |
3932 | return false; | 3949 | return false; |
3933 | } | 3950 | } |
3934 | 3951 | ||
3935 | |||
3936 | /* Lets allocate real memory and load it */ | 3952 | /* Lets allocate real memory and load it */ |
3937 | handle = core_alloc_ex("tc ramcache", shdr.tc_stat.ramcache_allocated, &ops); | 3953 | handle = core_alloc_ex("tc ramcache", shdr.tc_stat.ramcache_allocated, &ops); |
3938 | ramcache_hdr = core_get_data(handle); | 3954 | if (handle <= 0) |
3939 | move_lock++; | 3955 | { |
3940 | rc = read(fd, ramcache_hdr, shdr.tc_stat.ramcache_allocated); | 3956 | logf("alloc failure"); |
3941 | move_lock--; | 3957 | return false; |
3958 | } | ||
3959 | |||
3960 | tcrc_buffer_lock(); | ||
3961 | tcramcache.hdr = core_get_data(handle); | ||
3962 | rc = read(fd, tcramcache.hdr, shdr.tc_stat.ramcache_allocated); | ||
3963 | tcrc_buffer_unlock(); | ||
3964 | |||
3942 | close(fd); | 3965 | close(fd); |
3943 | 3966 | ||
3944 | if (rc != shdr.tc_stat.ramcache_allocated) | 3967 | if (rc != shdr.tc_stat.ramcache_allocated) |
3945 | { | 3968 | { |
3946 | logf("read failure!"); | 3969 | logf("read failure!"); |
3947 | ramcache_hdr = NULL; | 3970 | core_free(handle); |
3948 | return false; | 3971 | return false; |
3949 | } | 3972 | } |
3950 | 3973 | ||
3951 | memcpy(&tc_stat, &shdr.tc_stat, sizeof(struct tagcache_stat)); | 3974 | tc_stat = shdr.tc_stat; |
3952 | 3975 | ||
3953 | /* Now fix the pointers */ | 3976 | /* Now fix the pointers */ |
3954 | fix_ramcache(shdr.hdr, ramcache_hdr); | 3977 | fix_ramcache(shdr.hdr, tcramcache.hdr); |
3955 | 3978 | ||
3956 | /* Load the tagcache master header (should match the actual DB file header). */ | 3979 | /* Load the tagcache master header (should match the actual DB file header). */ |
3957 | memcpy(¤t_tcmh, &shdr.mh, sizeof current_tcmh); | 3980 | memcpy(¤t_tcmh, &shdr.mh, sizeof current_tcmh); |
@@ -3976,63 +3999,62 @@ static bool tagcache_dumpsave(void) | |||
3976 | 3999 | ||
3977 | /* Create the header */ | 4000 | /* Create the header */ |
3978 | shdr.magic = TAGCACHE_STATEFILE_MAGIC; | 4001 | shdr.magic = TAGCACHE_STATEFILE_MAGIC; |
3979 | shdr.hdr = ramcache_hdr; | 4002 | shdr.hdr = tcramcache.hdr; |
3980 | memcpy(&shdr.mh, ¤t_tcmh, sizeof current_tcmh); | 4003 | memcpy(&shdr.mh, ¤t_tcmh, sizeof current_tcmh); |
3981 | memcpy(&shdr.tc_stat, &tc_stat, sizeof tc_stat); | 4004 | memcpy(&shdr.tc_stat, &tc_stat, sizeof tc_stat); |
3982 | write(fd, &shdr, sizeof shdr); | 4005 | write(fd, &shdr, sizeof shdr); |
3983 | 4006 | ||
3984 | /* And dump the data too */ | 4007 | /* And dump the data too */ |
3985 | move_lock++; | 4008 | tcrc_buffer_lock(); |
3986 | write(fd, ramcache_hdr, tc_stat.ramcache_allocated); | 4009 | write(fd, tcramcache.hdr, tc_stat.ramcache_allocated); |
3987 | move_lock--; | 4010 | tcrc_buffer_unlock(); |
3988 | close(fd); | 4011 | close(fd); |
3989 | 4012 | ||
3990 | return true; | 4013 | return true; |
3991 | } | 4014 | } |
3992 | # endif | 4015 | #endif /* HAVE_EEPROM_SETTINGS */ |
3993 | 4016 | ||
3994 | static bool load_tagcache(void) | 4017 | static bool load_tagcache(void) |
3995 | { | 4018 | { |
3996 | struct tagcache_header *tch; | 4019 | /* DEBUG: After tagcache commit and dircache rebuild, hdr-sturcture |
3997 | struct master_header tcmh; | 4020 | * may become corrupt. */ |
3998 | long bytesleft = tc_stat.ramcache_allocated - sizeof(struct ramcache_header); | 4021 | |
3999 | struct index_entry *idx; | 4022 | bool const auto_update = global_settings.tagcache_autoupdate; |
4000 | int rc, fd; | 4023 | |
4001 | char *p; | 4024 | bool ok = false; |
4002 | int i, tag; | 4025 | ssize_t bytesleft = tc_stat.ramcache_allocated - sizeof(struct ramcache_header); |
4003 | 4026 | int fd; | |
4004 | # ifdef HAVE_DIRCACHE | 4027 | |
4005 | while (dircache_is_initializing()) | 4028 | #ifdef HAVE_DIRCACHE |
4006 | sleep(1); | 4029 | /* Wait for any in-progress dircache build to complete */ |
4030 | dircache_wait(); | ||
4031 | #endif /* HAVE_DIRCACHE */ | ||
4007 | 4032 | ||
4008 | dircache_set_appflag(DIRCACHE_APPFLAG_TAGCACHE); | ||
4009 | # endif | ||
4010 | |||
4011 | logf("loading tagcache to ram..."); | 4033 | logf("loading tagcache to ram..."); |
4012 | 4034 | ||
4013 | fd = open(TAGCACHE_FILE_MASTER, O_RDONLY); | 4035 | fd = open(TAGCACHE_FILE_MASTER, O_RDONLY); |
4014 | if (fd < 0) | 4036 | if (fd < 0) |
4015 | { | 4037 | { |
4016 | logf("tagcache open failed"); | 4038 | logf("tagcache open failed"); |
4017 | return false; | 4039 | goto failure; |
4018 | } | 4040 | } |
4019 | 4041 | ||
4042 | tcrc_buffer_lock(); /* lock for the rest of the scan, simpler to handle */ | ||
4043 | |||
4044 | struct master_header tcmh; | ||
4020 | if (ecread(fd, &tcmh, 1, master_header_ec, tc_stat.econ) | 4045 | if (ecread(fd, &tcmh, 1, master_header_ec, tc_stat.econ) |
4021 | != sizeof(struct master_header) | 4046 | != sizeof(struct master_header) |
4022 | || tcmh.tch.magic != TAGCACHE_MAGIC) | 4047 | || tcmh.tch.magic != TAGCACHE_MAGIC) |
4023 | { | 4048 | { |
4024 | logf("incorrect header"); | 4049 | logf("incorrect header"); |
4025 | return false; | 4050 | goto failure; |
4026 | } | 4051 | } |
4027 | 4052 | ||
4028 | /* Master header copy should already match, this can be redundant to do. */ | 4053 | /* Master header copy should already match, this can be redundant to do. */ |
4029 | memcpy(¤t_tcmh, &tcmh, sizeof current_tcmh); | 4054 | current_tcmh = tcmh; |
4030 | |||
4031 | move_lock++; /* lock for the reset of the scan, simpler to handle */ | ||
4032 | idx = ramcache_hdr->indices; | ||
4033 | 4055 | ||
4034 | /* Load the master index table. */ | 4056 | /* Load the master index table. */ |
4035 | for (i = 0; i < tcmh.tch.entry_count; i++) | 4057 | for (int i = 0; i < tcmh.tch.entry_count; i++) |
4036 | { | 4058 | { |
4037 | bytesleft -= sizeof(struct index_entry); | 4059 | bytesleft -= sizeof(struct index_entry); |
4038 | if (bytesleft < 0) | 4060 | if (bytesleft < 0) |
@@ -4041,142 +4063,157 @@ static bool load_tagcache(void) | |||
4041 | goto failure; | 4063 | goto failure; |
4042 | } | 4064 | } |
4043 | 4065 | ||
4044 | /* DEBUG: After tagcache commit and dircache rebuild, hdr-sturcture | 4066 | int rc = ecread_index_entry(fd, &tcramcache.hdr->indices[i]); |
4045 | * may become corrupt. */ | 4067 | if (rc != sizeof (struct index_entry)) |
4046 | rc = ecread_index_entry(fd, idx); | ||
4047 | if (rc != sizeof(struct index_entry)) | ||
4048 | { | 4068 | { |
4049 | logf("read error #10"); | 4069 | logf("read error #10"); |
4050 | goto failure; | 4070 | goto failure; |
4051 | } | 4071 | } |
4052 | |||
4053 | idx++; | ||
4054 | } | 4072 | } |
4055 | 4073 | ||
4056 | close(fd); | 4074 | close(fd); |
4075 | fd = -1; | ||
4057 | 4076 | ||
4058 | /* Load the tags. */ | 4077 | /* Load the tags right after the index entries */ |
4059 | p = (char *)idx; | 4078 | char *p = (char *)&tcramcache.hdr->indices[tcmh.tch.entry_count]; |
4060 | for (tag = 0; tag < TAG_COUNT; tag++) | 4079 | |
4080 | for (int tag = 0; tag < TAG_COUNT; tag++) | ||
4061 | { | 4081 | { |
4062 | struct tagfile_entry *fe; | 4082 | ssize_t rc; |
4063 | char buf[TAG_MAXLEN+32]; | ||
4064 | 4083 | ||
4065 | if (TAGCACHE_IS_NUMERIC(tag)) | 4084 | if (TAGCACHE_IS_NUMERIC(tag)) |
4066 | continue ; | 4085 | continue; |
4067 | 4086 | ||
4068 | //p = ((void *)p+1); | 4087 | p = TC_ALIGN_PTR(p, &rc); |
4069 | p = (char *)((long)p & ~0x03) + 0x04; | 4088 | bytesleft -= rc; |
4070 | ramcache_hdr->tags[tag] = p; | 4089 | if (bytesleft <= 0) |
4090 | { | ||
4091 | logf("Too big tagcache #10.5"); | ||
4092 | goto failure; | ||
4093 | } | ||
4094 | |||
4095 | tcramcache.hdr->tags[tag] = p; | ||
4071 | 4096 | ||
4072 | /* Check the header. */ | 4097 | /* Load the header */ |
4073 | tch = (struct tagcache_header *)p; | 4098 | struct tagcache_header *tch = (struct tagcache_header *)p; |
4074 | p += sizeof(struct tagcache_header); | 4099 | p += sizeof(struct tagcache_header); |
4075 | 4100 | bytesleft -= sizeof (struct tagcache_header); | |
4076 | if ( (fd = open_tag_fd(tch, tag, false)) < 0) | 4101 | |
4077 | goto failure_nofd; | 4102 | fd = open_tag_fd(tch, tag, false); |
4078 | 4103 | if (rc < 0) | |
4079 | for (ramcache_hdr->entry_count[tag] = 0; | 4104 | goto failure; |
4080 | ramcache_hdr->entry_count[tag] < tch->entry_count; | 4105 | |
4081 | ramcache_hdr->entry_count[tag]++) | 4106 | /* Load the entries for this tag */ |
4107 | for (tcramcache.hdr->entry_count[tag] = 0; | ||
4108 | tcramcache.hdr->entry_count[tag] < tch->entry_count; | ||
4109 | tcramcache.hdr->entry_count[tag]++) | ||
4082 | { | 4110 | { |
4083 | long pos; | 4111 | /* Abort if we got a critical event in queue */ |
4084 | 4112 | if (do_timed_yield() && check_event_queue()) | |
4085 | if (do_timed_yield()) | 4113 | goto failure; |
4114 | |||
4115 | p = TC_ALIGN_PTR(p, &rc); | ||
4116 | bytesleft -= rc; | ||
4117 | if (bytesleft <= 0) | ||
4086 | { | 4118 | { |
4087 | /* Abort if we got a critical event in queue */ | 4119 | logf("Too big tagcache #10.75"); |
4088 | if (check_event_queue()) | 4120 | goto failure; |
4089 | goto failure; | 4121 | } |
4122 | |||
4123 | if (bytesleft < (ssize_t)sizeof (struct tagfile_entry)) | ||
4124 | { | ||
4125 | logf("Too big tagcache #10.875"); | ||
4126 | goto failure; | ||
4090 | } | 4127 | } |
4091 | 4128 | ||
4092 | fe = (struct tagfile_entry *)p; | 4129 | struct tagfile_entry *fe = (struct tagfile_entry *)p; |
4093 | pos = lseek(fd, 0, SEEK_CUR); | 4130 | off_t pos = lseek(fd, 0, SEEK_CUR); |
4094 | rc = ecread_tagfile_entry(fd, fe); | 4131 | |
4095 | if (rc != sizeof(struct tagfile_entry)) | 4132 | /* Load the header for the tag itself */ |
4133 | if (ecread_tagfile_entry(fd, fe) != sizeof(struct tagfile_entry)) | ||
4096 | { | 4134 | { |
4097 | /* End of lookup table. */ | 4135 | /* End of lookup table. */ |
4098 | logf("read error #11"); | 4136 | logf("read error #11"); |
4099 | goto failure; | 4137 | goto failure; |
4100 | } | 4138 | } |
4101 | 4139 | ||
4102 | /* We have a special handling for the filename tags. */ | 4140 | /* We have a special handling for the filename tags; neither the |
4141 | paths nor the entry headers are stored; only the tagcache header | ||
4142 | and dircache references are. */ | ||
4103 | if (tag == tag_filename) | 4143 | if (tag == tag_filename) |
4104 | { | 4144 | { |
4105 | # ifdef HAVE_DIRCACHE | 4145 | int idx_id = fe->idx_id; /* gonna clobber tagfile entry */ |
4106 | int dc; | 4146 | struct index_entry *idx = &tcramcache.hdr->indices[idx_id]; |
4107 | # endif | 4147 | |
4108 | 4148 | #ifdef HAVE_DIRCACHE | |
4109 | idx = &ramcache_hdr->indices[fe->idx_id]; | ||
4110 | |||
4111 | if (fe->tag_length >= (long)sizeof(buf)-1) | ||
4112 | { | ||
4113 | read(fd, buf, 10); | ||
4114 | buf[10] = '\0'; | ||
4115 | logf("TAG:%s", buf); | ||
4116 | logf("too long filename"); | ||
4117 | goto failure; | ||
4118 | } | ||
4119 | |||
4120 | rc = read(fd, buf, fe->tag_length); | ||
4121 | if (rc != fe->tag_length) | ||
4122 | { | ||
4123 | logf("read error #12"); | ||
4124 | goto failure; | ||
4125 | } | ||
4126 | |||
4127 | /* Check if the entry has already been removed */ | ||
4128 | if (idx->flag & FLAG_DELETED) | ||
4129 | continue; | ||
4130 | |||
4131 | /* This flag must not be used yet. */ | ||
4132 | if (idx->flag & FLAG_DIRCACHE) | 4149 | if (idx->flag & FLAG_DIRCACHE) |
4133 | { | 4150 | { |
4151 | /* This flag must not be used yet. */ | ||
4134 | logf("internal error!"); | 4152 | logf("internal error!"); |
4135 | goto failure; | 4153 | goto failure; |
4136 | } | 4154 | } |
4137 | 4155 | ||
4156 | p += sizeof (struct dircache_fileref); | ||
4157 | bytesleft -= sizeof (struct dircache_fileref); | ||
4158 | #endif /* HAVE_DIRCACHE */ | ||
4159 | |||
4138 | if (idx->tag_seek[tag] != pos) | 4160 | if (idx->tag_seek[tag] != pos) |
4139 | { | 4161 | { |
4140 | logf("corrupt data structures!"); | 4162 | logf("corrupt data structures!"); |
4141 | goto failure; | 4163 | goto failure; |
4142 | } | 4164 | } |
4143 | 4165 | ||
4144 | if (global_settings.tagcache_autoupdate) | 4166 | char filename[TAG_MAXLEN+32]; |
4167 | if (fe->tag_length >= (long)sizeof(filename)-1) | ||
4145 | { | 4168 | { |
4146 | /* Check if entry has been removed. */ | 4169 | read(fd, filename, 10); |
4147 | #ifdef HAVE_DIRCACHE | 4170 | filename[10] = '\0'; |
4148 | /* This will be very slow unless dircache is enabled | 4171 | logf("TAG:%s", filename); |
4149 | or target is flash based. */ | 4172 | logf("too long filename"); |
4150 | ################## | 4173 | goto failure; |
4151 | if (dircache_search( /* will get this! -- jethead71 */ | 4174 | } |
4152 | dc = dircache_get_entry_id(buf); | 4175 | |
4153 | if (dc < 0) | 4176 | if ((idx->flag & FLAG_DELETED) IFN_DIRCACHE( || !auto_update )) |
4177 | { | ||
4178 | if (lseek(fd, fe->tag_length, SEEK_CUR) < 0) | ||
4154 | { | 4179 | { |
4155 | logf("Entry no longer valid."); | 4180 | logf("read error #11.5"); |
4156 | logf("-> %s", buf); | 4181 | goto failure; |
4157 | if (global_settings.tagcache_autoupdate) | ||
4158 | delete_entry(fe->idx_id); | ||
4159 | continue ; | ||
4160 | } | 4182 | } |
4183 | } | ||
4184 | |||
4185 | if (read(fd, filename, fe->tag_length) != fe->tag_length) | ||
4186 | { | ||
4187 | logf("read error #12"); | ||
4188 | goto failure; | ||
4189 | } | ||
4190 | |||
4191 | #ifdef HAVE_DIRCACHE | ||
4192 | /* If auto updating, check storage too, otherwise simply | ||
4193 | attempt to load cache references */ | ||
4194 | unsigned int searchflag = auto_update ? DCS_STORAGE_PATH : | ||
4195 | DCS_CACHED_PATH; | ||
4161 | 4196 | ||
4197 | int rc = dircache_search(searchflag | DCS_UPDATE_FILEREF, | ||
4198 | &tcrc_dcfrefs[idx_id], filename); | ||
4199 | if (rc > 0) /* in cache and we have fileref */ | ||
4162 | idx->flag |= FLAG_DIRCACHE; | 4200 | idx->flag |= FLAG_DIRCACHE; |
4163 | idx->tag_seek[tag_filename] = dc; | 4201 | else if (rc == 0) /* not in cache but okay */ |
4164 | #else /* ndef HAVE_DIRCACHE */ | 4202 | ; |
4165 | /* This will be very slow unless target is flash based; | 4203 | else if (auto_update) |
4166 | do it anyway for consistency. */ | 4204 | #else /* ndef HAVE_DIRCACHE */ |
4167 | if (!file_exists(buf)) | 4205 | /* Check if path is no longer valid */ |
4168 | { | 4206 | if (auto_update && !file_exists(filename)) |
4169 | logf("Entry no longer valid."); | 4207 | #endif /* HAVE_DIRCACHE */ |
4170 | logf("-> %s", buf); | 4208 | { |
4171 | delete_entry(fe->idx_id); | 4209 | logf("Entry no longer valid."); |
4172 | continue; | 4210 | logf("-> %s", filename); |
4173 | } | 4211 | delete_entry(idx_id); |
4174 | #endif /* HAVE_DIRCACHE */ | ||
4175 | } | 4212 | } |
4176 | 4213 | ||
4177 | continue ; | 4214 | continue; |
4178 | } | 4215 | } |
4179 | 4216 | ||
4180 | bytesleft -= sizeof(struct tagfile_entry) + fe->tag_length; | 4217 | bytesleft -= sizeof(struct tagfile_entry) + fe->tag_length; |
4181 | if (bytesleft < 0) | 4218 | if (bytesleft < 0) |
4182 | { | 4219 | { |
@@ -4187,7 +4224,7 @@ static bool load_tagcache(void) | |||
4187 | } | 4224 | } |
4188 | 4225 | ||
4189 | p = fe->tag_data; | 4226 | p = fe->tag_data; |
4190 | rc = read(fd, fe->tag_data, fe->tag_length); | 4227 | rc = read(fd, p, fe->tag_length); |
4191 | p += rc; | 4228 | p += rc; |
4192 | 4229 | ||
4193 | if (rc != fe->tag_length) | 4230 | if (rc != fe->tag_length) |
@@ -4200,20 +4237,27 @@ static bool load_tagcache(void) | |||
4200 | goto failure; | 4237 | goto failure; |
4201 | } | 4238 | } |
4202 | } | 4239 | } |
4240 | |||
4241 | #ifdef HAVE_DIRCACHE | ||
4242 | if (tag == tag_filename) | ||
4243 | p = (char *)&tcrc_dcfrefs[tcmh.tch.entry_count]; | ||
4244 | #endif /* HAVE_DIRCACHE */ | ||
4245 | |||
4203 | close(fd); | 4246 | close(fd); |
4204 | } | 4247 | } |
4205 | 4248 | ||
4206 | tc_stat.ramcache_used = tc_stat.ramcache_allocated - bytesleft; | 4249 | tc_stat.ramcache_used = tc_stat.ramcache_allocated - bytesleft; |
4207 | logf("tagcache loaded into ram!"); | 4250 | logf("tagcache loaded into ram!"); |
4251 | logf("utilization: %d%%", 100*tc_stat.ramcache_used / tc_stat.ramcache_allocated); | ||
4208 | 4252 | ||
4209 | move_lock--; | 4253 | ok = true; |
4210 | return true; | ||
4211 | 4254 | ||
4212 | failure: | 4255 | failure: |
4213 | close(fd); | 4256 | if (fd >= 0) |
4214 | failure_nofd: | 4257 | close(fd); |
4215 | move_lock--; | 4258 | |
4216 | return false; | 4259 | tcrc_buffer_unlock(); |
4260 | return ok; | ||
4217 | } | 4261 | } |
4218 | #endif /* HAVE_TC_RAMCACHE */ | 4262 | #endif /* HAVE_TC_RAMCACHE */ |
4219 | 4263 | ||
@@ -4235,10 +4279,7 @@ static bool check_deleted_files(void) | |||
4235 | 4279 | ||
4236 | lseek(fd, sizeof(struct tagcache_header), SEEK_SET); | 4280 | lseek(fd, sizeof(struct tagcache_header), SEEK_SET); |
4237 | while (ecread_tagfile_entry(fd, &tfe) == sizeof(struct tagfile_entry) | 4281 | while (ecread_tagfile_entry(fd, &tfe) == sizeof(struct tagfile_entry) |
4238 | #ifndef __PCTOOL__ | 4282 | && !check_event_queue()) |
4239 | && !check_event_queue() | ||
4240 | #endif | ||
4241 | ) | ||
4242 | { | 4283 | { |
4243 | if (tfe.tag_length >= (long)sizeof(buf)-1) | 4284 | if (tfe.tag_length >= (long)sizeof(buf)-1) |
4244 | { | 4285 | { |
@@ -4278,7 +4319,7 @@ static bool check_deleted_files(void) | |||
4278 | /* Note that this function must not be inlined, otherwise the whole point | 4319 | /* Note that this function must not be inlined, otherwise the whole point |
4279 | * of having the code in a separate function is lost. | 4320 | * of having the code in a separate function is lost. |
4280 | */ | 4321 | */ |
4281 | static void __attribute__ ((noinline)) check_ignore(const char *dirname, | 4322 | static void NO_INLINE check_ignore(const char *dirname, |
4282 | int *ignore, int *unignore) | 4323 | int *ignore, int *unignore) |
4283 | { | 4324 | { |
4284 | char newpath[MAX_PATH]; | 4325 | char newpath[MAX_PATH]; |
@@ -4408,18 +4449,17 @@ static int free_search_roots(struct search_roots_ll * start) | |||
4408 | 4449 | ||
4409 | static bool check_dir(const char *dirname, int add_files) | 4450 | static bool check_dir(const char *dirname, int add_files) |
4410 | { | 4451 | { |
4411 | DIR *dir; | ||
4412 | int len; | ||
4413 | int success = false; | 4452 | int success = false; |
4414 | int ignore, unignore; | ||
4415 | 4453 | ||
4416 | dir = opendir(dirname); | 4454 | DIR *dir = opendir(dirname); |
4417 | if (!dir) | 4455 | if (!dir) |
4418 | { | 4456 | { |
4419 | logf("tagcache: opendir(%s) failed", dirname); | 4457 | logf("tagcache: opendir(%s) failed", dirname); |
4420 | return false; | 4458 | return false; |
4421 | } | 4459 | } |
4460 | |||
4422 | /* check for a database.ignore and database.unignore */ | 4461 | /* check for a database.ignore and database.unignore */ |
4462 | int ignore, unignore; | ||
4423 | check_ignore(dirname, &ignore, &unignore); | 4463 | check_ignore(dirname, &ignore, &unignore); |
4424 | 4464 | ||
4425 | /* don't do anything if both ignore and unignore are there */ | 4465 | /* don't do anything if both ignore and unignore are there */ |
@@ -4427,11 +4467,7 @@ static bool check_dir(const char *dirname, int add_files) | |||
4427 | add_files = unignore; | 4467 | add_files = unignore; |
4428 | 4468 | ||
4429 | /* Recursively scan the dir. */ | 4469 | /* Recursively scan the dir. */ |
4430 | #ifdef __PCTOOL__ | ||
4431 | while (1) | ||
4432 | #else | ||
4433 | while (!check_event_queue()) | 4470 | while (!check_event_queue()) |
4434 | #endif | ||
4435 | { | 4471 | { |
4436 | struct dirent *entry = readdir(dir); | 4472 | struct dirent *entry = readdir(dir); |
4437 | if (entry == NULL) | 4473 | if (entry == NULL) |
@@ -4440,42 +4476,32 @@ static bool check_dir(const char *dirname, int add_files) | |||
4440 | break; | 4476 | break; |
4441 | } | 4477 | } |
4442 | 4478 | ||
4443 | if (!strcmp((char *)entry->d_name, ".") || | 4479 | if (is_dotdir_name(entry->d_name)) |
4444 | !strcmp((char *)entry->d_name, "..")) | ||
4445 | continue; | 4480 | continue; |
4446 | 4481 | ||
4447 | struct dirinfo info = dir_get_info(dir, entry); | 4482 | struct dirinfo info = dir_get_info(dir, entry); |
4448 | 4483 | size_t len = strlen(curpath); | |
4449 | yield(); | 4484 | path_append(&curpath[len], PA_SEP_HARD, entry->d_name, |
4450 | 4485 | sizeof (curpath) - len); | |
4451 | len = strlen(curpath); | ||
4452 | /* don't add an extra / for curpath == / */ | ||
4453 | if (len <= 1) len = 0; | ||
4454 | snprintf(&curpath[len], sizeof(curpath) - len, "/%s", entry->d_name); | ||
4455 | 4486 | ||
4456 | processed_dir_count++; | 4487 | processed_dir_count++; |
4457 | if (info.attribute & ATTR_DIRECTORY) | 4488 | if (info.attribute & ATTR_DIRECTORY) |
4489 | { | ||
4458 | #ifndef SIMULATOR | 4490 | #ifndef SIMULATOR |
4459 | { /* don't follow symlinks to dirs, but try to add it as a search root | 4491 | /* don't follow symlinks to dirs, but try to add it as a search root |
4460 | * this makes able to avoid looping in recursive symlinks */ | 4492 | * this makes able to avoid looping in recursive symlinks */ |
4461 | if (info.attribute & ATTR_LINK) | 4493 | if (info.attribute & ATTR_LINK) |
4462 | add_search_root(curpath); | 4494 | add_search_root(curpath); |
4463 | else | 4495 | else |
4496 | #endif /* SIMULATOR */ | ||
4464 | check_dir(curpath, add_files); | 4497 | check_dir(curpath, add_files); |
4465 | } | 4498 | } |
4466 | #else | ||
4467 | check_dir(curpath, add_files); | ||
4468 | #endif | ||
4469 | else if (add_files) | 4499 | else if (add_files) |
4470 | { | 4500 | { |
4471 | tc_stat.curentry = curpath; | 4501 | tc_stat.curentry = curpath; |
4472 | 4502 | ||
4473 | /* Add a new entry to the temporary db file. */ | 4503 | /* Add a new entry to the temporary db file. */ |
4474 | add_tagcache(curpath, info.mtime | 4504 | add_tagcache(curpath, info.mtime); |
4475 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | ||
4476 | , dir->internal_entry | ||
4477 | #endif | ||
4478 | ); | ||
4479 | 4505 | ||
4480 | /* Wait until current path for debug screen is read and unset. */ | 4506 | /* Wait until current path for debug screen is read and unset. */ |
4481 | while (tc_stat.syncscreen && tc_stat.curentry != NULL) | 4507 | while (tc_stat.syncscreen && tc_stat.curentry != NULL) |
@@ -4517,8 +4543,7 @@ void do_tagcache_build(const char *path[]) | |||
4517 | processed_dir_count = 0; | 4543 | processed_dir_count = 0; |
4518 | 4544 | ||
4519 | #ifdef HAVE_DIRCACHE | 4545 | #ifdef HAVE_DIRCACHE |
4520 | while (dircache_is_initializing()) | 4546 | dircache_wait(); |
4521 | sleep(1); | ||
4522 | #endif | 4547 | #endif |
4523 | 4548 | ||
4524 | logf("updating tagcache"); | 4549 | logf("updating tagcache"); |
@@ -4606,7 +4631,7 @@ void do_tagcache_build(const char *path[]) | |||
4606 | #endif | 4631 | #endif |
4607 | 4632 | ||
4608 | #ifdef HAVE_TC_RAMCACHE | 4633 | #ifdef HAVE_TC_RAMCACHE |
4609 | if (ramcache_hdr) | 4634 | if (tcramcache.hdr) |
4610 | { | 4635 | { |
4611 | /* Import runtime statistics if we just initialized the db. */ | 4636 | /* Import runtime statistics if we just initialized the db. */ |
4612 | if (current_tcmh.serial == 0) | 4637 | if (current_tcmh.serial == 0) |
@@ -4629,12 +4654,12 @@ void tagcache_build(void) | |||
4629 | 4654 | ||
4630 | do_tagcache_build((const char**)vect); | 4655 | do_tagcache_build((const char**)vect); |
4631 | } | 4656 | } |
4632 | #endif | 4657 | #endif /* __PCTOOL__ */ |
4633 | 4658 | ||
4634 | #ifdef HAVE_TC_RAMCACHE | 4659 | #ifdef HAVE_TC_RAMCACHE |
4635 | static void load_ramcache(void) | 4660 | static void load_ramcache(void) |
4636 | { | 4661 | { |
4637 | if (!ramcache_hdr) | 4662 | if (!tcramcache.hdr) |
4638 | return ; | 4663 | return ; |
4639 | 4664 | ||
4640 | cpu_boost(true); | 4665 | cpu_boost(true); |
@@ -4647,7 +4672,7 @@ static void load_ramcache(void) | |||
4647 | /* If loading failed, it must indicate some problem with the db | 4672 | /* If loading failed, it must indicate some problem with the db |
4648 | * so disable it entirely to prevent further issues. */ | 4673 | * so disable it entirely to prevent further issues. */ |
4649 | tc_stat.ready = false; | 4674 | tc_stat.ready = false; |
4650 | ramcache_hdr = NULL; | 4675 | tcramcache.hdr = NULL; |
4651 | } | 4676 | } |
4652 | 4677 | ||
4653 | cpu_boost(false); | 4678 | cpu_boost(false); |
@@ -4659,7 +4684,7 @@ void tagcache_unload_ramcache(void) | |||
4659 | /* Just to make sure there is no statefile present. */ | 4684 | /* Just to make sure there is no statefile present. */ |
4660 | // remove(TAGCACHE_STATEFILE); | 4685 | // remove(TAGCACHE_STATEFILE); |
4661 | } | 4686 | } |
4662 | #endif | 4687 | #endif /* HAVE_TC_RAMCACHE */ |
4663 | 4688 | ||
4664 | #ifndef __PCTOOL__ | 4689 | #ifndef __PCTOOL__ |
4665 | static void tagcache_thread(void) | 4690 | static void tagcache_thread(void) |
@@ -4675,7 +4700,7 @@ static void tagcache_thread(void) | |||
4675 | free_tempbuf(); | 4700 | free_tempbuf(); |
4676 | 4701 | ||
4677 | #ifdef HAVE_TC_RAMCACHE | 4702 | #ifdef HAVE_TC_RAMCACHE |
4678 | # ifdef HAVE_EEPROM_SETTINGS | 4703 | #ifdef HAVE_EEPROM_SETTINGS |
4679 | if (firmware_settings.initialized && firmware_settings.disk_clean | 4704 | if (firmware_settings.initialized && firmware_settings.disk_clean |
4680 | && global_settings.tagcache_ram) | 4705 | && global_settings.tagcache_ram) |
4681 | { | 4706 | { |
@@ -4683,12 +4708,12 @@ static void tagcache_thread(void) | |||
4683 | } | 4708 | } |
4684 | 4709 | ||
4685 | remove(TAGCACHE_STATEFILE); | 4710 | remove(TAGCACHE_STATEFILE); |
4686 | # endif | 4711 | #endif /* HAVE_EEPROM_SETTINGS */ |
4687 | 4712 | ||
4688 | /* Allocate space for the tagcache if found on disk. */ | 4713 | /* Allocate space for the tagcache if found on disk. */ |
4689 | if (global_settings.tagcache_ram && !tc_stat.ramcache) | 4714 | if (global_settings.tagcache_ram && !tc_stat.ramcache) |
4690 | allocate_tagcache(); | 4715 | allocate_tagcache(); |
4691 | #endif | 4716 | #endif /* HAVE_TC_RAMCACHE */ |
4692 | 4717 | ||
4693 | cpu_boost(false); | 4718 | cpu_boost(false); |
4694 | tc_stat.initialized = true; | 4719 | tc_stat.initialized = true; |
@@ -4741,7 +4766,7 @@ static void tagcache_thread(void) | |||
4741 | tagcache_build(); | 4766 | tagcache_build(); |
4742 | } | 4767 | } |
4743 | else | 4768 | else |
4744 | #endif | 4769 | #endif /* HAVE_RC_RAMCACHE */ |
4745 | if (global_settings.tagcache_autoupdate) | 4770 | if (global_settings.tagcache_autoupdate) |
4746 | { | 4771 | { |
4747 | tagcache_build(); | 4772 | tagcache_build(); |
@@ -4800,23 +4825,29 @@ static int get_progress(void) | |||
4800 | int total_count = -1; | 4825 | int total_count = -1; |
4801 | 4826 | ||
4802 | #ifdef HAVE_DIRCACHE | 4827 | #ifdef HAVE_DIRCACHE |
4803 | if (dircache_is_enabled()) | 4828 | struct dircache_info dcinfo; |
4829 | dircache_get_info(&dcinfo); | ||
4830 | if (dcinfo.status != DIRCACHE_IDLE) | ||
4804 | { | 4831 | { |
4805 | total_count = dircache_get_entry_count(); | 4832 | total_count = dcinfo.entry_count; |
4806 | } | 4833 | } |
4807 | else | 4834 | else |
4808 | #endif | 4835 | #endif /* HAVE_DIRCACHE */ |
4809 | #ifdef HAVE_TC_RAMCACHE | 4836 | #ifdef HAVE_TC_RAMCACHE |
4810 | { | 4837 | { |
4811 | if (ramcache_hdr && tc_stat.ramcache) | 4838 | if (tcramcache.hdr && tc_stat.ramcache) |
4812 | total_count = current_tcmh.tch.entry_count; | 4839 | total_count = current_tcmh.tch.entry_count; |
4813 | } | 4840 | } |
4814 | #endif | 4841 | #endif /* HAVE_TC_RAMCACHE */ |
4815 | 4842 | ||
4816 | if (total_count < 0) | 4843 | if (total_count < 0) |
4817 | return -1; | 4844 | return -1; |
4818 | 4845 | else if (total_count == 0) | |
4819 | return processed_dir_count * 100 / total_count; | 4846 | return 0; |
4847 | else if (processed_dir_count > total_count) | ||
4848 | return 100; | ||
4849 | else | ||
4850 | return processed_dir_count * 100 / total_count; | ||
4820 | } | 4851 | } |
4821 | 4852 | ||
4822 | struct tagcache_stat* tagcache_get_stat(void) | 4853 | struct tagcache_stat* tagcache_get_stat(void) |