Add very rudimentary eviction data blocks from the cache.
authorMichael Vrable <mvrable@cs.ucsd.edu>
Fri, 5 Feb 2010 21:23:06 +0000 (13:23 -0800)
committerMichael Vrable <mvrable@cs.ucsd.edu>
Fri, 5 Feb 2010 21:23:06 +0000 (13:23 -0800)
bluesky/bluesky-private.h
bluesky/bluesky.h
bluesky/cache.c
bluesky/file.c
bluesky/inode.c

index 3e4d39b..a4c8a5e 100644 (file)
@@ -117,6 +117,7 @@ void bluesky_inode_start_sync(BlueSkyInode *inode, BlueSkyStoreAsync *barrier);
 void bluesky_block_flush(BlueSkyFS *fs, BlueSkyBlock *block,
                          BlueSkyStoreAsync *barrier);
 void bluesky_file_flush(BlueSkyInode *inode, BlueSkyStoreAsync *barrier);
+void bluesky_file_drop_cached(BlueSkyInode *inode);
 
 #ifdef __cplusplus
 }
index 7b8aad2..d7750f7 100644 (file)
@@ -169,6 +169,9 @@ typedef struct {
      * set to the current time.  If the inode is clean, it is set to zero. */
     int64_t change_time;
 
+    /* Last access time to this inode, for controlling cache evictions. */
+    int64_t access_time;
+
     /* Additional state for tracking cache writeback status. */
     uint64_t change_pending;    /* change_count version currently being committed to storage */
 
index 979c917..e9d95cf 100644 (file)
@@ -14,6 +14,7 @@
 #include "bluesky-private.h"
 
 #define WRITEBACK_DELAY (5 * 1000000)
+#define CACHE_CLEAN_DELAY (30 * 1000000)
 
 /* Filesystem caching and cache coherency. */
 
@@ -36,6 +37,13 @@ static void writeback_complete(gpointer a, gpointer i)
     g_mutex_unlock(inode->lock);
 }
 
+/* Drop cached data for a given inode, if it is clean.  inode must be locked. */
+static void drop_caches(BlueSkyInode *inode)
+{
+    if (inode->type == BLUESKY_REGULAR)
+        bluesky_file_drop_cached(inode);
+}
+
 static void flushd_inode(gpointer value, gpointer user_data)
 {
     BlueSkyFS *fs = (BlueSkyFS *)user_data;
@@ -45,6 +53,9 @@ static void flushd_inode(gpointer value, gpointer user_data)
     g_mutex_lock(inode->lock);
 
     if (inode->change_count == inode->change_commit) {
+        uint64_t delay = bluesky_get_current_time() - inode->access_time;
+        if (delay >= CACHE_CLEAN_DELAY)
+            drop_caches(inode);
         g_mutex_unlock(inode->lock);
         bluesky_inode_unref(inode);
         return;
index 9b9f916..2df979e 100644 (file)
@@ -244,3 +244,22 @@ void bluesky_file_flush(BlueSkyInode *inode, BlueSkyStoreAsync *barrier)
         bluesky_block_flush(inode->fs, b, barrier);
     }
 }
+
+/* Drop clean data blocks for a file from cache. */
+void bluesky_file_drop_cached(BlueSkyInode *inode)
+{
+    g_return_if_fail(inode->type == BLUESKY_REGULAR);
+
+    for (int i = 0; i < inode->blocks->len; i++) {
+        BlueSkyBlock *b = &g_array_index(inode->blocks, BlueSkyBlock, i);
+        if (b->type == BLUESKY_BLOCK_CACHED) {
+            g_log("bluesky/cache", G_LOG_LEVEL_DEBUG,
+                  "Dropping block %d of inode %"PRIu64" from cache",
+                  i, inode->inum);
+
+            bluesky_string_unref(b->data);
+            b->data = NULL;
+            b->type = BLUESKY_BLOCK_REF;
+        }
+    }
+}
index 05f63bf..55781ca 100644 (file)
@@ -197,6 +197,10 @@ BlueSkyInode *bluesky_get_inode(BlueSkyFS *fs, uint64_t inum)
 
     if (inode != NULL) {
         bluesky_inode_ref(inode);
+
+        /* FIXME: We assume we can atomically update the in-memory access time
+         * without a lock. */
+        inode->access_time = bluesky_get_current_time();
     }
 
     g_mutex_unlock(fs->lock);