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.c60
1 files changed, 18 insertions, 42 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index 8917b3348e..1d6371a6b5 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -249,7 +249,6 @@ static struct dircache_runinfo
249 /* cache buffer info */ 249 /* cache buffer info */
250 int handle; /* buflib buffer handle */ 250 int handle; /* buflib buffer handle */
251 size_t bufsize; /* size of buflib allocation - 1 */ 251 size_t bufsize; /* size of buflib allocation - 1 */
252 int buflocked; /* don't move due to other allocs */
253 union { 252 union {
254 void *p; /* address of buffer - ENTRYSIZE */ 253 void *p; /* address of buffer - ENTRYSIZE */
255 struct dircache_entry *pentry; /* alias of .p to assist entry resolution */ 254 struct dircache_entry *pentry; /* alias of .p to assist entry resolution */
@@ -329,29 +328,9 @@ static inline void dumpster_clean_buffer(void *p, size_t size)
329 */ 328 */
330static int move_callback(int handle, void *current, void *new) 329static int move_callback(int handle, void *current, void *new)
331{ 330{
332 if (dircache_runinfo.buflocked) 331 (void)handle; (void)current;
333 return BUFLIB_CB_CANNOT_MOVE;
334
335 dircache_runinfo.p = new - ENTRYSIZE; 332 dircache_runinfo.p = new - ENTRYSIZE;
336
337 return BUFLIB_CB_OK; 333 return BUFLIB_CB_OK;
338 (void)handle; (void)current;
339}
340
341/**
342 * add a "don't move" lock count
343 */
344static inline void buffer_lock(void)
345{
346 dircache_runinfo.buflocked++;
347}
348
349/**
350 * remove a "don't move" lock count
351 */
352static inline void buffer_unlock(void)
353{
354 dircache_runinfo.buflocked--;
355} 334}
356 335
357 336
@@ -530,14 +509,14 @@ static void set_buffer(int handle, size_t size)
530 509
531/** 510/**
532 * remove the allocation from dircache control and return the handle 511 * remove the allocation from dircache control and return the handle
512 * Note that dircache must not be using the buffer!
533 */ 513 */
534static int reset_buffer(void) 514static int reset_buffer(void)
535{ 515{
536 int handle = dircache_runinfo.handle; 516 int handle = dircache_runinfo.handle;
537 if (handle > 0) 517 if (handle > 0)
538 { 518 {
539 /* don't mind .p; it might get changed by the callback even after 519 /* don't mind .p; buffer presence is determined by the following: */
540 this call; buffer presence is determined by the following: */
541 dircache_runinfo.handle = 0; 520 dircache_runinfo.handle = 0;
542 dircache_runinfo.bufsize = 0; 521 dircache_runinfo.bufsize = 0;
543 } 522 }
@@ -1857,7 +1836,7 @@ static void reset_cache(void)
1857 */ 1836 */
1858static void build_volumes(void) 1837static void build_volumes(void)
1859{ 1838{
1860 buffer_lock(); 1839 core_pin(dircache_runinfo.handle);
1861 1840
1862 for (int i = 0; i < NUM_VOLUMES; i++) 1841 for (int i = 0; i < NUM_VOLUMES; i++)
1863 { 1842 {
@@ -1903,12 +1882,14 @@ static void build_volumes(void)
1903 1882
1904 logf("Done, %ld KiB used", dircache.size / 1024); 1883 logf("Done, %ld KiB used", dircache.size / 1024);
1905 1884
1906 buffer_unlock(); 1885 core_unpin(dircache_runinfo.handle);
1907} 1886}
1908 1887
1909/** 1888/**
1910 * allocate buffer and return whether or not a synchronous build should take 1889 * allocate buffer and return whether or not a synchronous build should take
1911 * place; if 'realloced' is NULL, it's just a query about what will happen 1890 * place; if 'realloced' is NULL, it's just a query about what will happen
1891 *
1892 * Note this must be called with the dircache_lock() active.
1912 */ 1893 */
1913static int prepare_build(bool *realloced) 1894static int prepare_build(bool *realloced)
1914{ 1895{
@@ -1958,16 +1939,14 @@ static int prepare_build(bool *realloced)
1958 *realloced = true; 1939 *realloced = true;
1959 reset_cache(); 1940 reset_cache();
1960 1941
1961 buffer_lock();
1962
1963 int handle = reset_buffer(); 1942 int handle = reset_buffer();
1964 dircache_unlock(); 1943 dircache_unlock(); /* release lock held by caller */
1965 1944
1966 core_free(handle); 1945 core_free(handle);
1967 1946
1968 handle = alloc_cache(size); 1947 handle = alloc_cache(size);
1969 1948
1970 dircache_lock(); 1949 dircache_lock(); /* reacquire lock */
1971 1950
1972 if (dircache_runinfo.suspended && handle > 0) 1951 if (dircache_runinfo.suspended && handle > 0)
1973 { 1952 {
@@ -1979,13 +1958,9 @@ static int prepare_build(bool *realloced)
1979 } 1958 }
1980 1959
1981 if (handle <= 0) 1960 if (handle <= 0)
1982 {
1983 buffer_unlock();
1984 return -1; 1961 return -1;
1985 }
1986 1962
1987 set_buffer(handle, size); 1963 set_buffer(handle, size);
1988 buffer_unlock();
1989 1964
1990 return syncbuild; 1965 return syncbuild;
1991} 1966}
@@ -2384,9 +2359,9 @@ void dircache_fileop_create(struct file_base_info *dirinfop,
2384 if ((dinp->attr & ATTR_DIRECTORY) && !is_dotdir_name(basename)) 2359 if ((dinp->attr & ATTR_DIRECTORY) && !is_dotdir_name(basename))
2385 { 2360 {
2386 /* scan-in the contents of the new directory at this level only */ 2361 /* scan-in the contents of the new directory at this level only */
2387 buffer_lock(); 2362 core_pin(dircache_runinfo.handle);
2388 sab_process_dir(infop, false); 2363 sab_process_dir(infop, false);
2389 buffer_unlock(); 2364 core_unpin(dircache_runinfo.handle);
2390 } 2365 }
2391} 2366}
2392 2367
@@ -2915,7 +2890,7 @@ void dircache_dump(void)
2915 2890
2916 if (dircache_runinfo.handle) 2891 if (dircache_runinfo.handle)
2917 { 2892 {
2918 buffer_lock(); 2893 core_pin(dircache_runinfo.handle);
2919 2894
2920 /* bin */ 2895 /* bin */
2921 write(fdbin, dircache_runinfo.p + ENTRYSIZE, 2896 write(fdbin, dircache_runinfo.p + ENTRYSIZE,
@@ -2985,7 +2960,7 @@ void dircache_dump(void)
2985 tm.tm_hour, tm.tm_min, tm.tm_sec); 2960 tm.tm_hour, tm.tm_min, tm.tm_sec);
2986 } 2961 }
2987 2962
2988 buffer_unlock(); 2963 core_unpin(dircache_runinfo.handle);
2989 } 2964 }
2990 2965
2991 dircache_unlock(); 2966 dircache_unlock();
@@ -3104,7 +3079,6 @@ int dircache_load(void)
3104 } 3079 }
3105 3080
3106 dircache_lock(); 3081 dircache_lock();
3107 buffer_lock();
3108 3082
3109 if (!dircache_is_clean(false)) 3083 if (!dircache_is_clean(false))
3110 goto error; 3084 goto error;
@@ -3113,6 +3087,7 @@ int dircache_load(void)
3113 dircache = maindata.dircache; 3087 dircache = maindata.dircache;
3114 3088
3115 set_buffer(handle, bufsize); 3089 set_buffer(handle, bufsize);
3090 core_pin(handle);
3116 hasbuffer = true; 3091 hasbuffer = true;
3117 3092
3118 /* convert back to in-RAM representation */ 3093 /* convert back to in-RAM representation */
@@ -3167,13 +3142,13 @@ int dircache_load(void)
3167 dircache_enable_internal(false); 3142 dircache_enable_internal(false);
3168 3143
3169 /* cache successfully loaded */ 3144 /* cache successfully loaded */
3145 core_unpin(handle);
3170 logf("Done, %ld KiB used", dircache.size / 1024); 3146 logf("Done, %ld KiB used", dircache.size / 1024);
3171 rc = 0; 3147 rc = 0;
3172error: 3148error:
3173 if (rc < 0 && hasbuffer) 3149 if (rc < 0 && hasbuffer)
3174 reset_buffer(); 3150 reset_buffer();
3175 3151
3176 buffer_unlock();
3177 dircache_unlock(); 3152 dircache_unlock();
3178 3153
3179error_nolock: 3154error_nolock:
@@ -3199,8 +3174,9 @@ int dircache_save(void)
3199 if (fd < 0) 3174 if (fd < 0)
3200 return -1; 3175 return -1;
3201 3176
3177 /* it seems the handle *must* exist if this function is called */
3202 dircache_lock(); 3178 dircache_lock();
3203 buffer_lock(); 3179 core_pin(dircache_runinfo.handle);
3204 3180
3205 int rc = -1; 3181 int rc = -1;
3206 3182
@@ -3269,7 +3245,7 @@ int dircache_save(void)
3269 that makes what was saved completely invalid */ 3245 that makes what was saved completely invalid */
3270 rc = 0; 3246 rc = 0;
3271error: 3247error:
3272 buffer_unlock(); 3248 core_unpin(dircache_runinfo.handle);
3273 dircache_unlock(); 3249 dircache_unlock();
3274 3250
3275 if (rc < 0) 3251 if (rc < 0)