diff options
-rw-r--r-- | apps/playlist.c | 19 | ||||
-rw-r--r-- | apps/playlist.h | 2 | ||||
-rw-r--r-- | apps/tagcache.c | 57 | ||||
-rw-r--r-- | firmware/common/dircache.c | 73 | ||||
-rw-r--r-- | firmware/common/file.c | 13 | ||||
-rw-r--r-- | firmware/common/filefuncs.c | 2 | ||||
-rw-r--r-- | firmware/include/dircache.h | 26 | ||||
-rw-r--r-- | uisimulator/common/io.c | 7 |
8 files changed, 104 insertions, 95 deletions
diff --git a/apps/playlist.c b/apps/playlist.c index dcf2fe1118..ea183d7552 100644 --- a/apps/playlist.c +++ b/apps/playlist.c | |||
@@ -575,7 +575,7 @@ static int add_indices_to_playlist(struct playlist_info* playlist, | |||
575 | playlist->indices[ playlist->amount ] = i+count; | 575 | playlist->indices[ playlist->amount ] = i+count; |
576 | #ifdef HAVE_DIRCACHE | 576 | #ifdef HAVE_DIRCACHE |
577 | if (playlist->filenames) | 577 | if (playlist->filenames) |
578 | playlist->filenames[ playlist->amount ] = NULL; | 578 | playlist->filenames[ playlist->amount ] = -1; |
579 | #endif | 579 | #endif |
580 | playlist->amount++; | 580 | playlist->amount++; |
581 | } | 581 | } |
@@ -816,7 +816,7 @@ static int add_track_to_playlist(struct playlist_info* playlist, | |||
816 | 816 | ||
817 | #ifdef HAVE_DIRCACHE | 817 | #ifdef HAVE_DIRCACHE |
818 | if (playlist->filenames) | 818 | if (playlist->filenames) |
819 | playlist->filenames[insert_position] = NULL; | 819 | playlist->filenames[insert_position] = -1; |
820 | #endif | 820 | #endif |
821 | 821 | ||
822 | playlist->amount++; | 822 | playlist->amount++; |
@@ -958,9 +958,9 @@ static int randomise_playlist(struct playlist_info* playlist, | |||
958 | #ifdef HAVE_DIRCACHE | 958 | #ifdef HAVE_DIRCACHE |
959 | if (playlist->filenames) | 959 | if (playlist->filenames) |
960 | { | 960 | { |
961 | store = (long)playlist->filenames[candidate]; | 961 | store = playlist->filenames[candidate]; |
962 | playlist->filenames[candidate] = playlist->filenames[count]; | 962 | playlist->filenames[candidate] = playlist->filenames[count]; |
963 | playlist->filenames[count] = (struct dircache_entry *)store; | 963 | playlist->filenames[count] = store; |
964 | } | 964 | } |
965 | #endif | 965 | #endif |
966 | } | 966 | } |
@@ -1298,7 +1298,7 @@ static void playlist_thread(void) | |||
1298 | && queue_empty(&playlist_queue); index++) | 1298 | && queue_empty(&playlist_queue); index++) |
1299 | { | 1299 | { |
1300 | /* Process only pointers that are not already loaded. */ | 1300 | /* Process only pointers that are not already loaded. */ |
1301 | if (playlist->filenames[index]) | 1301 | if (playlist->filenames[index] >= 0) |
1302 | continue ; | 1302 | continue ; |
1303 | 1303 | ||
1304 | control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK; | 1304 | control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK; |
@@ -1310,7 +1310,7 @@ static void playlist_thread(void) | |||
1310 | break ; | 1310 | break ; |
1311 | 1311 | ||
1312 | /* Set the dircache entry pointer. */ | 1312 | /* Set the dircache entry pointer. */ |
1313 | playlist->filenames[index] = dircache_get_entry_ptr(tmp); | 1313 | playlist->filenames[index] = dircache_get_entry_id(tmp); |
1314 | 1314 | ||
1315 | /* And be on background so user doesn't notice any delays. */ | 1315 | /* And be on background so user doesn't notice any delays. */ |
1316 | yield(); | 1316 | yield(); |
@@ -1351,7 +1351,7 @@ static int get_filename(struct playlist_info* playlist, int index, int seek, | |||
1351 | #ifdef HAVE_DIRCACHE | 1351 | #ifdef HAVE_DIRCACHE |
1352 | if (dircache_is_enabled() && playlist->filenames) | 1352 | if (dircache_is_enabled() && playlist->filenames) |
1353 | { | 1353 | { |
1354 | if (playlist->filenames[index] != NULL) | 1354 | if (playlist->filenames[index] >= 0) |
1355 | { | 1355 | { |
1356 | max = dircache_copy_path(playlist->filenames[index], | 1356 | max = dircache_copy_path(playlist->filenames[index], |
1357 | tmp_buf, sizeof(tmp_buf)-1); | 1357 | tmp_buf, sizeof(tmp_buf)-1); |
@@ -2389,7 +2389,7 @@ int playlist_add(const char *filename) | |||
2389 | 2389 | ||
2390 | playlist->indices[playlist->amount] = playlist->buffer_end_pos; | 2390 | playlist->indices[playlist->amount] = playlist->buffer_end_pos; |
2391 | #ifdef HAVE_DIRCACHE | 2391 | #ifdef HAVE_DIRCACHE |
2392 | playlist->filenames[playlist->amount] = NULL; | 2392 | playlist->filenames[playlist->amount] = -1; |
2393 | #endif | 2393 | #endif |
2394 | playlist->amount++; | 2394 | playlist->amount++; |
2395 | 2395 | ||
@@ -2713,8 +2713,7 @@ int playlist_create_ex(struct playlist_info* playlist, | |||
2713 | playlist->max_playlist_size = num_indices; | 2713 | playlist->max_playlist_size = num_indices; |
2714 | playlist->indices = index_buffer; | 2714 | playlist->indices = index_buffer; |
2715 | #ifdef HAVE_DIRCACHE | 2715 | #ifdef HAVE_DIRCACHE |
2716 | playlist->filenames = (const struct dircache_entry **) | 2716 | playlist->filenames = (int*)&playlist->indices[num_indices]; |
2717 | &playlist->indices[num_indices]; | ||
2718 | #endif | 2717 | #endif |
2719 | 2718 | ||
2720 | playlist->buffer_size = 0; | 2719 | playlist->buffer_size = 0; |
diff --git a/apps/playlist.h b/apps/playlist.h index 9c45769981..d994f6e800 100644 --- a/apps/playlist.h +++ b/apps/playlist.h | |||
@@ -81,7 +81,7 @@ struct playlist_info | |||
81 | bool control_created; /* has control file been created? */ | 81 | bool control_created; /* has control file been created? */ |
82 | int dirlen; /* Length of the path to the playlist file */ | 82 | int dirlen; /* Length of the path to the playlist file */ |
83 | unsigned long *indices; /* array of indices */ | 83 | unsigned long *indices; /* array of indices */ |
84 | const struct dircache_entry **filenames; /* Entries from dircache */ | 84 | int *filenames; /* Array of dircache indices */ |
85 | int max_playlist_size; /* Max number of files in playlist. Mirror of | 85 | int max_playlist_size; /* Max number of files in playlist. Mirror of |
86 | global_settings.max_files_in_playlist */ | 86 | global_settings.max_files_in_playlist */ |
87 | bool in_ram; /* playlist stored in ram (dirplay) */ | 87 | bool in_ram; /* playlist stored in ram (dirplay) */ |
diff --git a/apps/tagcache.c b/apps/tagcache.c index 080f4198c3..c5a8dcbae5 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c | |||
@@ -383,8 +383,9 @@ static bool do_timed_yield(void) | |||
383 | #endif | 383 | #endif |
384 | 384 | ||
385 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | 385 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) |
386 | static long find_entry_ram(const char *filename, | 386 | /* find the ramcache entry corresponding to the file indicated by |
387 | const struct dircache_entry *dc) | 387 | * filename and dc (it's corresponding dircache id). */ |
388 | static long find_entry_ram(const char *filename, int dc) | ||
388 | { | 389 | { |
389 | static long last_pos = 0; | 390 | static long last_pos = 0; |
390 | int i; | 391 | int i; |
@@ -393,10 +394,10 @@ static long find_entry_ram(const char *filename, | |||
393 | if (!tc_stat.ramcache) | 394 | if (!tc_stat.ramcache) |
394 | return -1; | 395 | return -1; |
395 | 396 | ||
396 | if (dc == NULL) | 397 | if (dc < 0) |
397 | dc = dircache_get_entry_ptr(filename); | 398 | dc = dircache_get_entry_id(filename); |
398 | 399 | ||
399 | if (dc == NULL) | 400 | if (dc < 0) |
400 | { | 401 | { |
401 | logf("tagcache: file not found."); | 402 | logf("tagcache: file not found."); |
402 | return -1; | 403 | return -1; |
@@ -411,7 +412,7 @@ static long find_entry_ram(const char *filename, | |||
411 | 412 | ||
412 | for (; i < current_tcmh.tch.entry_count; i++) | 413 | for (; i < current_tcmh.tch.entry_count; i++) |
413 | { | 414 | { |
414 | if (hdr->indices[i].tag_seek[tag_filename] == (long)dc) | 415 | if (hdr->indices[i].tag_seek[tag_filename] == dc) |
415 | { | 416 | { |
416 | last_pos = MAX(0, i - 3); | 417 | last_pos = MAX(0, i - 3); |
417 | return i; | 418 | return i; |
@@ -539,7 +540,7 @@ static int find_index(const char *filename) | |||
539 | 540 | ||
540 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | 541 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) |
541 | if (tc_stat.ramcache && is_dircache_intact()) | 542 | if (tc_stat.ramcache && is_dircache_intact()) |
542 | idx_id = find_entry_ram(filename, NULL); | 543 | idx_id = find_entry_ram(filename, -1); |
543 | #endif | 544 | #endif |
544 | 545 | ||
545 | if (idx_id < 0) | 546 | if (idx_id < 0) |
@@ -723,8 +724,8 @@ static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx, | |||
723 | if (tag == tag_filename && (idx->flag & FLAG_DIRCACHE) | 724 | if (tag == tag_filename && (idx->flag & FLAG_DIRCACHE) |
724 | && is_dircache_intact()) | 725 | && is_dircache_intact()) |
725 | { | 726 | { |
726 | dircache_copy_path((struct dircache_entry *)seek, | 727 | /* for tag_filename, seek is a dircache index */ |
727 | buf, size); | 728 | dircache_copy_path(seek, buf, size); |
728 | return true; | 729 | return true; |
729 | } | 730 | } |
730 | else | 731 | else |
@@ -1481,8 +1482,7 @@ static bool get_next(struct tagcache_search *tcs) | |||
1481 | if (tcs->type == tag_filename && (flag & FLAG_DIRCACHE) | 1482 | if (tcs->type == tag_filename && (flag & FLAG_DIRCACHE) |
1482 | && is_dircache_intact()) | 1483 | && is_dircache_intact()) |
1483 | { | 1484 | { |
1484 | size_t len = dircache_copy_path((struct dircache_entry *)tcs->position, | 1485 | size_t len = dircache_copy_path(tcs->position, buf, sizeof buf); |
1485 | buf, sizeof buf); | ||
1486 | tcs->result_len = len + 1; | 1486 | tcs->result_len = len + 1; |
1487 | tcs->result = buf; | 1487 | tcs->result = buf; |
1488 | tcs->ramresult = false; | 1488 | tcs->ramresult = false; |
@@ -1599,29 +1599,6 @@ static bool update_master_header(void) | |||
1599 | return true; | 1599 | return true; |
1600 | } | 1600 | } |
1601 | 1601 | ||
1602 | #if 0 | ||
1603 | |||
1604 | void tagcache_modify(struct tagcache_search *tcs, int type, const char *text) | ||
1605 | { | ||
1606 | struct tagentry *entry; | ||
1607 | |||
1608 | if (tcs->type != tag_title) | ||
1609 | return ; | ||
1610 | |||
1611 | /* We will need reserve buffer for this. */ | ||
1612 | if (tcs->ramcache) | ||
1613 | { | ||
1614 | struct tagfile_entry *ep; | ||
1615 | |||
1616 | ep = (struct tagfile_entry *)&hdr->tags[tcs->type][tcs->result_seek]; | ||
1617 | tcs->seek_list[tcs->seek_list_count]; | ||
1618 | } | ||
1619 | |||
1620 | entry = find_entry_ram(); | ||
1621 | |||
1622 | } | ||
1623 | #endif | ||
1624 | |||
1625 | void tagcache_search_finish(struct tagcache_search *tcs) | 1602 | void tagcache_search_finish(struct tagcache_search *tcs) |
1626 | { | 1603 | { |
1627 | int i; | 1604 | int i; |
@@ -1677,7 +1654,7 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename) | |||
1677 | return false; | 1654 | return false; |
1678 | 1655 | ||
1679 | /* Find the corresponding entry in tagcache. */ | 1656 | /* Find the corresponding entry in tagcache. */ |
1680 | idx_id = find_entry_ram(filename, NULL); | 1657 | idx_id = find_entry_ram(filename, -1); |
1681 | if (idx_id < 0) | 1658 | if (idx_id < 0) |
1682 | return false; | 1659 | return false; |
1683 | 1660 | ||
@@ -1761,7 +1738,7 @@ static int check_if_empty(char **tag) | |||
1761 | static void __attribute__ ((noinline)) add_tagcache(char *path, | 1738 | static void __attribute__ ((noinline)) add_tagcache(char *path, |
1762 | unsigned long mtime | 1739 | unsigned long mtime |
1763 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | 1740 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) |
1764 | ,const struct dircache_entry *dc | 1741 | ,int dc |
1765 | #endif | 1742 | #endif |
1766 | ) | 1743 | ) |
1767 | { | 1744 | { |
@@ -4017,7 +3994,7 @@ static bool load_tagcache(void) | |||
4017 | if (tag == tag_filename) | 3994 | if (tag == tag_filename) |
4018 | { | 3995 | { |
4019 | # ifdef HAVE_DIRCACHE | 3996 | # ifdef HAVE_DIRCACHE |
4020 | const struct dircache_entry *dc; | 3997 | int dc; |
4021 | # endif | 3998 | # endif |
4022 | 3999 | ||
4023 | // FIXME: This is wrong! | 4000 | // FIXME: This is wrong! |
@@ -4064,8 +4041,8 @@ static bool load_tagcache(void) | |||
4064 | # ifdef HAVE_DIRCACHE | 4041 | # ifdef HAVE_DIRCACHE |
4065 | if (dircache_is_enabled()) | 4042 | if (dircache_is_enabled()) |
4066 | { | 4043 | { |
4067 | dc = dircache_get_entry_ptr(buf); | 4044 | dc = dircache_get_entry_id(buf); |
4068 | if (dc == NULL) | 4045 | if (dc < 0) |
4069 | { | 4046 | { |
4070 | logf("Entry no longer valid."); | 4047 | logf("Entry no longer valid."); |
4071 | logf("-> %s", buf); | 4048 | logf("-> %s", buf); |
@@ -4075,7 +4052,7 @@ static bool load_tagcache(void) | |||
4075 | } | 4052 | } |
4076 | 4053 | ||
4077 | idx->flag |= FLAG_DIRCACHE; | 4054 | idx->flag |= FLAG_DIRCACHE; |
4078 | idx->tag_seek[tag_filename] = (long)dc; | 4055 | idx->tag_seek[tag_filename] = dc; |
4079 | } | 4056 | } |
4080 | else | 4057 | else |
4081 | # endif | 4058 | # endif |
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 |
60 | static DIR_CACHED opendirs[MAX_OPEN_DIRS]; | 60 | |
61 | #define MAX_PENDING_BINDINGS 2 | ||
62 | struct fdbind_queue { | ||
63 | char path[MAX_PATH]; | ||
64 | int fd; | ||
65 | }; | ||
66 | |||
67 | /* Exported structures. */ | ||
68 | struct 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 | */ |
78 | static 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 */ |
80 | static struct dircache_entry *dircache_root; | 95 | static 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; | |||
86 | static struct dircache_entry *append_position; | 101 | static struct dircache_entry *append_position; |
87 | #endif | 102 | #endif |
88 | 103 | ||
104 | static DIR_CACHED opendirs[MAX_OPEN_DIRS]; | ||
105 | static struct dircache_entry *fd_bindings[MAX_OPEN_FILES]; | ||
106 | |||
89 | static bool dircache_initialized = false; | 107 | static bool dircache_initialized = false; |
90 | static bool dircache_initializing = false; | 108 | static bool dircache_initializing = false; |
91 | static bool thread_enabled = false; | 109 | static 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 | ||
126 | static 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 | */ |
1017 | const struct dircache_entry *dircache_get_entry_ptr(const char *filename) | 1040 | static 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 | |||
1049 | int 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 | */ | ||
1057 | long _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 | */ | ||
1065 | struct 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 | */ |
1053 | size_t dircache_copy_path(const struct dircache_entry *entry, char *buf, size_t size) | 1098 | size_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 | ||
1395 | struct dirent_cached* readdir_cached(DIR_CACHED* dir) | 1440 | struct 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); |
diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h index 908165cf3c..585bb10fbc 100644 --- a/firmware/include/dircache.h +++ b/firmware/include/dircache.h | |||
@@ -47,22 +47,6 @@ struct travel_data { | |||
47 | int pathpos; | 47 | int pathpos; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | #define MAX_PENDING_BINDINGS 2 | ||
51 | struct fdbind_queue { | ||
52 | char path[MAX_PATH]; | ||
53 | int fd; | ||
54 | }; | ||
55 | |||
56 | /* Exported structures. */ | ||
57 | struct dircache_entry { | ||
58 | struct dirinfo info; | ||
59 | struct dircache_entry *next; | ||
60 | struct dircache_entry *up; | ||
61 | struct dircache_entry *down; | ||
62 | long startcluster; | ||
63 | char *d_name; | ||
64 | }; | ||
65 | |||
66 | struct dirent_cached { | 50 | struct dirent_cached { |
67 | struct dirinfo info; | 51 | struct dirinfo info; |
68 | char *d_name; | 52 | char *d_name; |
@@ -72,7 +56,7 @@ struct dirent_cached { | |||
72 | typedef struct { | 56 | typedef struct { |
73 | bool busy; | 57 | bool busy; |
74 | struct dirent_cached theent; /* .attribute is set to -1 on init(opendir) */ | 58 | struct dirent_cached theent; /* .attribute is set to -1 on init(opendir) */ |
75 | struct dircache_entry *internal_entry; /* the current entry in the directory */ | 59 | int internal_entry; /* the current entry in the directory */ |
76 | DIR_UNCACHED *regulardir; | 60 | DIR_UNCACHED *regulardir; |
77 | } DIR_CACHED; | 61 | } DIR_CACHED; |
78 | 62 | ||
@@ -90,8 +74,12 @@ int dircache_get_cache_size(void); | |||
90 | int dircache_get_reserve_used(void); | 74 | int dircache_get_reserve_used(void); |
91 | int dircache_get_build_ticks(void); | 75 | int dircache_get_build_ticks(void); |
92 | void dircache_disable(void); | 76 | void dircache_disable(void); |
93 | const struct dircache_entry *dircache_get_entry_ptr(const char *filename); | 77 | int dircache_get_entry_id(const char *filename); |
94 | size_t dircache_copy_path(const struct dircache_entry *entry, char *buf, size_t size); | 78 | size_t dircache_copy_path(int index, char *buf, size_t size); |
79 | |||
80 | /* the next two are internal for file.c */ | ||
81 | long _dircache_get_entry_startcluster(int id); | ||
82 | struct dirinfo* _dircache_get_entry_dirinfo(int id); | ||
95 | 83 | ||
96 | void dircache_bind(int fd, const char *path); | 84 | void dircache_bind(int fd, const char *path); |
97 | void dircache_update_filesize(int fd, long newsize, long startcluster); | 85 | void dircache_update_filesize(int fd, long newsize, long startcluster); |
diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c index d094feee6b..71da4fc2ce 100644 --- a/uisimulator/common/io.c +++ b/uisimulator/common/io.c | |||
@@ -148,8 +148,7 @@ extern int _wrmdir(const wchar_t*); | |||
148 | 148 | ||
149 | 149 | ||
150 | #ifdef HAVE_DIRCACHE | 150 | #ifdef HAVE_DIRCACHE |
151 | struct dircache_entry; | 151 | int dircache_get_entry_id(const char *filename); |
152 | const struct dircache_entry *dircache_get_entry_ptr(const char *filename); | ||
153 | void dircache_add_file(const char *name, long startcluster); | 152 | void dircache_add_file(const char *name, long startcluster); |
154 | void dircache_remove(const char *name); | 153 | void dircache_remove(const char *name); |
155 | void dircache_rename(const char *oldname, const char *newname); | 154 | void dircache_rename(const char *oldname, const char *newname); |
@@ -409,7 +408,7 @@ int sim_open(const char *name, int o, ...) | |||
409 | mode_t mode = va_arg(ap, unsigned int); | 408 | mode_t mode = va_arg(ap, unsigned int); |
410 | ret = OPEN(get_sim_pathname(name), opts, mode); | 409 | ret = OPEN(get_sim_pathname(name), opts, mode); |
411 | #ifdef HAVE_DIRCACHE | 410 | #ifdef HAVE_DIRCACHE |
412 | if (ret >= 0 && !dircache_get_entry_ptr(name)) | 411 | if (ret >= 0 && (dircache_get_entry_id(name) < 0)) |
413 | dircache_add_file(name, 0); | 412 | dircache_add_file(name, 0); |
414 | #endif | 413 | #endif |
415 | va_end(ap); | 414 | va_end(ap); |
@@ -436,7 +435,7 @@ int sim_creat(const char *name, mode_t mode) | |||
436 | int ret = OPEN(get_sim_pathname(name), | 435 | int ret = OPEN(get_sim_pathname(name), |
437 | O_BINARY | O_WRONLY | O_CREAT | O_TRUNC, mode); | 436 | O_BINARY | O_WRONLY | O_CREAT | O_TRUNC, mode); |
438 | #ifdef HAVE_DIRCACHE | 437 | #ifdef HAVE_DIRCACHE |
439 | if (ret >= 0 && !dircache_get_entry_ptr(name)) | 438 | if (ret >= 0 && (dircache_get_entry_id(name) < 0)) |
440 | dircache_add_file(name, 0); | 439 | dircache_add_file(name, 0); |
441 | #endif | 440 | #endif |
442 | return ret; | 441 | return ret; |