forked from len0rd/rockbox
FS#7598 - Dircache support for multivolume targets (by Phil Light).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16632 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
afde7f74d4
commit
52d827a26d
6 changed files with 102 additions and 49 deletions
|
@ -380,7 +380,7 @@ Keith Perri
|
|||
Mark Fawcus
|
||||
Ivan Pesic
|
||||
Marcel Barbulescu
|
||||
|
||||
Phil Light
|
||||
|
||||
The libmad team
|
||||
The wavpack team
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "dir.h"
|
||||
#include "debug.h"
|
||||
#include "atoi.h"
|
||||
//#include "dircache.h"
|
||||
|
||||
#define MAX_OPEN_DIRS 8
|
||||
|
||||
|
@ -32,22 +31,9 @@ static DIR_UNCACHED opendirs[MAX_OPEN_DIRS];
|
|||
|
||||
#ifdef HAVE_MULTIVOLUME
|
||||
|
||||
/* how to name volumes, first char must be outside of legal file names,
|
||||
a number gets appended to enumerate, if applicable */
|
||||
#ifdef HAVE_MMC
|
||||
static const char* vol_names = "<MMC%d>";
|
||||
#define VOL_ENUM_POS 4 /* position of %d, to avoid runtime calculation */
|
||||
#elif defined(HAVE_HOTSWAP)
|
||||
static const char* vol_names = "<microSD%d>";
|
||||
#define VOL_ENUM_POS 8 /* position of %d, to avoid runtime calculation */
|
||||
#else
|
||||
static const char* vol_names = "<HD%d>";
|
||||
#define VOL_ENUM_POS 3
|
||||
#endif
|
||||
|
||||
/* returns on which volume this is, and copies the reduced name
|
||||
(sortof a preprocessor for volume-decorated pathnames) */
|
||||
static int strip_volume(const char* name, char* namecopy)
|
||||
int strip_volume(const char* name, char* namecopy)
|
||||
{
|
||||
int volume = 0;
|
||||
const char *temp = name;
|
||||
|
@ -55,7 +41,7 @@ static int strip_volume(const char* name, char* namecopy)
|
|||
while (*temp == '/') /* skip all leading slashes */
|
||||
++temp;
|
||||
|
||||
if (*temp && !strncmp(temp, vol_names, VOL_ENUM_POS))
|
||||
if (*temp && !strncmp(temp, VOL_NAMES, VOL_ENUM_POS))
|
||||
{
|
||||
temp += VOL_ENUM_POS; /* behind special name */
|
||||
volume = atoi(temp); /* number is following */
|
||||
|
@ -199,7 +185,7 @@ struct dirent_uncached* readdir_uncached(DIR_UNCACHED* dir)
|
|||
memset(theent, 0, sizeof(*theent));
|
||||
theent->attribute = FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME;
|
||||
snprintf(theent->d_name, sizeof(theent->d_name),
|
||||
vol_names, dir->volumecounter);
|
||||
VOL_NAMES, dir->volumecounter);
|
||||
return theent;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "usb.h"
|
||||
#include "file.h"
|
||||
#include "buffer.h"
|
||||
#include "dir.h"
|
||||
#if CONFIG_RTC
|
||||
#include "time.h"
|
||||
#include "timefuncs.h"
|
||||
|
@ -51,6 +52,9 @@ DIR_CACHED opendirs[MAX_OPEN_DIRS];
|
|||
|
||||
static struct dircache_entry *fd_bindings[MAX_OPEN_FILES];
|
||||
static struct dircache_entry *dircache_root;
|
||||
#ifdef HAVE_MULTIVOLUME
|
||||
static struct dircache_entry *append_position;
|
||||
#endif
|
||||
|
||||
static bool dircache_initialized = false;
|
||||
static bool dircache_initializing = false;
|
||||
|
@ -155,6 +159,9 @@ static bool check_event_queue(void)
|
|||
{
|
||||
case DIRCACHE_STOP:
|
||||
case SYS_USB_CONNECTED:
|
||||
#ifdef HAVE_HOTSWAP
|
||||
case SYS_FS_CHANGED:
|
||||
#endif
|
||||
/* Put the event back into the queue. */
|
||||
queue_post(&dircache_queue, ev.id, ev.data);
|
||||
return true;
|
||||
|
@ -166,7 +173,7 @@ static bool check_event_queue(void)
|
|||
/**
|
||||
* Internal function to iterate a path.
|
||||
*/
|
||||
static int dircache_scan(struct travel_data *td)
|
||||
static int dircache_scan(IF_MV2(int volume,) struct travel_data *td)
|
||||
{
|
||||
#ifdef SIMULATOR
|
||||
while ( ( td->entry = readdir_uncached(td->dir) ) )
|
||||
|
@ -273,22 +280,37 @@ static int dircache_scan(struct travel_data *td)
|
|||
* Recursively scan the hard disk and build the cache.
|
||||
*/
|
||||
#ifdef SIMULATOR
|
||||
static int dircache_travel(DIR_UNCACHED *dir, struct dircache_entry *ce)
|
||||
static int dircache_travel(IF_MV2(int volume,) DIR_UNCACHED *dir, struct dircache_entry *ce)
|
||||
#else
|
||||
static int dircache_travel(struct fat_dir *dir, struct dircache_entry *ce)
|
||||
static int dircache_travel(IF_MV2(int volume,) struct fat_dir *dir, struct dircache_entry *ce)
|
||||
#endif
|
||||
{
|
||||
int depth = 0;
|
||||
int result;
|
||||
|
||||
memset(ce, 0, sizeof(struct dircache_entry));
|
||||
|
||||
#if defined(HAVE_MULTIVOLUME) && !defined(SIMULATOR)
|
||||
if (volume > 0)
|
||||
{
|
||||
ce->d_name = ((char *)dircache_root+dircache_size);
|
||||
snprintf(ce->d_name, VOL_ENUM_POS + 3, VOL_NAMES, volume);
|
||||
ce->name_len = VOL_ENUM_POS + 3;
|
||||
dircache_size += ce->name_len;
|
||||
ce->attribute = FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME;
|
||||
ce->size = 0;
|
||||
append_position = dircache_gen_next(ce);
|
||||
ce = dircache_gen_down(ce);
|
||||
}
|
||||
#endif
|
||||
|
||||
dir_recursion[0].dir = dir;
|
||||
dir_recursion[0].ce = ce;
|
||||
dir_recursion[0].first = ce;
|
||||
|
||||
do {
|
||||
//logf("=> %s", dircache_cur_path);
|
||||
result = dircache_scan(&dir_recursion[depth]);
|
||||
result = dircache_scan(IF_MV2(volume,) &dir_recursion[depth]);
|
||||
switch (result) {
|
||||
case 0: /* Leaving the current directory. */
|
||||
/* Add the standard . and .. entries. */
|
||||
|
@ -536,7 +558,19 @@ static int dircache_do_rebuild(void)
|
|||
start_tick = current_tick;
|
||||
dircache_initializing = true;
|
||||
appflags = 0;
|
||||
entry_count = 0;
|
||||
|
||||
memset(dircache_cur_path, 0, sizeof(dircache_cur_path));
|
||||
dircache_size = sizeof(struct dircache_entry);
|
||||
|
||||
#ifdef HAVE_MULTIVOLUME
|
||||
append_position = dircache_root;
|
||||
|
||||
for (i = NUM_VOLUMES; i >= 0; i--)
|
||||
{
|
||||
if (fat_ismounted(i))
|
||||
{
|
||||
#endif
|
||||
#ifdef SIMULATOR
|
||||
pdir = opendir_uncached("/");
|
||||
if (pdir == NULL)
|
||||
|
@ -546,19 +580,23 @@ static int dircache_do_rebuild(void)
|
|||
return -3;
|
||||
}
|
||||
#else
|
||||
if ( fat_opendir(IF_MV2(volume,) &dir, 0, NULL) < 0 ) {
|
||||
#ifdef HAVE_MULTIVOLUME
|
||||
if ( fat_opendir(IF_MV2(i,) &dir, 0, NULL) < 0 ) {
|
||||
#else
|
||||
if ( fat_opendir(IF_MV2(0,) &dir, 0, NULL) < 0 ) {
|
||||
#endif /* HAVE_MULTIVOLUME */
|
||||
logf("Failed opening root dir");
|
||||
dircache_initializing = false;
|
||||
return -3;
|
||||
}
|
||||
pdir = &dir;
|
||||
#endif
|
||||
|
||||
memset(dircache_cur_path, 0, sizeof(dircache_cur_path));
|
||||
dircache_size = sizeof(struct dircache_entry);
|
||||
|
||||
cpu_boost(true);
|
||||
if (dircache_travel(pdir, dircache_root) < 0)
|
||||
#ifdef HAVE_MULTIVOLUME
|
||||
if (dircache_travel(IF_MV2(i,) pdir, append_position) < 0)
|
||||
#else
|
||||
if (dircache_travel(IF_MV2(0,) pdir, dircache_root) < 0)
|
||||
#endif /* HAVE_MULTIVOLUME */
|
||||
{
|
||||
logf("dircache_travel failed");
|
||||
cpu_boost(false);
|
||||
|
@ -567,6 +605,10 @@ static int dircache_do_rebuild(void)
|
|||
return -2;
|
||||
}
|
||||
cpu_boost(false);
|
||||
#ifdef HAVE_MULTIVOLUME
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
logf("Done, %ld KiB used", dircache_size / 1024);
|
||||
|
||||
|
@ -610,6 +652,12 @@ static void dircache_thread(void)
|
|||
|
||||
switch (ev.id)
|
||||
{
|
||||
#ifdef HAVE_HOTSWAP
|
||||
case SYS_FS_CHANGED:
|
||||
if (!dircache_initialized)
|
||||
break;
|
||||
dircache_initialized = false;
|
||||
#endif
|
||||
case DIRCACHE_BUILD:
|
||||
thread_enabled = true;
|
||||
dircache_do_rebuild();
|
||||
|
|
|
@ -313,9 +313,7 @@
|
|||
* plenty of RAM. Both features can be enabled independently. */
|
||||
#if ((defined(MEMORYSIZE) && (MEMORYSIZE > 8)) || MEM > 8) && \
|
||||
!defined(BOOTLOADER)
|
||||
#if !defined(SANSA_E200) && !defined(SANSA_C200)
|
||||
#define HAVE_DIRCACHE
|
||||
#endif
|
||||
#ifdef HAVE_TAGCACHE
|
||||
#define HAVE_TC_RAMCACHE
|
||||
#endif
|
||||
|
|
|
@ -22,6 +22,23 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_MULTIVOLUME
|
||||
|
||||
/* how to name volumes, first char must be outside of legal file names,
|
||||
a number gets appended to enumerate, if applicable */
|
||||
#ifdef HAVE_MMC
|
||||
#define VOL_NAMES "<MMC%d>"
|
||||
#define VOL_ENUM_POS 4 /* position of %d, to avoid runtime calculation */
|
||||
#elif defined(HAVE_HOTSWAP)
|
||||
#define VOL_NAMES "<microSD%d>"
|
||||
#define VOL_ENUM_POS 8 /* position of %d, to avoid runtime calculation */
|
||||
#else
|
||||
#define VOL_NAMES "<HD%d>"
|
||||
#define VOL_ENUM_POS 3
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DIRCACHE
|
||||
# include "dircache.h"
|
||||
# define DIR DIR_CACHED
|
||||
|
|
|
@ -75,6 +75,10 @@ typedef struct {
|
|||
char *get_volume_name(int volume);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MULTIVOLUME
|
||||
int strip_volume(const char*, char*);
|
||||
#endif
|
||||
|
||||
#ifndef DIRFUNCTIONS_DEFINED
|
||||
|
||||
extern DIR_UNCACHED* opendir_uncached(const char* name);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue