diff options
Diffstat (limited to 'firmware/common')
-rw-r--r-- | firmware/common/dircache.c | 22 |
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; | ||
906 | fail: | ||
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 | */ |
907 | void* dircache_steal_buffer(long *size) | 915 | void* dircache_steal_buffer(size_t *size) |
908 | { | 916 | { |
909 | dircache_disable(); | 917 | dircache_disable(); |
910 | if (dircache_size == 0) | 918 | if (dircache_size == 0) |