summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2008-01-13 19:13:37 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2008-01-13 19:13:37 +0000
commit39c597b5e1121b8d07c36934b1569d60f75d02c9 (patch)
tree736a1f24e0bcb10734c0a5a12c3ab5fdfcfc391c
parentfa7eb56c84f2e338ed5ff62dfb79e6bf513ddcdb (diff)
downloadrockbox-39c597b5e1121b8d07c36934b1569d60f75d02c9.tar.gz
rockbox-39c597b5e1121b8d07c36934b1569d60f75d02c9.zip
Always check for deleted files, no matter how slow it might be when DB autoupdate is enabled. Also simplified code a bit. Fixed a crash when search is performaed and dircache has been vanished and DB is still exists ram.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16081 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/tagcache.c52
-rw-r--r--firmware/common/dircache.c20
-rw-r--r--firmware/include/dircache.h5
3 files changed, 51 insertions, 26 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 2b4f1a2181..044fcab6e7 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -299,6 +299,15 @@ bool tagcache_is_sorted_tag(int type)
return false;
}
+/**
+ * Returns true if specified flag is still present, i.e., dircache
+ * has not been reloaded.
+ */
+static bool is_dircache_intact(void)
+{
+ return dircache_get_appflag(DIRCACHE_APPFLAG_TAGCACHE);
+}
+
static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write)
{
int fd;
@@ -531,7 +540,7 @@ static int find_index(const char *filename)
long idx_id = -1;
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
- if (tc_stat.ramcache && dircache_is_enabled())
+ if (tc_stat.ramcache && is_dircache_intact())
idx_id = find_entry_ram(filename, NULL);
#endif
@@ -703,7 +712,8 @@ static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx,
struct tagfile_entry *ep;
# ifdef HAVE_DIRCACHE
- if (tag == tag_filename && idx->flag & FLAG_DIRCACHE)
+ if (tag == tag_filename && (idx->flag & FLAG_DIRCACHE)
+ && is_dircache_intact())
{
dircache_copy_path((struct dirent *)seek,
buf, size);
@@ -1292,7 +1302,7 @@ bool tagcache_search_add_clause(struct tagcache_search *tcs,
}
#define TAG_FILENAME_RAM(tcs) ((tcs->type == tag_filename) \
- ? (flag & FLAG_DIRCACHE) : 1)
+ ? ((flag & FLAG_DIRCACHE) && is_dircache_intact()) : 1)
static bool get_next(struct tagcache_search *tcs)
{
@@ -1657,7 +1667,7 @@ static void add_tagcache(char *path, unsigned long mtime
/* Check if the file is already cached. */
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
- if (tc_stat.ramcache && dircache_is_enabled())
+ if (tc_stat.ramcache && is_dircache_intact())
{
idx_id = find_entry_ram(path, dc);
}
@@ -3776,6 +3786,8 @@ static bool load_tagcache(void)
sleep(1);
# endif
+ dircache_set_appflag(DIRCACHE_APPFLAG_TAGCACHE);
+
logf("loading tagcache to ram...");
fd = open(TAGCACHE_FILE_MASTER, O_RDONLY);
@@ -3931,25 +3943,20 @@ static bool load_tagcache(void)
else
# endif
{
-
- /* Enabled for flash based targets. Too slow otherwise. */
-# ifdef HAVE_FLASH_STORAGE
+ /* This will be very slow unless dircache is enabled
+ or target is flash based, but do it anyway for
+ consistency. */
/* Check if entry has been removed. */
if (global_settings.tagcache_autoupdate)
{
- int testfd;
-
- testfd = open(buf, O_RDONLY);
- if (testfd < 0)
+ if (!file_exists(buf))
{
logf("Entry no longer valid.");
logf("-> %s", buf);
delete_entry(fe->idx_id);
continue;
}
- close(testfd);
}
-# endif
}
continue ;
@@ -3992,7 +3999,7 @@ static bool load_tagcache(void)
static bool check_deleted_files(void)
{
- int fd, testfd;
+ int fd;
char buf[TAG_MAXLEN+32];
struct tagfile_entry tfe;
@@ -4033,14 +4040,12 @@ static bool check_deleted_files(void)
continue;
/* Now check if the file exists. */
- testfd = open(buf, O_RDONLY);
- if (testfd < 0)
+ if (!file_exists(buf))
{
logf("Entry no longer valid.");
logf("-> %s / %d", buf, tfe.tag_length);
delete_entry(tfe.idx_id);
}
- close(testfd);
}
close(fd);
@@ -4336,16 +4341,11 @@ static void tagcache_thread(void)
if (global_settings.tagcache_autoupdate)
{
build_tagcache("/");
- /* Don't do auto removal without dircache or flash
- * storage (very slow). */
-#ifdef HAVE_FLASH_STORAGE
+
+ /* This will be very slow unless dircache is enabled
+ or target is flash based, but do it anyway for
+ consistency. */
check_deleted_files();
-#else
-# ifdef HAVE_DIRCACHE
- if (dircache_is_enabled())
- check_deleted_files();
-# endif
-#endif
}
logf("tagcache check done");
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index 8e9cffb73e..983f0b03cf 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -60,6 +60,7 @@ static unsigned long dircache_size = 0;
static unsigned long entry_count = 0;
static unsigned long reserve_used = 0;
static unsigned int cache_build_ticks = 0;
+static unsigned long appflags = 0;
static char dircache_cur_path[MAX_PATH*2];
static struct event_queue dircache_queue;
@@ -450,6 +451,7 @@ int dircache_load(void)
dircache_root = buffer_alloc(maindata.size + DIRCACHE_RESERVE);
entry_count = maindata.entry_count;
+ appflags = maindata.appflags;
bytes_read = read(fd, dircache_root, MIN(DIRCACHE_LIMIT, maindata.size));
close(fd);
remove(DIRCACHE_FILE);
@@ -493,6 +495,7 @@ int dircache_save(void)
maindata.size = dircache_size;
maindata.root_entry = dircache_root;
maindata.entry_count = entry_count;
+ maindata.appflags = appflags;
/* Save the info structure */
bytes_written = write(fd, &maindata, sizeof(struct dircache_maindata));
@@ -532,6 +535,7 @@ static int dircache_do_rebuild(void)
/* Measure how long it takes build the cache. */
start_tick = current_tick;
dircache_initializing = true;
+ appflags = 0;
#ifdef SIMULATOR
pdir = opendir_uncached("/");
@@ -723,6 +727,22 @@ bool dircache_is_initializing(void)
}
/**
+ * Set application flags used to determine if dircache is still intact.
+ */
+void dircache_set_appflag(long mask)
+{
+ appflags |= mask;
+}
+
+/**
+ * Get application flags used to determine if dircache is still intact.
+ */
+bool dircache_get_appflag(long mask)
+{
+ return appflags & mask;
+}
+
+/**
* Returns the current number of entries (directories and files) in the cache.
*/
int dircache_get_entry_count(void)
diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h
index 7d2111697c..a703d0be41 100644
--- a/firmware/include/dircache.h
+++ b/firmware/include/dircache.h
@@ -28,6 +28,8 @@
/* FIXME: We should use ROCKBOX_DIR here but it's defined in apps/ */
#define DIRCACHE_FILE "/.rockbox/dircache.dat"
+#define DIRCACHE_APPFLAG_TAGCACHE 0x0001
+
/* Internal structures. */
struct travel_data {
struct dircache_entry *first;
@@ -49,6 +51,7 @@ struct dircache_maindata {
long magic;
long size;
long entry_count;
+ long appflags;
struct dircache_entry *root_entry;
};
@@ -87,6 +90,8 @@ int dircache_build(int last_size);
void* dircache_steal_buffer(long *size);
bool dircache_is_enabled(void);
bool dircache_is_initializing(void);
+void dircache_set_appflag(long mask);
+bool dircache_get_appflag(long mask);
int dircache_get_entry_count(void);
int dircache_get_cache_size(void);
int dircache_get_reserve_used(void);