diff options
Diffstat (limited to 'apps/tagcache.c')
-rw-r--r-- | apps/tagcache.c | 214 |
1 files changed, 134 insertions, 80 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c index d4ec1078d8..d7a377e7e2 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c | |||
@@ -410,7 +410,7 @@ static long find_entry_ram(const char *filename, | |||
410 | } | 410 | } |
411 | #endif | 411 | #endif |
412 | 412 | ||
413 | static long find_entry_disk(const char *filename) | 413 | static long find_entry_disk(const char *filename, bool localfd) |
414 | { | 414 | { |
415 | struct tagcache_header tch; | 415 | struct tagcache_header tch; |
416 | static long last_pos = -1; | 416 | static long last_pos = -1; |
@@ -427,7 +427,7 @@ static long find_entry_disk(const char *filename) | |||
427 | return -2; | 427 | return -2; |
428 | 428 | ||
429 | fd = filenametag_fd; | 429 | fd = filenametag_fd; |
430 | if (fd < 0) | 430 | if (fd < 0 || localfd) |
431 | { | 431 | { |
432 | last_pos = -1; | 432 | last_pos = -1; |
433 | if ( (fd = open_tag_fd(&tch, tag_filename, false)) < 0) | 433 | if ( (fd = open_tag_fd(&tch, tag_filename, false)) < 0) |
@@ -458,6 +458,8 @@ static long find_entry_disk(const char *filename) | |||
458 | { | 458 | { |
459 | logf("too long tag #1"); | 459 | logf("too long tag #1"); |
460 | close(fd); | 460 | close(fd); |
461 | if (!localfd) | ||
462 | filenametag_fd = -1; | ||
461 | last_pos = -1; | 463 | last_pos = -1; |
462 | return -2; | 464 | return -2; |
463 | } | 465 | } |
@@ -466,6 +468,8 @@ static long find_entry_disk(const char *filename) | |||
466 | { | 468 | { |
467 | logf("read error #2"); | 469 | logf("read error #2"); |
468 | close(fd); | 470 | close(fd); |
471 | if (!localfd) | ||
472 | filenametag_fd = -1; | ||
469 | last_pos = -1; | 473 | last_pos = -1; |
470 | return -3; | 474 | return -3; |
471 | } | 475 | } |
@@ -491,12 +495,12 @@ static long find_entry_disk(const char *filename) | |||
491 | goto check_again; | 495 | goto check_again; |
492 | } | 496 | } |
493 | 497 | ||
494 | if (fd != filenametag_fd) | 498 | if (fd != filenametag_fd || localfd) |
495 | close(fd); | 499 | close(fd); |
496 | return -4; | 500 | return -4; |
497 | } | 501 | } |
498 | 502 | ||
499 | if (fd != filenametag_fd) | 503 | if (fd != filenametag_fd || localfd) |
500 | close(fd); | 504 | close(fd); |
501 | 505 | ||
502 | return tfe.idx_id; | 506 | return tfe.idx_id; |
@@ -512,7 +516,7 @@ static int find_index(const char *filename) | |||
512 | #endif | 516 | #endif |
513 | 517 | ||
514 | if (idx_id < 0) | 518 | if (idx_id < 0) |
515 | idx_id = find_entry_disk(filename); | 519 | idx_id = find_entry_disk(filename, true); |
516 | 520 | ||
517 | return idx_id; | 521 | return idx_id; |
518 | } | 522 | } |
@@ -554,8 +558,14 @@ static bool get_index(int masterfd, int idxid, | |||
554 | if (hdr->indices[idxid].flag & FLAG_DELETED) | 558 | if (hdr->indices[idxid].flag & FLAG_DELETED) |
555 | return false; | 559 | return false; |
556 | 560 | ||
557 | memcpy(idx, &hdr->indices[idxid], sizeof(struct index_entry)); | 561 | # ifdef HAVE_DIRCACHE |
558 | return true; | 562 | if (!(hdr->indices[idxid].flag & FLAG_DIRCACHE) |
563 | || is_dircache_intact()) | ||
564 | #endif | ||
565 | { | ||
566 | memcpy(idx, &hdr->indices[idxid], sizeof(struct index_entry)); | ||
567 | return true; | ||
568 | } | ||
559 | } | 569 | } |
560 | #else | 570 | #else |
561 | (void)use_ram; | 571 | (void)use_ram; |
@@ -1006,17 +1016,20 @@ static bool add_uniqbuf(struct tagcache_search *tcs, unsigned long id) | |||
1006 | static bool build_lookup_list(struct tagcache_search *tcs) | 1016 | static bool build_lookup_list(struct tagcache_search *tcs) |
1007 | { | 1017 | { |
1008 | struct index_entry entry; | 1018 | struct index_entry entry; |
1009 | int i; | 1019 | int i, j; |
1010 | 1020 | ||
1011 | tcs->seek_list_count = 0; | 1021 | tcs->seek_list_count = 0; |
1012 | 1022 | ||
1013 | #ifdef HAVE_TC_RAMCACHE | 1023 | #ifdef HAVE_TC_RAMCACHE |
1014 | if (tcs->ramsearch) | 1024 | if (tcs->ramsearch |
1025 | # ifdef HAVE_DIRCACHE | ||
1026 | && (tcs->type != tag_filename || is_dircache_intact()) | ||
1027 | # endif | ||
1028 | ) | ||
1015 | { | 1029 | { |
1016 | int j; | ||
1017 | |||
1018 | for (i = tcs->seek_pos; i < hdr->h.tch.entry_count; i++) | 1030 | for (i = tcs->seek_pos; i < hdr->h.tch.entry_count; i++) |
1019 | { | 1031 | { |
1032 | struct tagcache_seeklist_entry *seeklist; | ||
1020 | struct index_entry *idx = &hdr->indices[i]; | 1033 | struct index_entry *idx = &hdr->indices[i]; |
1021 | if (tcs->seek_list_count == SEEK_LIST_SIZE) | 1034 | if (tcs->seek_list_count == SEEK_LIST_SIZE) |
1022 | break ; | 1035 | break ; |
@@ -1046,26 +1059,37 @@ static bool build_lookup_list(struct tagcache_search *tcs) | |||
1046 | continue; | 1059 | continue; |
1047 | 1060 | ||
1048 | /* Lets add it. */ | 1061 | /* Lets add it. */ |
1049 | tcs->seek_list[tcs->seek_list_count] = idx->tag_seek[tcs->type]; | 1062 | seeklist = &tcs->seeklist[tcs->seek_list_count]; |
1050 | tcs->seek_flags[tcs->seek_list_count] = idx->flag; | 1063 | seeklist->seek = idx->tag_seek[tcs->type]; |
1064 | seeklist->flag = idx->flag; | ||
1065 | seeklist->idx_id = i; | ||
1051 | tcs->seek_list_count++; | 1066 | tcs->seek_list_count++; |
1052 | } | 1067 | } |
1053 | 1068 | ||
1054 | tcs->seek_pos = i; | 1069 | tcs->seek_pos = i; |
1055 | 1070 | ||
1056 | return tcs->seek_list_count > 0; | 1071 | return tcs->seek_list_count > 0; |
1057 | } | 1072 | } |
1058 | #endif | 1073 | #endif |
1059 | 1074 | ||
1075 | if (tcs->masterfd < 0) | ||
1076 | { | ||
1077 | struct master_header tcmh; | ||
1078 | tcs->masterfd = open_master_fd(&tcmh, false); | ||
1079 | } | ||
1080 | |||
1060 | lseek(tcs->masterfd, tcs->seek_pos * sizeof(struct index_entry) + | 1081 | lseek(tcs->masterfd, tcs->seek_pos * sizeof(struct index_entry) + |
1061 | sizeof(struct master_header), SEEK_SET); | 1082 | sizeof(struct master_header), SEEK_SET); |
1062 | 1083 | ||
1063 | while (ecread(tcs->masterfd, &entry, 1, index_entry_ec, tc_stat.econ) | 1084 | while (ecread(tcs->masterfd, &entry, 1, index_entry_ec, tc_stat.econ) |
1064 | == sizeof(struct index_entry)) | 1085 | == sizeof(struct index_entry)) |
1065 | { | 1086 | { |
1087 | struct tagcache_seeklist_entry *seeklist; | ||
1088 | |||
1066 | if (tcs->seek_list_count == SEEK_LIST_SIZE) | 1089 | if (tcs->seek_list_count == SEEK_LIST_SIZE) |
1067 | break ; | 1090 | break ; |
1068 | 1091 | ||
1092 | i = tcs->seek_pos; | ||
1069 | tcs->seek_pos++; | 1093 | tcs->seek_pos++; |
1070 | 1094 | ||
1071 | /* Check if entry has been deleted. */ | 1095 | /* Check if entry has been deleted. */ |
@@ -1073,13 +1097,13 @@ static bool build_lookup_list(struct tagcache_search *tcs) | |||
1073 | continue; | 1097 | continue; |
1074 | 1098 | ||
1075 | /* Go through all filters.. */ | 1099 | /* Go through all filters.. */ |
1076 | for (i = 0; i < tcs->filter_count; i++) | 1100 | for (j = 0; j < tcs->filter_count; j++) |
1077 | { | 1101 | { |
1078 | if (entry.tag_seek[tcs->filter_tag[i]] != tcs->filter_seek[i]) | 1102 | if (entry.tag_seek[tcs->filter_tag[j]] != tcs->filter_seek[j]) |
1079 | break ; | 1103 | break ; |
1080 | } | 1104 | } |
1081 | 1105 | ||
1082 | if (i < tcs->filter_count) | 1106 | if (j < tcs->filter_count) |
1083 | continue ; | 1107 | continue ; |
1084 | 1108 | ||
1085 | /* Check for conditions. */ | 1109 | /* Check for conditions. */ |
@@ -1091,8 +1115,10 @@ static bool build_lookup_list(struct tagcache_search *tcs) | |||
1091 | continue; | 1115 | continue; |
1092 | 1116 | ||
1093 | /* Lets add it. */ | 1117 | /* Lets add it. */ |
1094 | tcs->seek_list[tcs->seek_list_count] = entry.tag_seek[tcs->type]; | 1118 | seeklist = &tcs->seeklist[tcs->seek_list_count]; |
1095 | tcs->seek_flags[tcs->seek_list_count] = entry.flag; | 1119 | seeklist->seek = entry.tag_seek[tcs->type]; |
1120 | seeklist->flag = entry.flag; | ||
1121 | seeklist->idx_id = i; | ||
1096 | tcs->seek_list_count++; | 1122 | tcs->seek_list_count++; |
1097 | 1123 | ||
1098 | yield(); | 1124 | yield(); |
@@ -1155,15 +1181,17 @@ static bool check_all_headers(void) | |||
1155 | return true; | 1181 | return true; |
1156 | } | 1182 | } |
1157 | 1183 | ||
1184 | bool tagcache_is_busy(void) | ||
1185 | { | ||
1186 | return read_lock || write_lock; | ||
1187 | } | ||
1188 | |||
1158 | bool tagcache_search(struct tagcache_search *tcs, int tag) | 1189 | bool tagcache_search(struct tagcache_search *tcs, int tag) |
1159 | { | 1190 | { |
1160 | struct tagcache_header tag_hdr; | 1191 | struct tagcache_header tag_hdr; |
1161 | struct master_header master_hdr; | 1192 | struct master_header master_hdr; |
1162 | int i; | 1193 | int i; |
1163 | 1194 | ||
1164 | if (tcs->initialized) | ||
1165 | tagcache_search_finish(tcs); | ||
1166 | |||
1167 | while (read_lock) | 1195 | while (read_lock) |
1168 | sleep(1); | 1196 | sleep(1); |
1169 | 1197 | ||
@@ -1174,6 +1202,7 @@ bool tagcache_search(struct tagcache_search *tcs, int tag) | |||
1174 | tcs->position = sizeof(struct tagcache_header); | 1202 | tcs->position = sizeof(struct tagcache_header); |
1175 | tcs->type = tag; | 1203 | tcs->type = tag; |
1176 | tcs->seek_pos = 0; | 1204 | tcs->seek_pos = 0; |
1205 | tcs->list_position = 0; | ||
1177 | tcs->seek_list_count = 0; | 1206 | tcs->seek_list_count = 0; |
1178 | tcs->filter_count = 0; | 1207 | tcs->filter_count = 0; |
1179 | tcs->masterfd = -1; | 1208 | tcs->masterfd = -1; |
@@ -1192,19 +1221,24 @@ bool tagcache_search(struct tagcache_search *tcs, int tag) | |||
1192 | else | 1221 | else |
1193 | #endif | 1222 | #endif |
1194 | { | 1223 | { |
1224 | /* Always open as R/W so we can pass tcs to functions that modify data also | ||
1225 | * without failing. */ | ||
1226 | tcs->masterfd = open_master_fd(&master_hdr, true); | ||
1227 | if (tcs->masterfd < 0) | ||
1228 | return false; | ||
1229 | |||
1195 | if (!TAGCACHE_IS_NUMERIC(tcs->type)) | 1230 | if (!TAGCACHE_IS_NUMERIC(tcs->type)) |
1196 | { | 1231 | { |
1197 | tcs->idxfd[tcs->type] = open_tag_fd(&tag_hdr, tcs->type, false); | 1232 | tcs->idxfd[tcs->type] = open_tag_fd(&tag_hdr, tcs->type, false); |
1198 | if (tcs->idxfd[tcs->type] < 0) | 1233 | if (tcs->idxfd[tcs->type] < 0) |
1199 | return false; | 1234 | return false; |
1235 | |||
1236 | tcs->entry_count = tag_hdr.entry_count; | ||
1237 | } | ||
1238 | else | ||
1239 | { | ||
1240 | tcs->entry_count = master_hdr.tch.entry_count; | ||
1200 | } | 1241 | } |
1201 | |||
1202 | /* Always open as R/W so we can pass tcs to functions that modify data also | ||
1203 | * without failing. */ | ||
1204 | tcs->masterfd = open_master_fd(&master_hdr, true); | ||
1205 | |||
1206 | if (tcs->masterfd < 0) | ||
1207 | return false; | ||
1208 | } | 1242 | } |
1209 | 1243 | ||
1210 | tcs->valid = true; | 1244 | tcs->valid = true; |
@@ -1272,14 +1306,6 @@ bool tagcache_search_add_clause(struct tagcache_search *tcs, | |||
1272 | return true; | 1306 | return true; |
1273 | } | 1307 | } |
1274 | 1308 | ||
1275 | /* TODO: Remove this mess. */ | ||
1276 | #ifdef HAVE_DIRCACHE | ||
1277 | #define TAG_FILENAME_RAM(tcs) ((tcs->type == tag_filename) \ | ||
1278 | ? ((flag & FLAG_DIRCACHE) && is_dircache_intact()) : 1) | ||
1279 | #else | ||
1280 | #define TAG_FILENAME_RAM(tcs) (tcs->type != tag_filename) | ||
1281 | #endif | ||
1282 | |||
1283 | static bool get_next(struct tagcache_search *tcs) | 1309 | static bool get_next(struct tagcache_search *tcs) |
1284 | { | 1310 | { |
1285 | static char buf[TAG_MAXLEN+32]; | 1311 | static char buf[TAG_MAXLEN+32]; |
@@ -1298,11 +1324,20 @@ static bool get_next(struct tagcache_search *tcs) | |||
1298 | 1324 | ||
1299 | /* Relative fetch. */ | 1325 | /* Relative fetch. */ |
1300 | if (tcs->filter_count > 0 || tcs->clause_count > 0 | 1326 | if (tcs->filter_count > 0 || tcs->clause_count > 0 |
1301 | || TAGCACHE_IS_NUMERIC(tcs->type)) | 1327 | || TAGCACHE_IS_NUMERIC(tcs->type) |
1328 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | ||
1329 | /* We need to retrieve flag status for dircache. */ | ||
1330 | || (tcs->ramsearch && tcs->type == tag_filename) | ||
1331 | #endif | ||
1332 | ) | ||
1302 | { | 1333 | { |
1334 | struct tagcache_seeklist_entry *seeklist; | ||
1335 | |||
1303 | /* Check for end of list. */ | 1336 | /* Check for end of list. */ |
1304 | if (tcs->seek_list_count == 0) | 1337 | if (tcs->list_position == tcs->seek_list_count) |
1305 | { | 1338 | { |
1339 | tcs->list_position = 0; | ||
1340 | |||
1306 | /* Try to fetch more. */ | 1341 | /* Try to fetch more. */ |
1307 | if (!build_lookup_list(tcs)) | 1342 | if (!build_lookup_list(tcs)) |
1308 | { | 1343 | { |
@@ -1311,15 +1346,28 @@ static bool get_next(struct tagcache_search *tcs) | |||
1311 | } | 1346 | } |
1312 | } | 1347 | } |
1313 | 1348 | ||
1314 | tcs->seek_list_count--; | 1349 | seeklist = &tcs->seeklist[tcs->list_position]; |
1315 | flag = tcs->seek_flags[tcs->seek_list_count]; | 1350 | flag = seeklist->flag; |
1316 | tcs->position = tcs->seek_list[tcs->seek_list_count]; | 1351 | tcs->position = seeklist->seek; |
1352 | tcs->idx_id = seeklist->idx_id; | ||
1353 | tcs->list_position++; | ||
1317 | } | 1354 | } |
1355 | else | ||
1356 | { | ||
1357 | if (tcs->entry_count == 0) | ||
1358 | { | ||
1359 | tcs->valid = false; | ||
1360 | return false; | ||
1361 | } | ||
1362 | |||
1363 | tcs->entry_count--; | ||
1364 | } | ||
1365 | |||
1366 | tcs->result_seek = tcs->position; | ||
1318 | 1367 | ||
1319 | if (TAGCACHE_IS_NUMERIC(tcs->type)) | 1368 | if (TAGCACHE_IS_NUMERIC(tcs->type)) |
1320 | { | 1369 | { |
1321 | snprintf(buf, sizeof(buf), "%d", tcs->position); | 1370 | snprintf(buf, sizeof(buf), "%d", tcs->position); |
1322 | tcs->result_seek = tcs->position; | ||
1323 | tcs->result = buf; | 1371 | tcs->result = buf; |
1324 | tcs->result_len = strlen(buf) + 1; | 1372 | tcs->result_len = strlen(buf) + 1; |
1325 | return true; | 1373 | return true; |
@@ -1327,55 +1375,54 @@ static bool get_next(struct tagcache_search *tcs) | |||
1327 | 1375 | ||
1328 | /* Direct fetch. */ | 1376 | /* Direct fetch. */ |
1329 | #ifdef HAVE_TC_RAMCACHE | 1377 | #ifdef HAVE_TC_RAMCACHE |
1330 | if (tcs->ramsearch && TAG_FILENAME_RAM(tcs)) | 1378 | if (tcs->ramsearch) |
1331 | { | 1379 | { |
1332 | struct tagfile_entry *ep; | ||
1333 | |||
1334 | if (tcs->entry_count == 0) | ||
1335 | { | ||
1336 | tcs->valid = false; | ||
1337 | return false; | ||
1338 | } | ||
1339 | tcs->entry_count--; | ||
1340 | 1380 | ||
1341 | tcs->result_seek = tcs->position; | 1381 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) |
1342 | 1382 | if (tcs->type == tag_filename && (flag & FLAG_DIRCACHE) | |
1343 | # ifdef HAVE_DIRCACHE | 1383 | && is_dircache_intact()) |
1344 | if (tcs->type == tag_filename) | ||
1345 | { | 1384 | { |
1346 | dircache_copy_path((struct dirent *)tcs->position, | 1385 | dircache_copy_path((struct dirent *)tcs->position, |
1347 | buf, sizeof buf); | 1386 | buf, sizeof buf); |
1348 | tcs->result = buf; | 1387 | tcs->result = buf; |
1349 | tcs->result_len = strlen(buf) + 1; | 1388 | tcs->result_len = strlen(buf) + 1; |
1350 | tcs->idx_id = FLAG_GET_ATTR(flag); | ||
1351 | tcs->ramresult = false; | 1389 | tcs->ramresult = false; |
1352 | 1390 | ||
1353 | return true; | 1391 | return true; |
1354 | } | 1392 | } |
1355 | # endif | 1393 | else |
1356 | 1394 | #endif | |
1357 | ep = (struct tagfile_entry *)&hdr->tags[tcs->type][tcs->position]; | 1395 | if (tcs->type != tag_filename) |
1358 | tcs->position += sizeof(struct tagfile_entry) + ep->tag_length; | 1396 | { |
1359 | tcs->result = ep->tag_data; | 1397 | struct tagfile_entry *ep; |
1360 | tcs->result_len = strlen(tcs->result) + 1; | 1398 | |
1361 | tcs->idx_id = ep->idx_id; | 1399 | ep = (struct tagfile_entry *)&hdr->tags[tcs->type][tcs->position]; |
1362 | tcs->ramresult = true; | 1400 | tcs->result = ep->tag_data; |
1363 | 1401 | tcs->result_len = strlen(tcs->result) + 1; | |
1364 | return true; | 1402 | tcs->idx_id = ep->idx_id; |
1403 | tcs->ramresult = true; | ||
1404 | |||
1405 | /* Increase position for the next run. This may get overwritten. */ | ||
1406 | tcs->position += sizeof(struct tagfile_entry) + ep->tag_length; | ||
1407 | |||
1408 | return true; | ||
1409 | } | ||
1365 | } | 1410 | } |
1366 | #endif | 1411 | #endif |
1367 | 1412 | ||
1368 | if (!open_files(tcs, tcs->type)) | 1413 | if (!open_files(tcs, tcs->type)) |
1414 | { | ||
1415 | tcs->valid = false; | ||
1369 | return false; | 1416 | return false; |
1417 | } | ||
1370 | 1418 | ||
1371 | /* Seek stream to the correct position and continue to direct fetch. */ | 1419 | /* Seek stream to the correct position and continue to direct fetch. */ |
1372 | lseek(tcs->idxfd[tcs->type], tcs->position, SEEK_SET); | 1420 | lseek(tcs->idxfd[tcs->type], tcs->position, SEEK_SET); |
1373 | tcs->result_seek = tcs->position; | ||
1374 | 1421 | ||
1375 | if (ecread(tcs->idxfd[tcs->type], &entry, 1, | 1422 | if (ecread(tcs->idxfd[tcs->type], &entry, 1, |
1376 | tagfile_entry_ec, tc_stat.econ) != sizeof(struct tagfile_entry)) | 1423 | tagfile_entry_ec, tc_stat.econ) != sizeof(struct tagfile_entry)) |
1377 | { | 1424 | { |
1378 | /* End of data. */ | 1425 | logf("read error #5"); |
1379 | tcs->valid = false; | 1426 | tcs->valid = false; |
1380 | return false; | 1427 | return false; |
1381 | } | 1428 | } |
@@ -1384,6 +1431,7 @@ static bool get_next(struct tagcache_search *tcs) | |||
1384 | { | 1431 | { |
1385 | tcs->valid = false; | 1432 | tcs->valid = false; |
1386 | logf("too long tag #2"); | 1433 | logf("too long tag #2"); |
1434 | logf("P:%X/%X", tcs->position, entry.tag_length); | ||
1387 | return false; | 1435 | return false; |
1388 | } | 1436 | } |
1389 | 1437 | ||
@@ -1536,12 +1584,12 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename) | |||
1536 | struct index_entry *entry; | 1584 | struct index_entry *entry; |
1537 | int idx_id; | 1585 | int idx_id; |
1538 | 1586 | ||
1539 | if (!tc_stat.ready) | 1587 | if (!tc_stat.ready || !tc_stat.ramcache) |
1540 | return false; | 1588 | return false; |
1541 | 1589 | ||
1542 | /* Find the corresponding entry in tagcache. */ | 1590 | /* Find the corresponding entry in tagcache. */ |
1543 | idx_id = find_entry_ram(filename, NULL); | 1591 | idx_id = find_entry_ram(filename, NULL); |
1544 | if (idx_id < 0 || !tc_stat.ramcache) | 1592 | if (idx_id < 0) |
1545 | return false; | 1593 | return false; |
1546 | 1594 | ||
1547 | entry = &hdr->indices[idx_id]; | 1595 | entry = &hdr->indices[idx_id]; |
@@ -1644,14 +1692,11 @@ static void add_tagcache(char *path, unsigned long mtime | |||
1644 | { | 1692 | { |
1645 | idx_id = find_entry_ram(path, dc); | 1693 | idx_id = find_entry_ram(path, dc); |
1646 | } | 1694 | } |
1647 | else | ||
1648 | #endif | 1695 | #endif |
1649 | { | 1696 | |
1650 | if (filenametag_fd >= 0) | 1697 | /* Be sure the entry doesn't exist. */ |
1651 | { | 1698 | if (filenametag_fd >= 0 && idx_id < 0) |
1652 | idx_id = find_entry_disk(path); | 1699 | idx_id = find_entry_disk(path, false); |
1653 | } | ||
1654 | } | ||
1655 | 1700 | ||
1656 | /* Check if file has been modified. */ | 1701 | /* Check if file has been modified. */ |
1657 | if (idx_id >= 0) | 1702 | if (idx_id >= 0) |
@@ -2548,6 +2593,13 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2548 | 2593 | ||
2549 | /* Sort the buffer data and write it to the index file. */ | 2594 | /* Sort the buffer data and write it to the index file. */ |
2550 | lseek(fd, sizeof(struct tagcache_header), SEEK_SET); | 2595 | lseek(fd, sizeof(struct tagcache_header), SEEK_SET); |
2596 | /** | ||
2597 | * We need to truncate the index file now. There can be junk left | ||
2598 | * at the end of file (however, we _should_ always follow the | ||
2599 | * entry_count and don't crash with that). | ||
2600 | */ | ||
2601 | ftruncate(fd, lseek(fd, 0, SEEK_CUR)); | ||
2602 | |||
2551 | i = tempbuf_sort(fd); | 2603 | i = tempbuf_sort(fd); |
2552 | if (i < 0) | 2604 | if (i < 0) |
2553 | goto error_exit; | 2605 | goto error_exit; |
@@ -3328,7 +3380,10 @@ bool tagcache_import_changelog(void) | |||
3328 | close(masterfd); | 3380 | close(masterfd); |
3329 | 3381 | ||
3330 | if (filenametag_fd >= 0) | 3382 | if (filenametag_fd >= 0) |
3383 | { | ||
3331 | close(filenametag_fd); | 3384 | close(filenametag_fd); |
3385 | filenametag_fd = -1; | ||
3386 | } | ||
3332 | 3387 | ||
3333 | write_lock--; | 3388 | write_lock--; |
3334 | 3389 | ||
@@ -3919,7 +3974,6 @@ static bool load_tagcache(void) | |||
3919 | } | 3974 | } |
3920 | 3975 | ||
3921 | idx->flag |= FLAG_DIRCACHE; | 3976 | idx->flag |= FLAG_DIRCACHE; |
3922 | FLAG_SET_ATTR(idx->flag, fe->idx_id); | ||
3923 | idx->tag_seek[tag_filename] = (long)dc; | 3977 | idx->tag_seek[tag_filename] = (long)dc; |
3924 | } | 3978 | } |
3925 | else | 3979 | else |