1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index 5d280c4..a3632e3 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -846,10 +846,11 @@ int dircache_build(int last_size)
         return 3;
     }
 
-    /* struct dircache_entrys are allocated from the beginning,
-     * their corresponding d_name from the end
+    /* We'll use the entire audiobuf to allocate the dircache
+     * struct dircache_entrys are allocated from the beginning
+     * and their corresponding d_name from the end
      * after generation the buffer will be compacted with DIRCACHE_RESERVE
-     * free bytes in between */
+     * free bytes inbetween */
     audiobuf = (char*)(((intptr_t)audiobuf & ~0x03) + 0x04);
     dircache_root = (struct dircache_entry*)audiobuf;
     d_names_start = d_names_end = audiobufend - 1;
@@ -858,35 +859,30 @@ int dircache_build(int last_size)
 
     /* Start a non-transparent rebuild. */
     int res = dircache_do_rebuild();
+    if (ret < 0)
+        return res:
+
+    /* now compact the dircache buffer */
+    char* dst;
+    ptrdiff_t offset = d_names_start - dst, size_to_move;
+    if (offset <= 0) /* something went wrong */
+        return -1;
+
+    /* memmove d_names down, there's a possibility of overlap */
+    dst = ((char*)&dircache_root[entry_count] + DIRCACHE_RESERVE)
+    size_to_move = dircache_size - entry_count*sizeof(struct dircache_entry);
+    memmove(dst, d_names_start, size_to_move);
+    
+    /* fix up pointers to the d_names */
+    for(unsigned i = 0; i < entry_count; i++)
+        dircache_root[i].d_name -= offset;
+
+    d_names_end -= offset;
+    /* equivalent to dircache_size + DIRCACHE_RESERVE */
+    allocated_size = (d_names_end - dircache_root);
+    reserve_used = 0;
+    audiobuf += allocated_size;
 
-    /** compact the dircache buffer **/
-    if (res >= 0)
-    {
-        char* dst = ((char*)&dircache_root[entry_count] + DIRCACHE_RESERVE);
-        ssize_t offset = d_names_start - dst;
-        if (offset > 0)
-        {
-            ssize_t size_to_move = dircache_size -
-                                    entry_count*sizeof(struct dircache_entry);
-            /* move d_names down, use memmove if overlap */
-            if (offset > size_to_move)
-                memcpy(dst, d_names_start, size_to_move);
-            else
-                memmove(dst, d_names_start, size_to_move);
-            
-            /* fix up pointers to the d_names */
-            for(unsigned i = 0; i < entry_count; i++)
-                dircache_root[i].d_name -= offset;
-
-            d_names_end -= offset;
-            /* equivalent to dircache_size + DIRCACHE_RESERVE */
-            allocated_size = (d_names_end - (char*)dircache_root);
-            reserve_used = 0;
-            audiobuf += allocated_size;
-        }
-        else /* something went wrong */
-            return -1;
-    }
     return res;
 }