Better header checking. Only manually remove incorrect entries. Fixed
a bug and performance issue with find entry from disk by filename. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10291 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
b34c8fcaf2
commit
29fa15f521
1 changed files with 95 additions and 92 deletions
187
apps/tagcache.c
187
apps/tagcache.c
|
@ -211,6 +211,37 @@ bool tagcache_is_sorted_tag(int type)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
|
||||||
|
if (tagcache_is_numeric_tag(tag) || tag < 0 || tag >= TAG_COUNT)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag);
|
||||||
|
|
||||||
|
fd = open(buf, write ? O_RDWR : O_RDONLY);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
logf("tag file open failed: %d", tag);
|
||||||
|
stat.ready = false;
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the header. */
|
||||||
|
read(fd, hdr, sizeof(struct tagcache_header));
|
||||||
|
if (hdr->magic != TAGCACHE_MAGIC)
|
||||||
|
{
|
||||||
|
logf("header error");
|
||||||
|
stat.ready = false;
|
||||||
|
close(fd);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
|
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
|
||||||
static long find_entry_ram(const char *filename,
|
static long find_entry_ram(const char *filename,
|
||||||
const struct dircache_entry *dc)
|
const struct dircache_entry *dc)
|
||||||
|
@ -266,6 +297,7 @@ static long find_entry_ram(const char *filename,
|
||||||
|
|
||||||
static long find_entry_disk(const char *filename)
|
static long find_entry_disk(const char *filename)
|
||||||
{
|
{
|
||||||
|
struct tagcache_header tch;
|
||||||
static long last_pos = -1;
|
static long last_pos = -1;
|
||||||
long pos_history[POS_HISTORY_COUNT];
|
long pos_history[POS_HISTORY_COUNT];
|
||||||
long pos_history_idx = 0;
|
long pos_history_idx = 0;
|
||||||
|
@ -276,11 +308,14 @@ static long find_entry_disk(const char *filename)
|
||||||
int i;
|
int i;
|
||||||
int pos = -1;
|
int pos = -1;
|
||||||
|
|
||||||
|
if (!stat.ready)
|
||||||
|
return -2;
|
||||||
|
|
||||||
fd = filenametag_fd;
|
fd = filenametag_fd;
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
last_pos = -1;
|
last_pos = -1;
|
||||||
if ( (fd = open(TAGCACHE_FILE_MASTER, O_RDONLY)) < 0)
|
if ( (fd = open_tag_fd(&tch, tag_filename, false)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,8 +323,6 @@ static long find_entry_disk(const char *filename)
|
||||||
|
|
||||||
if (last_pos > 0)
|
if (last_pos > 0)
|
||||||
lseek(fd, last_pos, SEEK_SET);
|
lseek(fd, last_pos, SEEK_SET);
|
||||||
else
|
|
||||||
lseek(fd, sizeof(struct master_header), SEEK_SET);
|
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -374,6 +407,9 @@ bool tagcache_find_index(struct tagcache_search *tcs, const char *filename)
|
||||||
{
|
{
|
||||||
int idx_id;
|
int idx_id;
|
||||||
|
|
||||||
|
if (!stat.ready)
|
||||||
|
return false;
|
||||||
|
|
||||||
idx_id = find_index(filename);
|
idx_id = find_index(filename);
|
||||||
if (idx_id < 0)
|
if (idx_id < 0)
|
||||||
return false;
|
return false;
|
||||||
|
@ -444,6 +480,9 @@ long tagcache_get_numeric(const struct tagcache_search *tcs, int tag)
|
||||||
{
|
{
|
||||||
struct index_entry idx;
|
struct index_entry idx;
|
||||||
|
|
||||||
|
if (!stat.ready)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!tagcache_is_numeric_tag(tag))
|
if (!tagcache_is_numeric_tag(tag))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -672,6 +711,7 @@ static void remove_files(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int open_master_fd(struct master_header *hdr, bool write)
|
static int open_master_fd(struct master_header *hdr, bool write)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -691,7 +731,6 @@ static int open_master_fd(struct master_header *hdr, bool write)
|
||||||
logf("header error");
|
logf("header error");
|
||||||
stat.ready = false;
|
stat.ready = false;
|
||||||
close(fd);
|
close(fd);
|
||||||
remove_files();
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -702,7 +741,6 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
|
||||||
{
|
{
|
||||||
struct tagcache_header tag_hdr;
|
struct tagcache_header tag_hdr;
|
||||||
struct master_header master_hdr;
|
struct master_header master_hdr;
|
||||||
char buf[MAX_PATH];
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (tcs->valid)
|
if (tcs->valid)
|
||||||
|
@ -737,22 +775,10 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
|
||||||
if (tagcache_is_numeric_tag(tcs->type))
|
if (tagcache_is_numeric_tag(tcs->type))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tcs->type);
|
tcs->idxfd[tcs->type] = open_tag_fd(&tag_hdr, tcs->type, false);
|
||||||
tcs->idxfd[tcs->type] = open(buf, O_RDONLY);
|
|
||||||
if (tcs->idxfd[tcs->type] < 0)
|
if (tcs->idxfd[tcs->type] < 0)
|
||||||
{
|
|
||||||
logf("failed to open index");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the header. */
|
|
||||||
if (read(tcs->idxfd[tcs->type], &tag_hdr, sizeof(struct tagcache_header)) !=
|
|
||||||
sizeof(struct tagcache_header) || tag_hdr.magic != TAGCACHE_MAGIC)
|
|
||||||
{
|
|
||||||
logf("incorrect header");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
tcs->masterfd = open_master_fd(&master_hdr, false);
|
tcs->masterfd = open_master_fd(&master_hdr, false);
|
||||||
|
|
||||||
if (tcs->masterfd < 0)
|
if (tcs->masterfd < 0)
|
||||||
|
@ -829,7 +855,7 @@ static bool get_next(struct tagcache_search *tcs)
|
||||||
static char buf[MAX_PATH];
|
static char buf[MAX_PATH];
|
||||||
struct tagfile_entry entry;
|
struct tagfile_entry entry;
|
||||||
|
|
||||||
if (!tcs->valid)
|
if (!tcs->valid || !stat.ready)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (tcs->idxfd[tcs->type] < 0 && !tagcache_is_numeric_tag(tcs->type)
|
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)
|
||||||
struct index_entry *entry;
|
struct index_entry *entry;
|
||||||
int idx_id;
|
int idx_id;
|
||||||
|
|
||||||
|
if (!stat.ready)
|
||||||
|
return false;
|
||||||
|
|
||||||
/* Find the corresponding entry in tagcache. */
|
/* Find the corresponding entry in tagcache. */
|
||||||
idx_id = find_entry_ram(filename, NULL);
|
idx_id = find_entry_ram(filename, NULL);
|
||||||
if (idx_id < 0 || !stat.ramcache)
|
if (idx_id < 0 || !stat.ramcache)
|
||||||
|
@ -1156,8 +1185,11 @@ static void add_tagcache(const char *path)
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (find_entry_disk(path) >= 0)
|
if (filenametag_fd >= 0)
|
||||||
return ;
|
{
|
||||||
|
if (find_entry_disk(path) >= 0)
|
||||||
|
return ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = open(path, O_RDONLY);
|
fd = open(path, O_RDONLY);
|
||||||
|
@ -1563,20 +1595,10 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
|
||||||
memset(lookup, 0, LOOKUP_BUF_DEPTH * sizeof(void **));
|
memset(lookup, 0, LOOKUP_BUF_DEPTH * sizeof(void **));
|
||||||
|
|
||||||
/* Open the index file, which contains the tag names. */
|
/* Open the index file, which contains the tag names. */
|
||||||
snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, index_type);
|
fd = open_tag_fd(&tch, index_type, true);
|
||||||
fd = open(buf, O_RDWR);
|
|
||||||
|
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
{
|
{
|
||||||
/* Read the header. */
|
|
||||||
if (read(fd, &tch, sizeof(struct tagcache_header)) !=
|
|
||||||
sizeof(struct tagcache_header) || tch.magic != TAGCACHE_MAGIC)
|
|
||||||
{
|
|
||||||
logf("header error");
|
|
||||||
close(fd);
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If tag file contains unique tags (sorted index), we will load
|
* If tag file contains unique tags (sorted index), we will load
|
||||||
* it entirely into memory so we can resort it later for use with
|
* it entirely into memory so we can resort it later for use with
|
||||||
|
@ -1991,7 +2013,6 @@ static bool commit(void)
|
||||||
{
|
{
|
||||||
logf("incorrect header");
|
logf("incorrect header");
|
||||||
close(tmpfd);
|
close(tmpfd);
|
||||||
remove_files();
|
|
||||||
remove(TAGCACHE_FILE_TEMP);
|
remove(TAGCACHE_FILE_TEMP);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2159,6 +2180,9 @@ static bool update_current_serial(long serial)
|
||||||
|
|
||||||
long tagcache_increase_serial(void)
|
long tagcache_increase_serial(void)
|
||||||
{
|
{
|
||||||
|
if (!stat.ready)
|
||||||
|
return -2;
|
||||||
|
|
||||||
if (!update_current_serial(current_serial + 1))
|
if (!update_current_serial(current_serial + 1))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -2174,6 +2198,9 @@ static bool modify_numeric_entry(int masterfd, int idx_id, int tag, long data)
|
||||||
{
|
{
|
||||||
struct index_entry idx;
|
struct index_entry idx;
|
||||||
|
|
||||||
|
if (!stat.ready)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!tagcache_is_numeric_tag(tag))
|
if (!tagcache_is_numeric_tag(tag))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -2378,6 +2405,9 @@ bool tagcache_import_changelog(void)
|
||||||
char buf[512];
|
char buf[512];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
|
if (!stat.ready)
|
||||||
|
return false;
|
||||||
|
|
||||||
clfd = open(TAGCACHE_FILE_CHANGELOG, O_RDONLY);
|
clfd = open(TAGCACHE_FILE_CHANGELOG, O_RDONLY);
|
||||||
if (clfd < 0)
|
if (clfd < 0)
|
||||||
{
|
{
|
||||||
|
@ -2444,6 +2474,9 @@ bool tagcache_create_changelog(struct tagcache_search *tcs)
|
||||||
int clfd;
|
int clfd;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
|
if (!stat.ready)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!tagcache_search(tcs, tag_filename))
|
if (!tagcache_search(tcs, tag_filename))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -2621,33 +2654,19 @@ static bool delete_entry(long idx_id)
|
||||||
#ifdef HAVE_TC_RAMCACHE
|
#ifdef HAVE_TC_RAMCACHE
|
||||||
static bool allocate_tagcache(void)
|
static bool allocate_tagcache(void)
|
||||||
{
|
{
|
||||||
int rc, len;
|
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
hdr = NULL;
|
|
||||||
|
|
||||||
fd = open(TAGCACHE_FILE_MASTER, O_RDONLY);
|
|
||||||
if (fd < 0)
|
|
||||||
{
|
|
||||||
logf("no tagcache file found.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load the header. */
|
/* Load the header. */
|
||||||
hdr = (struct ramcache_header *)(((long)audiobuf & ~0x03) + 0x04);
|
hdr = (struct ramcache_header *)(((long)audiobuf & ~0x03) + 0x04);
|
||||||
memset(hdr, 0, sizeof(struct ramcache_header));
|
memset(hdr, 0, sizeof(struct ramcache_header));
|
||||||
len = sizeof(struct master_header);
|
if ( (fd = open_master_fd(&hdr->h, false)) < 0)
|
||||||
rc = read(fd, &hdr->h, len);
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
if (hdr->h.tch.magic != TAGCACHE_MAGIC || rc != len)
|
|
||||||
{
|
{
|
||||||
logf("incorrect header");
|
|
||||||
remove_files();
|
|
||||||
hdr = NULL;
|
hdr = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
hdr->indices = (struct index_entry *)(hdr + 1);
|
hdr->indices = (struct index_entry *)(hdr + 1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2734,26 +2753,12 @@ static bool load_tagcache(void)
|
||||||
p = (char *)((long)p & ~0x03) + 0x04;
|
p = (char *)((long)p & ~0x03) + 0x04;
|
||||||
hdr->tags[tag] = p;
|
hdr->tags[tag] = p;
|
||||||
|
|
||||||
snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag);
|
|
||||||
fd = open(buf, O_RDONLY);
|
|
||||||
|
|
||||||
if (fd < 0)
|
|
||||||
{
|
|
||||||
logf("%s open fail", buf);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the header. */
|
/* Check the header. */
|
||||||
tch = (struct tagcache_header *)p;
|
tch = (struct tagcache_header *)p;
|
||||||
rc = read(fd, tch, sizeof(struct tagcache_header));
|
p += sizeof(struct tagcache_header);
|
||||||
p += rc;
|
|
||||||
if (rc != sizeof(struct tagcache_header) ||
|
if ( (fd = open_tag_fd(tch, tag, false)) < 0)
|
||||||
tch->magic != TAGCACHE_MAGIC)
|
|
||||||
{
|
|
||||||
logf("incorrect header");
|
|
||||||
close(fd);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
for (hdr->entry_count[tag] = 0;
|
for (hdr->entry_count[tag] = 0;
|
||||||
hdr->entry_count[tag] < tch->entry_count;
|
hdr->entry_count[tag] < tch->entry_count;
|
||||||
|
@ -3004,7 +3009,6 @@ static void build_tagcache(void)
|
||||||
{
|
{
|
||||||
struct tagcache_header header;
|
struct tagcache_header header;
|
||||||
bool ret;
|
bool ret;
|
||||||
char buf[MAX_PATH];
|
|
||||||
|
|
||||||
curpath[0] = '\0';
|
curpath[0] = '\0';
|
||||||
data_size = 0;
|
data_size = 0;
|
||||||
|
@ -3028,21 +3032,8 @@ static void build_tagcache(void)
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag_filename);
|
filenametag_fd = open_tag_fd(&header, tag_filename, false);
|
||||||
filenametag_fd = open(buf, O_RDONLY);
|
|
||||||
|
|
||||||
if (filenametag_fd >= 0)
|
|
||||||
{
|
|
||||||
if (read(filenametag_fd, &header, sizeof(struct tagcache_header)) !=
|
|
||||||
sizeof(struct tagcache_header) || header.magic != TAGCACHE_MAGIC)
|
|
||||||
{
|
|
||||||
logf("header error");
|
|
||||||
close(filenametag_fd);
|
|
||||||
filenametag_fd = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cpu_boost(true);
|
cpu_boost(true);
|
||||||
|
|
||||||
/* Scan for new files. */
|
/* Scan for new files. */
|
||||||
|
@ -3095,18 +3086,17 @@ static void load_ramcache(void)
|
||||||
stat.ramcache = load_tagcache();
|
stat.ramcache = load_tagcache();
|
||||||
|
|
||||||
if (!stat.ramcache)
|
if (!stat.ramcache)
|
||||||
{
|
|
||||||
hdr = NULL;
|
hdr = NULL;
|
||||||
remove_files();
|
|
||||||
}
|
|
||||||
|
|
||||||
cpu_boost(false);
|
cpu_boost(false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool check_master_fd(void)
|
static bool check_all_headers(void)
|
||||||
{
|
{
|
||||||
struct master_header myhdr;
|
struct master_header myhdr;
|
||||||
|
struct tagcache_header tch;
|
||||||
|
int tag;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if ( (fd = open_master_fd(&myhdr, false)) < 0)
|
if ( (fd = open_master_fd(&myhdr, false)) < 0)
|
||||||
|
@ -3115,6 +3105,17 @@ static bool check_master_fd(void)
|
||||||
close(fd);
|
close(fd);
|
||||||
current_serial = myhdr.serial;
|
current_serial = myhdr.serial;
|
||||||
|
|
||||||
|
for (tag = 0; tag < TAG_COUNT; tag++)
|
||||||
|
{
|
||||||
|
if (tagcache_is_numeric_tag(tag))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( (fd = open_tag_fd(&tch, tag, false)) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3137,11 +3138,13 @@ static void tagcache_thread(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cpu_boost(false);
|
cpu_boost(false);
|
||||||
|
|
||||||
stat.ready = check_master_fd();
|
|
||||||
|
|
||||||
stat.initialized = true;
|
stat.initialized = true;
|
||||||
|
|
||||||
|
/* Don't delay bootup with the header check but do it on background. */
|
||||||
|
sleep(HZ);
|
||||||
|
stat.ready = check_all_headers();
|
||||||
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
queue_wait_w_tmo(&tagcache_queue, &ev, HZ);
|
queue_wait_w_tmo(&tagcache_queue, &ev, HZ);
|
||||||
|
@ -3163,7 +3166,7 @@ static void tagcache_thread(void)
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
case SYS_TIMEOUT:
|
case SYS_TIMEOUT:
|
||||||
if (check_done)
|
if (check_done || !stat.ready)
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
#ifdef HAVE_TC_RAMCACHE
|
#ifdef HAVE_TC_RAMCACHE
|
||||||
|
|
Loading…
Reference in a new issue