summaryrefslogtreecommitdiff
path: root/firmware/common/dircache.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/common/dircache.c')
-rw-r--r--firmware/common/dircache.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index 08fe5098f5..d114a6ac62 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -862,22 +862,26 @@ int dircache_build(int last_size)
862 * and their corresponding d_name from the end 862 * and their corresponding d_name from the end
863 * after generation the buffer will be compacted with DIRCACHE_RESERVE 863 * after generation the buffer will be compacted with DIRCACHE_RESERVE
864 * free bytes inbetween */ 864 * free bytes inbetween */
865 audiobuf = ALIGN_UP(audiobuf, sizeof(struct dircache_entry)); 865 size_t got_size;
866 dircache_root = (struct dircache_entry*)audiobuf; 866 char* buf = buffer_get_buffer(&got_size);
867 d_names_start = d_names_end = audiobufend - 1; 867 ALIGN_BUFFER(buf, got_size, sizeof(struct dircache_entry));
868 d_names_start = d_names_end = (char*)dircache_root + got_size - 1;
868 dircache_size = 0; 869 dircache_size = 0;
869 generate_dot_d_names(); 870 generate_dot_d_names();
870 871
871 /* Start a non-transparent rebuild. */ 872 /* Start a non-transparent rebuild. */
872 int res = dircache_do_rebuild(); 873 int res = dircache_do_rebuild();
873 if (res < 0) 874 if (res < 0)
874 return res; 875 goto fail;
875 876
876 /* now compact the dircache buffer */ 877 /* now compact the dircache buffer */
877 char* dst = ((char*)&dircache_root[entry_count] + DIRCACHE_RESERVE); 878 char* dst = ((char*)&dircache_root[entry_count] + DIRCACHE_RESERVE);
878 ptrdiff_t offset = d_names_start - dst; 879 ptrdiff_t offset = d_names_start - dst;
879 if (offset <= 0) /* something went wrong */ 880 if (offset <= 0) /* something went wrong */
880 return -1; 881 {
882 res = -1;
883 goto fail;
884 }
881 885
882 /* memmove d_names down, there's a possibility of overlap 886 /* memmove d_names down, there's a possibility of overlap
883 * equivaent to dircache_size - entry_count*sizeof(struct dircache_entry) */ 887 * equivaent to dircache_size - entry_count*sizeof(struct dircache_entry) */
@@ -896,15 +900,19 @@ int dircache_build(int last_size)
896 /* equivalent to dircache_size + DIRCACHE_RESERVE */ 900 /* equivalent to dircache_size + DIRCACHE_RESERVE */
897 allocated_size = (d_names_end - (char*)dircache_root); 901 allocated_size = (d_names_end - (char*)dircache_root);
898 reserve_used = 0; 902 reserve_used = 0;
899 audiobuf += allocated_size;
900 903
904 buffer_release_buffer(allocated_size);
905 return res;
906fail:
907 dircache_disable();
908 buffer_release_buffer(0);
901 return res; 909 return res;
902} 910}
903 911
904/** 912/**
905 * Steal the allocated dircache buffer and disable dircache. 913 * Steal the allocated dircache buffer and disable dircache.
906 */ 914 */
907void* dircache_steal_buffer(long *size) 915void* dircache_steal_buffer(size_t *size)
908{ 916{
909 dircache_disable(); 917 dircache_disable();
910 if (dircache_size == 0) 918 if (dircache_size == 0)