storage_dir_t *dir;
/** List of all the entries in the directory. */
smartlist_t *entries;
+
+ /** The maximum number of entries that we'd like to allow in this cache.
+ * This is the same as the storagedir limit when MUST_UNMAP_TO_UNLINK is
+ * not defined. */
+ unsigned max_entries;
};
static void consensus_cache_clear(consensus_cache_t *cache);
{
consensus_cache_t *cache = tor_malloc_zero(sizeof(consensus_cache_t));
char *directory = get_datadir_fname(subdir);
+ cache->max_entries = max_entries;
+#ifdef MUST_UNMAP_TO_UNLINK
+ max_entries = 1000000;
+#endif
cache->dir = storage_dir_new(directory, max_entries);
tor_free(directory);
if (!cache->dir) {
return cache;
}
+/** Return true if it's okay to put more entries in this cache than
+ * its official file limit. */
+int
+consensus_cache_may_overallocate(consensus_cache_t *cache)
+{
+ (void) cache;
+#ifdef MUST_UNMAP_TO_UNLINK
+ return 1;
+#else
+ return 0;
+#endif
+}
+
/**
* Tell the sandbox (if any) configured by <b>cfg</b> to allow the
* operations that <b>cache</b> will need.
consensus_cache_register_with_sandbox(consensus_cache_t *cache,
struct sandbox_cfg_elem **cfg)
{
+#ifdef MUST_UNMAP_TO_UNLINK
+ /* Our sandbox doesn't support huge limits like we use here.
+ */
+ tor_assert_nonfatal_unreached();
+#endif
return storage_dir_register_with_sandbox(cache->dir, cfg);
}
consensus_cache_t *consensus_cache_open(const char *subdir, int max_entries);
void consensus_cache_free(consensus_cache_t *cache);
struct sandbox_cfg_elem;
+int consensus_cache_may_overallocate(consensus_cache_t *cache);
int consensus_cache_register_with_sandbox(consensus_cache_t *cache,
struct sandbox_cfg_elem **cfg);
void consensus_cache_unmap_lazy(consensus_cache_t *cache, time_t cutoff);
return 0;
}
// Let's get more assertive: clean out unused stuff, and force-remove
- // the files.
+ // the files that we can.
consdiffmgr_cleanup();
consensus_cache_delete_pending(cache, 1);
const int n_to_remove = n - consensus_cache_get_n_filenames_available(cache);
smartlist_free(objects);
consensus_cache_delete_pending(cache, 1);
+
+ if (consensus_cache_may_overallocate(cache)) {
+ /* If we're allowed to throw extra files into the cache, let's do so
+ * rather getting upset.
+ */
+ return 0;
+ }
+
if (BUG(n_marked < n_to_remove))
return -1;
else