summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/tagcache.c185
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
214static 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)
215static long find_entry_ram(const char *filename, 246static 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
267static long find_entry_disk(const char *filename) 298static 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
675static int open_master_fd(struct master_header *hdr, bool write) 715static 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
2160long tagcache_increase_serial(void) 2181long 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
2622static bool allocate_tagcache(void) 2655static 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
3107static bool check_master_fd(void) 3095static 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