summaryrefslogtreecommitdiffstats
path: root/src/util/disk_cache.c
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2017-03-14 11:22:44 +1100
committerTimothy Arceri <[email protected]>2017-03-15 11:15:11 +1100
commitc2793e2c890b828c6cb1e9694619255d69a2ca1e (patch)
tree8b9798db164df757bf60f9c7199c529be461e870 /src/util/disk_cache.c
parent50989f87e62e0b9a4796c565a103ce45c684c673 (diff)
util/disk_cache: don't fallback to an empty cache dir on evict
If we fail to randomly select a two letter cache dir, don't select an empty dir on fallback. In real world use we should never hit the fallback path but it can be hit by tests when the cache is set to a very small max value. Reviewed-by: Grazvydas Ignotas <[email protected]>
Diffstat (limited to 'src/util/disk_cache.c')
-rw-r--r--src/util/disk_cache.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/src/util/disk_cache.c b/src/util/disk_cache.c
index 2d37f45e338..c71f039ee6d 100644
--- a/src/util/disk_cache.c
+++ b/src/util/disk_cache.c
@@ -576,14 +576,13 @@ unlink_random_file_from_directory(const char *path)
}
unlink(filename);
-
free (filename);
return sb.st_size;
}
/* Is entry a directory with a two-character name, (and not the
- * special name of "..")
+ * special name of ".."). We also return false if the dir is empty.
*/
static bool
is_two_character_sub_directory(const struct dirent *entry, const char *path)
@@ -594,15 +593,37 @@ is_two_character_sub_directory(const struct dirent *entry, const char *path)
struct stat sb;
int res = stat(subdir, &sb);
- free(subdir);
+ if (res == -1 || !S_ISDIR(sb.st_mode)) {
+ free(subdir);
+ return false;
+ }
- if (res == -1 || !S_ISDIR(sb.st_mode))
+ if (strlen(entry->d_name) != 2) {
+ free(subdir);
return false;
+ }
- if (strlen(entry->d_name) != 2)
+ if (strcmp(entry->d_name, "..") == 0) {
+ free(subdir);
return false;
+ }
+
+ DIR *dir = opendir(subdir);
+ free(subdir);
+
+ if (dir == NULL)
+ return false;
+
+ unsigned subdir_entries = 0;
+ struct dirent *d;
+ while ((d = readdir(dir)) != NULL) {
+ if(++subdir_entries > 2)
+ break;
+ }
+ closedir(dir);
- if (strcmp(entry->d_name, "..") == 0)
+ /* If dir only contains '.' and '..' it must be empty */
+ if (subdir_entries <= 2)
return false;
return true;