diff options
-rw-r--r-- | apps/tagcache.c | 185 |
1 files changed, 94 insertions, 91 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c index ff44e1014f..2c46860c95 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c | |||
@@ -211,6 +211,37 @@ bool tagcache_is_sorted_tag(int type) | |||
211 | return false; | 211 | return false; |
212 | } | 212 | } |
213 | 213 | ||
214 | static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write) | ||
215 | { | ||
216 | int fd; | ||
217 | char buf[MAX_PATH]; | ||
218 | |||
219 | if (tagcache_is_numeric_tag(tag) || tag < 0 || tag >= TAG_COUNT) | ||
220 | return -1; | ||
221 | |||
222 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag); | ||
223 | |||
224 | fd = open(buf, write ? O_RDWR : O_RDONLY); | ||
225 | if (fd < 0) | ||
226 | { | ||
227 | logf("tag file open failed: %d", tag); | ||
228 | stat.ready = false; | ||
229 | return fd; | ||
230 | } | ||
231 | |||
232 | /* Check the header. */ | ||
233 | read(fd, hdr, sizeof(struct tagcache_header)); | ||
234 | if (hdr->magic != TAGCACHE_MAGIC) | ||
235 | { | ||
236 | logf("header error"); | ||
237 | stat.ready = false; | ||
238 | close(fd); | ||
239 | return -2; | ||
240 | } | ||
241 | |||
242 | return fd; | ||
243 | } | ||
244 | |||
214 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | 245 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) |
215 | static long find_entry_ram(const char *filename, | 246 | static long find_entry_ram(const char *filename, |
216 | const struct dircache_entry *dc) | 247 | const struct dircache_entry *dc) |
@@ -266,6 +297,7 @@ static long find_entry_ram(const char *filename, | |||
266 | 297 | ||
267 | static long find_entry_disk(const char *filename) | 298 | static long find_entry_disk(const char *filename) |
268 | { | 299 | { |
300 | struct tagcache_header tch; | ||
269 | static long last_pos = -1; | 301 | static long last_pos = -1; |
270 | long pos_history[POS_HISTORY_COUNT]; | 302 | long pos_history[POS_HISTORY_COUNT]; |
271 | long pos_history_idx = 0; | 303 | long pos_history_idx = 0; |
@@ -276,11 +308,14 @@ static long find_entry_disk(const char *filename) | |||
276 | int i; | 308 | int i; |
277 | int pos = -1; | 309 | int pos = -1; |
278 | 310 | ||
311 | if (!stat.ready) | ||
312 | return -2; | ||
313 | |||
279 | fd = filenametag_fd; | 314 | fd = filenametag_fd; |
280 | if (fd < 0) | 315 | if (fd < 0) |
281 | { | 316 | { |
282 | last_pos = -1; | 317 | last_pos = -1; |
283 | if ( (fd = open(TAGCACHE_FILE_MASTER, O_RDONLY)) < 0) | 318 | if ( (fd = open_tag_fd(&tch, tag_filename, false)) < 0) |
284 | return -1; | 319 | return -1; |
285 | } | 320 | } |
286 | 321 | ||
@@ -288,8 +323,6 @@ static long find_entry_disk(const char *filename) | |||
288 | 323 | ||
289 | if (last_pos > 0) | 324 | if (last_pos > 0) |
290 | lseek(fd, last_pos, SEEK_SET); | 325 | lseek(fd, last_pos, SEEK_SET); |
291 | else | ||
292 | lseek(fd, sizeof(struct master_header), SEEK_SET); | ||
293 | 326 | ||
294 | while (true) | 327 | while (true) |
295 | { | 328 | { |
@@ -374,6 +407,9 @@ bool tagcache_find_index(struct tagcache_search *tcs, const char *filename) | |||
374 | { | 407 | { |
375 | int idx_id; | 408 | int idx_id; |
376 | 409 | ||
410 | if (!stat.ready) | ||
411 | return false; | ||
412 | |||
377 | idx_id = find_index(filename); | 413 | idx_id = find_index(filename); |
378 | if (idx_id < 0) | 414 | if (idx_id < 0) |
379 | return false; | 415 | return false; |
@@ -444,6 +480,9 @@ long tagcache_get_numeric(const struct tagcache_search *tcs, int tag) | |||
444 | { | 480 | { |
445 | struct index_entry idx; | 481 | struct index_entry idx; |
446 | 482 | ||
483 | if (!stat.ready) | ||
484 | return false; | ||
485 | |||
447 | if (!tagcache_is_numeric_tag(tag)) | 486 | if (!tagcache_is_numeric_tag(tag)) |
448 | return -1; | 487 | return -1; |
449 | 488 | ||
@@ -672,6 +711,7 @@ static void remove_files(void) | |||
672 | } | 711 | } |
673 | } | 712 | } |
674 | 713 | ||
714 | |||
675 | static int open_master_fd(struct master_header *hdr, bool write) | 715 | static int open_master_fd(struct master_header *hdr, bool write) |
676 | { | 716 | { |
677 | int fd; | 717 | int fd; |
@@ -691,7 +731,6 @@ static int open_master_fd(struct master_header *hdr, bool write) | |||
691 | logf("header error"); | 731 | logf("header error"); |
692 | stat.ready = false; | 732 | stat.ready = false; |
693 | close(fd); | 733 | close(fd); |
694 | remove_files(); | ||
695 | return -2; | 734 | return -2; |
696 | } | 735 | } |
697 | 736 | ||
@@ -702,7 +741,6 @@ bool tagcache_search(struct tagcache_search *tcs, int tag) | |||
702 | { | 741 | { |
703 | struct tagcache_header tag_hdr; | 742 | struct tagcache_header tag_hdr; |
704 | struct master_header master_hdr; | 743 | struct master_header master_hdr; |
705 | char buf[MAX_PATH]; | ||
706 | int i; | 744 | int i; |
707 | 745 | ||
708 | if (tcs->valid) | 746 | if (tcs->valid) |
@@ -737,22 +775,10 @@ bool tagcache_search(struct tagcache_search *tcs, int tag) | |||
737 | if (tagcache_is_numeric_tag(tcs->type)) | 775 | if (tagcache_is_numeric_tag(tcs->type)) |
738 | return true; | 776 | return true; |
739 | 777 | ||
740 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tcs->type); | 778 | tcs->idxfd[tcs->type] = open_tag_fd(&tag_hdr, tcs->type, false); |
741 | tcs->idxfd[tcs->type] = open(buf, O_RDONLY); | ||
742 | if (tcs->idxfd[tcs->type] < 0) | 779 | if (tcs->idxfd[tcs->type] < 0) |
743 | { | ||
744 | logf("failed to open index"); | ||
745 | return false; | 780 | return false; |
746 | } | ||
747 | 781 | ||
748 | /* Check the header. */ | ||
749 | if (read(tcs->idxfd[tcs->type], &tag_hdr, sizeof(struct tagcache_header)) != | ||
750 | sizeof(struct tagcache_header) || tag_hdr.magic != TAGCACHE_MAGIC) | ||
751 | { | ||
752 | logf("incorrect header"); | ||
753 | return false; | ||
754 | } | ||
755 | |||
756 | tcs->masterfd = open_master_fd(&master_hdr, false); | 782 | tcs->masterfd = open_master_fd(&master_hdr, false); |
757 | 783 | ||
758 | if (tcs->masterfd < 0) | 784 | if (tcs->masterfd < 0) |
@@ -829,7 +855,7 @@ static bool get_next(struct tagcache_search *tcs) | |||
829 | static char buf[MAX_PATH]; | 855 | static char buf[MAX_PATH]; |
830 | struct tagfile_entry entry; | 856 | struct tagfile_entry entry; |
831 | 857 | ||
832 | if (!tcs->valid) | 858 | if (!tcs->valid || !stat.ready) |
833 | return false; | 859 | return false; |
834 | 860 | ||
835 | if (tcs->idxfd[tcs->type] < 0 && !tagcache_is_numeric_tag(tcs->type) | 861 | if (tcs->idxfd[tcs->type] < 0 && !tagcache_is_numeric_tag(tcs->type) |
@@ -1087,6 +1113,9 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename) | |||
1087 | struct index_entry *entry; | 1113 | struct index_entry *entry; |
1088 | int idx_id; | 1114 | int idx_id; |
1089 | 1115 | ||
1116 | if (!stat.ready) | ||
1117 | return false; | ||
1118 | |||
1090 | /* Find the corresponding entry in tagcache. */ | 1119 | /* Find the corresponding entry in tagcache. */ |
1091 | idx_id = find_entry_ram(filename, NULL); | 1120 | idx_id = find_entry_ram(filename, NULL); |
1092 | if (idx_id < 0 || !stat.ramcache) | 1121 | if (idx_id < 0 || !stat.ramcache) |
@@ -1156,8 +1185,11 @@ static void add_tagcache(const char *path) | |||
1156 | else | 1185 | else |
1157 | #endif | 1186 | #endif |
1158 | { | 1187 | { |
1159 | if (find_entry_disk(path) >= 0) | 1188 | if (filenametag_fd >= 0) |
1160 | return ; | 1189 | { |
1190 | if (find_entry_disk(path) >= 0) | ||
1191 | return ; | ||
1192 | } | ||
1161 | } | 1193 | } |
1162 | 1194 | ||
1163 | fd = open(path, O_RDONLY); | 1195 | fd = open(path, O_RDONLY); |
@@ -1563,20 +1595,10 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
1563 | memset(lookup, 0, LOOKUP_BUF_DEPTH * sizeof(void **)); | 1595 | memset(lookup, 0, LOOKUP_BUF_DEPTH * sizeof(void **)); |
1564 | 1596 | ||
1565 | /* Open the index file, which contains the tag names. */ | 1597 | /* Open the index file, which contains the tag names. */ |
1566 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, index_type); | 1598 | fd = open_tag_fd(&tch, index_type, true); |
1567 | fd = open(buf, O_RDWR); | ||
1568 | 1599 | ||
1569 | if (fd >= 0) | 1600 | if (fd >= 0) |
1570 | { | 1601 | { |
1571 | /* Read the header. */ | ||
1572 | if (read(fd, &tch, sizeof(struct tagcache_header)) != | ||
1573 | sizeof(struct tagcache_header) || tch.magic != TAGCACHE_MAGIC) | ||
1574 | { | ||
1575 | logf("header error"); | ||
1576 | close(fd); | ||
1577 | return -2; | ||
1578 | } | ||
1579 | |||
1580 | /** | 1602 | /** |
1581 | * If tag file contains unique tags (sorted index), we will load | 1603 | * If tag file contains unique tags (sorted index), we will load |
1582 | * it entirely into memory so we can resort it later for use with | 1604 | * it entirely into memory so we can resort it later for use with |
@@ -1991,7 +2013,6 @@ static bool commit(void) | |||
1991 | { | 2013 | { |
1992 | logf("incorrect header"); | 2014 | logf("incorrect header"); |
1993 | close(tmpfd); | 2015 | close(tmpfd); |
1994 | remove_files(); | ||
1995 | remove(TAGCACHE_FILE_TEMP); | 2016 | remove(TAGCACHE_FILE_TEMP); |
1996 | return false; | 2017 | return false; |
1997 | } | 2018 | } |
@@ -2159,6 +2180,9 @@ static bool update_current_serial(long serial) | |||
2159 | 2180 | ||
2160 | long tagcache_increase_serial(void) | 2181 | long tagcache_increase_serial(void) |
2161 | { | 2182 | { |
2183 | if (!stat.ready) | ||
2184 | return -2; | ||
2185 | |||
2162 | if (!update_current_serial(current_serial + 1)) | 2186 | if (!update_current_serial(current_serial + 1)) |
2163 | return -1; | 2187 | return -1; |
2164 | 2188 | ||
@@ -2174,6 +2198,9 @@ static bool modify_numeric_entry(int masterfd, int idx_id, int tag, long data) | |||
2174 | { | 2198 | { |
2175 | struct index_entry idx; | 2199 | struct index_entry idx; |
2176 | 2200 | ||
2201 | if (!stat.ready) | ||
2202 | return false; | ||
2203 | |||
2177 | if (!tagcache_is_numeric_tag(tag)) | 2204 | if (!tagcache_is_numeric_tag(tag)) |
2178 | return false; | 2205 | return false; |
2179 | 2206 | ||
@@ -2378,6 +2405,9 @@ bool tagcache_import_changelog(void) | |||
2378 | char buf[512]; | 2405 | char buf[512]; |
2379 | int pos = 0; | 2406 | int pos = 0; |
2380 | 2407 | ||
2408 | if (!stat.ready) | ||
2409 | return false; | ||
2410 | |||
2381 | clfd = open(TAGCACHE_FILE_CHANGELOG, O_RDONLY); | 2411 | clfd = open(TAGCACHE_FILE_CHANGELOG, O_RDONLY); |
2382 | if (clfd < 0) | 2412 | if (clfd < 0) |
2383 | { | 2413 | { |
@@ -2444,6 +2474,9 @@ bool tagcache_create_changelog(struct tagcache_search *tcs) | |||
2444 | int clfd; | 2474 | int clfd; |
2445 | int i, j; | 2475 | int i, j; |
2446 | 2476 | ||
2477 | if (!stat.ready) | ||
2478 | return false; | ||
2479 | |||
2447 | if (!tagcache_search(tcs, tag_filename)) | 2480 | if (!tagcache_search(tcs, tag_filename)) |
2448 | return false; | 2481 | return false; |
2449 | 2482 | ||
@@ -2621,33 +2654,19 @@ static bool delete_entry(long idx_id) | |||
2621 | #ifdef HAVE_TC_RAMCACHE | 2654 | #ifdef HAVE_TC_RAMCACHE |
2622 | static bool allocate_tagcache(void) | 2655 | static bool allocate_tagcache(void) |
2623 | { | 2656 | { |
2624 | int rc, len; | ||
2625 | int fd; | 2657 | int fd; |
2626 | 2658 | ||
2627 | hdr = NULL; | ||
2628 | |||
2629 | fd = open(TAGCACHE_FILE_MASTER, O_RDONLY); | ||
2630 | if (fd < 0) | ||
2631 | { | ||
2632 | logf("no tagcache file found."); | ||
2633 | return false; | ||
2634 | } | ||
2635 | |||
2636 | /* Load the header. */ | 2659 | /* Load the header. */ |
2637 | hdr = (struct ramcache_header *)(((long)audiobuf & ~0x03) + 0x04); | 2660 | hdr = (struct ramcache_header *)(((long)audiobuf & ~0x03) + 0x04); |
2638 | memset(hdr, 0, sizeof(struct ramcache_header)); | 2661 | memset(hdr, 0, sizeof(struct ramcache_header)); |
2639 | len = sizeof(struct master_header); | 2662 | if ( (fd = open_master_fd(&hdr->h, false)) < 0) |
2640 | rc = read(fd, &hdr->h, len); | ||
2641 | close(fd); | ||
2642 | |||
2643 | if (hdr->h.tch.magic != TAGCACHE_MAGIC || rc != len) | ||
2644 | { | 2663 | { |
2645 | logf("incorrect header"); | ||
2646 | remove_files(); | ||
2647 | hdr = NULL; | 2664 | hdr = NULL; |
2648 | return false; | 2665 | return false; |
2649 | } | 2666 | } |
2650 | 2667 | ||
2668 | close(fd); | ||
2669 | |||
2651 | hdr->indices = (struct index_entry *)(hdr + 1); | 2670 | hdr->indices = (struct index_entry *)(hdr + 1); |
2652 | 2671 | ||
2653 | /** | 2672 | /** |
@@ -2734,26 +2753,12 @@ static bool load_tagcache(void) | |||
2734 | p = (char *)((long)p & ~0x03) + 0x04; | 2753 | p = (char *)((long)p & ~0x03) + 0x04; |
2735 | hdr->tags[tag] = p; | 2754 | hdr->tags[tag] = p; |
2736 | 2755 | ||
2737 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag); | ||
2738 | fd = open(buf, O_RDONLY); | ||
2739 | |||
2740 | if (fd < 0) | ||
2741 | { | ||
2742 | logf("%s open fail", buf); | ||
2743 | return false; | ||
2744 | } | ||
2745 | |||
2746 | /* Check the header. */ | 2756 | /* Check the header. */ |
2747 | tch = (struct tagcache_header *)p; | 2757 | tch = (struct tagcache_header *)p; |
2748 | rc = read(fd, tch, sizeof(struct tagcache_header)); | 2758 | p += sizeof(struct tagcache_header); |
2749 | p += rc; | 2759 | |
2750 | if (rc != sizeof(struct tagcache_header) || | 2760 | if ( (fd = open_tag_fd(tch, tag, false)) < 0) |
2751 | tch->magic != TAGCACHE_MAGIC) | ||
2752 | { | ||
2753 | logf("incorrect header"); | ||
2754 | close(fd); | ||
2755 | return false; | 2761 | return false; |
2756 | } | ||
2757 | 2762 | ||
2758 | for (hdr->entry_count[tag] = 0; | 2763 | for (hdr->entry_count[tag] = 0; |
2759 | hdr->entry_count[tag] < tch->entry_count; | 2764 | hdr->entry_count[tag] < tch->entry_count; |
@@ -3004,7 +3009,6 @@ static void build_tagcache(void) | |||
3004 | { | 3009 | { |
3005 | struct tagcache_header header; | 3010 | struct tagcache_header header; |
3006 | bool ret; | 3011 | bool ret; |
3007 | char buf[MAX_PATH]; | ||
3008 | 3012 | ||
3009 | curpath[0] = '\0'; | 3013 | curpath[0] = '\0'; |
3010 | data_size = 0; | 3014 | data_size = 0; |
@@ -3028,21 +3032,8 @@ static void build_tagcache(void) | |||
3028 | return ; | 3032 | return ; |
3029 | } | 3033 | } |
3030 | 3034 | ||
3031 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag_filename); | 3035 | filenametag_fd = open_tag_fd(&header, tag_filename, false); |
3032 | filenametag_fd = open(buf, O_RDONLY); | 3036 | |
3033 | |||
3034 | if (filenametag_fd >= 0) | ||
3035 | { | ||
3036 | if (read(filenametag_fd, &header, sizeof(struct tagcache_header)) != | ||
3037 | sizeof(struct tagcache_header) || header.magic != TAGCACHE_MAGIC) | ||
3038 | { | ||
3039 | logf("header error"); | ||
3040 | close(filenametag_fd); | ||
3041 | filenametag_fd = -1; | ||
3042 | } | ||
3043 | } | ||
3044 | |||
3045 | |||
3046 | cpu_boost(true); | 3037 | cpu_boost(true); |
3047 | 3038 | ||
3048 | /* Scan for new files. */ | 3039 | /* Scan for new files. */ |
@@ -3095,18 +3086,17 @@ static void load_ramcache(void) | |||
3095 | stat.ramcache = load_tagcache(); | 3086 | stat.ramcache = load_tagcache(); |
3096 | 3087 | ||
3097 | if (!stat.ramcache) | 3088 | if (!stat.ramcache) |
3098 | { | ||
3099 | hdr = NULL; | 3089 | hdr = NULL; |
3100 | remove_files(); | ||
3101 | } | ||
3102 | 3090 | ||
3103 | cpu_boost(false); | 3091 | cpu_boost(false); |
3104 | } | 3092 | } |
3105 | #endif | 3093 | #endif |
3106 | 3094 | ||
3107 | static bool check_master_fd(void) | 3095 | static bool check_all_headers(void) |
3108 | { | 3096 | { |
3109 | struct master_header myhdr; | 3097 | struct master_header myhdr; |
3098 | struct tagcache_header tch; | ||
3099 | int tag; | ||
3110 | int fd; | 3100 | int fd; |
3111 | 3101 | ||
3112 | if ( (fd = open_master_fd(&myhdr, false)) < 0) | 3102 | if ( (fd = open_master_fd(&myhdr, false)) < 0) |
@@ -3115,6 +3105,17 @@ static bool check_master_fd(void) | |||
3115 | close(fd); | 3105 | close(fd); |
3116 | current_serial = myhdr.serial; | 3106 | current_serial = myhdr.serial; |
3117 | 3107 | ||
3108 | for (tag = 0; tag < TAG_COUNT; tag++) | ||
3109 | { | ||
3110 | if (tagcache_is_numeric_tag(tag)) | ||
3111 | continue; | ||
3112 | |||
3113 | if ( (fd = open_tag_fd(&tch, tag, false)) < 0) | ||
3114 | return false; | ||
3115 | |||
3116 | close(fd); | ||
3117 | } | ||
3118 | |||
3118 | return true; | 3119 | return true; |
3119 | } | 3120 | } |
3120 | 3121 | ||
@@ -3137,10 +3138,12 @@ static void tagcache_thread(void) | |||
3137 | #endif | 3138 | #endif |
3138 | 3139 | ||
3139 | cpu_boost(false); | 3140 | cpu_boost(false); |
3141 | stat.initialized = true; | ||
3140 | 3142 | ||
3141 | stat.ready = check_master_fd(); | 3143 | /* Don't delay bootup with the header check but do it on background. */ |
3144 | sleep(HZ); | ||
3145 | stat.ready = check_all_headers(); | ||
3142 | 3146 | ||
3143 | stat.initialized = true; | ||
3144 | 3147 | ||
3145 | while (1) | 3148 | while (1) |
3146 | { | 3149 | { |
@@ -3163,7 +3166,7 @@ static void tagcache_thread(void) | |||
3163 | break ; | 3166 | break ; |
3164 | 3167 | ||
3165 | case SYS_TIMEOUT: | 3168 | case SYS_TIMEOUT: |
3166 | if (check_done) | 3169 | if (check_done || !stat.ready) |
3167 | break ; | 3170 | break ; |
3168 | 3171 | ||
3169 | #ifdef HAVE_TC_RAMCACHE | 3172 | #ifdef HAVE_TC_RAMCACHE |