From de946bbcea4c0bc0c92a858eae4d5c668e923c83 Mon Sep 17 00:00:00 2001
From: Michael Vrable <mvrable@cs.ucsd.edu>
Date: Fri, 26 Mar 2010 09:48:05 -0700
Subject: [PATCH] In-progress work on better cache flushing.

---
 bluesky/bluesky-private.h |  5 +++++
 bluesky/cache.c           |  6 ++++++
 bluesky/init.c            | 13 +++++++++++++
 bluesky/inode.c           |  6 +++++-
 4 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/bluesky/bluesky-private.h b/bluesky/bluesky-private.h
index ccd57cb..8d2e3fc 100644
--- a/bluesky/bluesky-private.h
+++ b/bluesky/bluesky-private.h
@@ -19,6 +19,11 @@
 extern "C" {
 #endif
 
+/* Target cache size levels. */
+extern int bluesky_watermark_low_dirty;
+extern int bluesky_watermark_medium_dirty;
+extern int bluesky_watermark_high_dirty;
+
 /* TODO: Make this go away entirely. */
 BlueSkyFS *bluesky_new_fs(gchar *name);
 
diff --git a/bluesky/cache.c b/bluesky/cache.c
index f58a949..211c2b9 100644
--- a/bluesky/cache.c
+++ b/bluesky/cache.c
@@ -74,6 +74,12 @@ static void flushd_inode(gpointer value, gpointer user_data)
                     if (g_hash_table_remove(fs->inodes, &inode->inum))
                         bluesky_inode_unref(inode);
                 }
+                bluesky_list_unlink(&inode->fs->accessed_list,
+                                    inode->accessed_list);
+                inode->accessed_list = NULL;
+                bluesky_list_unlink(&inode->fs->dirty_list,
+                                    inode->dirty_list);
+                inode->dirty_list = NULL;
                 g_mutex_unlock(fs->lock);
             }
         }
diff --git a/bluesky/init.c b/bluesky/init.c
index 0feb0f5..eb2515c 100644
--- a/bluesky/init.c
+++ b/bluesky/init.c
@@ -19,6 +19,19 @@ BlueSkyOptions bluesky_options;
  * limit */
 int bluesky_max_threads = 16;
 
+/* Watermark levels for cache tuning: these control when dirty data is flushed
+ * from cache, when clean data is dropped from the cache, etc.  These values
+ * are measured in blocks, not bytes.
+ *
+ * There are a few relevant levels:
+ *   low: Below this point, data is not forced out due to memory pressure
+ *   medium: At this point start flushing data to get back below medium
+ *   high: Flush data very aggressively (launch extra tasks if needed)
+ */
+int bluesky_watermark_low_dirty    = (64 << 20) / BLUESKY_BLOCK_SIZE;
+int bluesky_watermark_medium_dirty = (96 << 20) / BLUESKY_BLOCK_SIZE;
+int bluesky_watermark_high_dirty   = (192 << 20) / BLUESKY_BLOCK_SIZE;
+
 /* Environment variables that can be used to initialize settings. */
 static struct {
     const char *env;
diff --git a/bluesky/inode.c b/bluesky/inode.c
index ef6e75d..39feff8 100644
--- a/bluesky/inode.c
+++ b/bluesky/inode.c
@@ -133,10 +133,14 @@ void bluesky_inode_unref(BlueSkyInode *inode)
 
         /* Sanity check: Is the inode clean? */
         if (inode->change_commit < inode->change_count
+                || inode->accessed_list != NULL
                 || inode->dirty_list != NULL) {
-            g_warning("Dropping inode which is not clean (commit %"PRIi64" < change %"PRIi64"; dirty_list = %p)\n", inode->change_commit, inode->change_count, inode->dirty_list);
+            g_warning("Dropping inode which is not clean (commit %"PRIi64" < change %"PRIi64"; accessed_list = %p; dirty_list = %p)\n", inode->change_commit, inode->change_count, inode->accessed_list, inode->dirty_list);
         }
 
+        /* These shouldn't be needed, but in case the above warning fires and
+         * we delete the inode anyway, we ought to be sure the inode is not on
+         * any LRU list. */
         g_mutex_lock(inode->fs->lock);
         bluesky_list_unlink(&inode->fs->accessed_list, inode->accessed_list);
         bluesky_list_unlink(&inode->fs->dirty_list, inode->dirty_list);
-- 
2.20.1