summaryrefslogtreecommitdiff
path: root/firmware/common
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2011-06-20 20:12:42 +0000
committerThomas Martitz <kugel@rockbox.org>2011-06-20 20:12:42 +0000
commitaf7aaae478b5c7382ae5505abab233a97aa3e658 (patch)
tree566d2e728aefb9f0e6b19edfd3519bf2826339e3 /firmware/common
parent0b9c57d33e59a26b1f341632b990aff0dffd0fcb (diff)
downloadrockbox-af7aaae478b5c7382ae5505abab233a97aa3e658.tar.gz
rockbox-af7aaae478b5c7382ae5505abab233a97aa3e658.zip
Dircache: Don't expose struct dircache_entry and pointers into the cache, use IDs instead.
Only integer IDs are exposed from dircache with this. This way the cache is isolated from other modules. This is needed for my buflib gsoc project. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30038 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/common')
-rw-r--r--firmware/common/dircache.c73
-rw-r--r--firmware/common/file.c13
-rw-r--r--firmware/common/filefuncs.c2
3 files changed, 67 insertions, 21 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index 0f3c453ee7..bff9c2f4e7 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -57,7 +57,23 @@
57#else 57#else
58#define MAX_OPEN_DIRS 8 58#define MAX_OPEN_DIRS 8
59#endif 59#endif
60static DIR_CACHED opendirs[MAX_OPEN_DIRS]; 60
61#define MAX_PENDING_BINDINGS 2
62struct fdbind_queue {
63 char path[MAX_PATH];
64 int fd;
65};
66
67/* Exported structures. */
68struct dircache_entry {
69 struct dirinfo info;
70 struct dircache_entry *next;
71 struct dircache_entry *up;
72 struct dircache_entry *down;
73 long startcluster;
74 char *d_name;
75};
76
61/* Cache Layout: 77/* Cache Layout:
62 * 78 *
63 * x - array of struct dircache_entry 79 * x - array of struct dircache_entry
@@ -75,7 +91,6 @@ static DIR_CACHED opendirs[MAX_OPEN_DIRS];
75 * total allocation size grows 91 * total allocation size grows
76 * |xxxxxxxx|rrrrrrrrr|dddddddd| 92 * |xxxxxxxx|rrrrrrrrr|dddddddd|
77 */ 93 */
78static struct dircache_entry *fd_bindings[MAX_OPEN_FILES];
79/* this points to the beginnging of the buffer and the first entry */ 94/* this points to the beginnging of the buffer and the first entry */
80static struct dircache_entry *dircache_root; 95static struct dircache_entry *dircache_root;
81/* these point to the start and end of the name buffer (d above) */ 96/* these point to the start and end of the name buffer (d above) */
@@ -86,6 +101,9 @@ static char *dot, *dotdot;
86static struct dircache_entry *append_position; 101static struct dircache_entry *append_position;
87#endif 102#endif
88 103
104static DIR_CACHED opendirs[MAX_OPEN_DIRS];
105static struct dircache_entry *fd_bindings[MAX_OPEN_FILES];
106
89static bool dircache_initialized = false; 107static bool dircache_initialized = false;
90static bool dircache_initializing = false; 108static bool dircache_initializing = false;
91static bool thread_enabled = false; 109static bool thread_enabled = false;
@@ -105,6 +123,11 @@ static int fdbind_idx = 0;
105 123
106/* --- Internal cache structure control functions --- */ 124/* --- Internal cache structure control functions --- */
107 125
126static inline struct dircache_entry* get_entry(int id)
127{
128 return &dircache_root[id];
129}
130
108#ifdef HAVE_EEPROM_SETTINGS 131#ifdef HAVE_EEPROM_SETTINGS
109/** 132/**
110 * Open the dircache file to save a snapshot on disk 133 * Open the dircache file to save a snapshot on disk
@@ -1012,14 +1035,36 @@ void dircache_disable(void)
1012} 1035}
1013 1036
1014/** 1037/**
1015 * Usermode function to return dircache_entry pointer to the given path. 1038 * Usermode function to return dircache_entry index to the given path.
1016 */ 1039 */
1017const struct dircache_entry *dircache_get_entry_ptr(const char *filename) 1040static int dircache_get_entry_id_ex(const char *filename, bool go_down)
1018{ 1041{
1019 if (!dircache_initialized || filename == NULL) 1042 if (!dircache_initialized || filename == NULL)
1020 return NULL; 1043 return -1;
1021 1044
1022 return dircache_get_entry(filename, false); 1045 struct dircache_entry* res = dircache_get_entry(filename, go_down);
1046 return res ? res - dircache_root : -1;
1047}
1048
1049int dircache_get_entry_id(const char* filename)
1050{
1051 return dircache_get_entry_id_ex(filename, false);
1052}
1053
1054/**
1055 * Internal: Get the startcluster for the index
1056 */
1057long _dircache_get_entry_startcluster(int id)
1058{
1059 return get_entry(id)->startcluster;
1060}
1061
1062/**
1063 * Internal: Get the struct dirinfo for the index
1064 */
1065struct dirinfo* _dircache_get_entry_dirinfo(int id)
1066{
1067 return &get_entry(id)->info;
1023} 1068}
1024 1069
1025/* 1070/*
@@ -1050,13 +1095,13 @@ static size_t copy_path_helper(const struct dircache_entry *entry, char *buf, si
1050 * 1095 *
1051 * Returns the size of the resulting string, or 0 if an error occured 1096 * Returns the size of the resulting string, or 0 if an error occured
1052 */ 1097 */
1053size_t dircache_copy_path(const struct dircache_entry *entry, char *buf, size_t size) 1098size_t dircache_copy_path(int index, char *buf, size_t size)
1054{ 1099{
1055 if (!size || !buf) 1100 if (!size || !buf || index < 0)
1056 return 0; 1101 return 0;
1057 1102
1058 buf[0] = '/'; 1103 buf[0] = '/';
1059 size_t res = copy_path_helper(entry, buf, size); 1104 size_t res = copy_path_helper(&dircache_root[index], buf, size);
1060 /* fixup trailing '/' */ 1105 /* fixup trailing '/' */
1061 buf[res] = '\0'; 1106 buf[res] = '\0';
1062 return res; 1107 return res;
@@ -1373,17 +1418,17 @@ DIR_CACHED* opendir_cached(const char* name)
1373 1418
1374 if (!dircache_initialized || is_disable_msg_pending()) 1419 if (!dircache_initialized || is_disable_msg_pending())
1375 { 1420 {
1376 pdir->internal_entry = NULL; 1421 pdir->internal_entry = -1;
1377 pdir->regulardir = opendir_uncached(name); 1422 pdir->regulardir = opendir_uncached(name);
1378 } 1423 }
1379 else 1424 else
1380 { 1425 {
1381 pdir->regulardir = NULL; 1426 pdir->regulardir = NULL;
1382 pdir->internal_entry = dircache_get_entry(name, true); 1427 pdir->internal_entry = dircache_get_entry_id_ex(name, true);
1383 pdir->theent.info.attribute = -1; /* used to make readdir_cached aware of the first call */ 1428 pdir->theent.info.attribute = -1; /* used to make readdir_cached aware of the first call */
1384 } 1429 }
1385 1430
1386 if (pdir->internal_entry == NULL && pdir->regulardir == NULL) 1431 if (pdir->internal_entry == -1 && pdir->regulardir == NULL)
1387 { 1432 {
1388 pdir->busy = false; 1433 pdir->busy = false;
1389 return NULL; 1434 return NULL;
@@ -1394,7 +1439,7 @@ DIR_CACHED* opendir_cached(const char* name)
1394 1439
1395struct dirent_cached* readdir_cached(DIR_CACHED* dir) 1440struct dirent_cached* readdir_cached(DIR_CACHED* dir)
1396{ 1441{
1397 struct dircache_entry *ce = dir->internal_entry; 1442 struct dircache_entry *ce = get_entry(dir->internal_entry);
1398 struct dirent_uncached *regentry; 1443 struct dirent_uncached *regentry;
1399 1444
1400 if (!dir->busy) 1445 if (!dir->busy)
@@ -1430,7 +1475,7 @@ struct dirent_cached* readdir_cached(DIR_CACHED* dir)
1430 because that modifies the d_name pointer. */ 1475 because that modifies the d_name pointer. */
1431 dir->theent.startcluster = ce->startcluster; 1476 dir->theent.startcluster = ce->startcluster;
1432 dir->theent.info = ce->info; 1477 dir->theent.info = ce->info;
1433 dir->internal_entry = ce; 1478 dir->internal_entry = ce - dircache_root;
1434 1479
1435 //logf("-> %s", ce->d_name); 1480 //logf("-> %s", ce->d_name);
1436 return &dir->theent; 1481 return &dir->theent;
diff --git a/firmware/common/file.c b/firmware/common/file.c
index 8f6bfa051b..cfebd0622f 100644
--- a/firmware/common/file.c
+++ b/firmware/common/file.c
@@ -108,25 +108,26 @@ static int open_internal(const char* pathname, int flags, bool use_cache)
108#ifdef HAVE_DIRCACHE 108#ifdef HAVE_DIRCACHE
109 if (dircache_is_enabled() && !file->write && use_cache) 109 if (dircache_is_enabled() && !file->write && use_cache)
110 { 110 {
111 const struct dircache_entry *ce;
112# ifdef HAVE_MULTIVOLUME 111# ifdef HAVE_MULTIVOLUME
113 int volume = strip_volume(pathname, pathnamecopy); 112 int volume = strip_volume(pathname, pathnamecopy);
114# endif 113# endif
115 114
116 ce = dircache_get_entry_ptr(pathname); 115 int ce = dircache_get_entry_id(pathname);
117 if (!ce) 116 if (ce < 0)
118 { 117 {
119 errno = ENOENT; 118 errno = ENOENT;
120 file->busy = false; 119 file->busy = false;
121 return -7; 120 return -7;
122 } 121 }
123 122
123 long startcluster = _dircache_get_entry_startcluster(ce);
124 fat_open(IF_MV2(volume,) 124 fat_open(IF_MV2(volume,)
125 ce->startcluster, 125 startcluster,
126 &(file->fatfile), 126 &(file->fatfile),
127 NULL); 127 NULL);
128 file->size = ce->info.size; 128 struct dirinfo *info = _dircache_get_entry_dirinfo(ce);
129 file->attr = ce->info.attribute; 129 file->size = info->size;
130 file->attr = info->attribute;
130 file->cacheoffset = -1; 131 file->cacheoffset = -1;
131 file->fileoffset = 0; 132 file->fileoffset = 0;
132 133
diff --git a/firmware/common/filefuncs.c b/firmware/common/filefuncs.c
index 6eb2bafa40..fd33f3c6f9 100644
--- a/firmware/common/filefuncs.c
+++ b/firmware/common/filefuncs.c
@@ -70,7 +70,7 @@ bool file_exists(const char *file)
70 70
71#ifdef HAVE_DIRCACHE 71#ifdef HAVE_DIRCACHE
72 if (dircache_is_enabled()) 72 if (dircache_is_enabled())
73 return (dircache_get_entry_ptr(file) != NULL); 73 return (dircache_get_entry_id(file) >= 0);
74#endif 74#endif
75 75
76 fd = open(file, O_RDONLY); 76 fd = open(file, O_RDONLY);