Add a more aggressive mode of cleaning up disk space.
authorMichael Vrable <mvrable@cs.ucsd.edu>
Tue, 19 Oct 2010 21:14:50 +0000 (14:14 -0700)
committerMichael Vrable <mvrable@cs.ucsd.edu>
Tue, 19 Oct 2010 21:14:50 +0000 (14:14 -0700)
If enough space cannot be deleted in the disk cache, drop nearly all clean
data from memory so that most disk cache files are unreferenced, then make
another pass to delete log/cache files.

bluesky/cache.c

index d8ef5fa..bfbfe3c 100644 (file)
@@ -235,8 +235,11 @@ static void drop_caches(BlueSkyInode *inode)
  * memory-mapped from log file or similar, so the kernel can drop this clean
  * data from memory for us and hence memory management isn't too important.
  * Mainly, we'll want to drop references to data that hasn't been accessed in a
- * while so that it is possible to reclaim log segments on disk. */
-static void flushd_clean(BlueSkyFS *fs)
+ * while so that it is possible to reclaim log segments on disk.
+ *
+ * If aggressive is set, try much harder to drop data from the caches to free
+ * up space. */
+static void flushd_clean(BlueSkyFS *fs, int aggressive)
 {
     g_mutex_lock(fs->lock);
 
@@ -251,7 +254,7 @@ static void flushd_clean(BlueSkyFS *fs)
         inode = fs->accessed_list.prev->data;
 
         uint64_t elapsed = bluesky_get_current_time() - inode->access_time;
-        if (elapsed < CACHE_DROP_DELAY)
+        if (elapsed < CACHE_DROP_DELAY && !aggressive)
             break;
 
         if (bluesky_verbose) {
@@ -370,6 +373,7 @@ void bluesky_cachefile_gc(BlueSkyFS *fs)
         files = g_list_delete_link(files, files);
     }
     g_list_free(files);
+    g_print("\nEnding cache size: %d kB\n", fs->log->disk_used);
 
     g_mutex_unlock(fs->log->mmap_lock);
 }
@@ -389,8 +393,17 @@ static gpointer flushd_task(BlueSkyFS *fs)
 
     flushd_dirty(fs);
     flushd_cloud(fs);
-    flushd_clean(fs);
+    flushd_clean(fs, 0);
     bluesky_cachefile_gc(fs);
+
+    /* If running out of disk cache space, make another more aggressive pass to
+     * free up space. */
+    if (g_atomic_int_get(&fs->log->disk_used) > bluesky_options.cache_size) {
+        g_print("Still short on disk space, trying again to free space...\n");
+        flushd_clean(fs, 1);
+        bluesky_cachefile_gc(fs);
+    }
+
     g_mutex_unlock(fs->flushd_lock);
 
     return NULL;