From 579ee9ab24b7cd3981d927f69ae919dcfaeac5ff Mon Sep 17 00:00:00 2001 From: Michael Vrable Date: Fri, 5 Feb 2010 13:23:06 -0800 Subject: [PATCH] Add very rudimentary eviction data blocks from the cache. --- bluesky/bluesky-private.h | 1 + bluesky/bluesky.h | 3 +++ bluesky/cache.c | 11 +++++++++++ bluesky/file.c | 19 +++++++++++++++++++ bluesky/inode.c | 4 ++++ 5 files changed, 38 insertions(+) diff --git a/bluesky/bluesky-private.h b/bluesky/bluesky-private.h index 3e4d39b..a4c8a5e 100644 --- a/bluesky/bluesky-private.h +++ b/bluesky/bluesky-private.h @@ -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 } diff --git a/bluesky/bluesky.h b/bluesky/bluesky.h index 7b8aad2..d7750f7 100644 --- a/bluesky/bluesky.h +++ b/bluesky/bluesky.h @@ -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 */ diff --git a/bluesky/cache.c b/bluesky/cache.c index 979c917..e9d95cf 100644 --- a/bluesky/cache.c +++ b/bluesky/cache.c @@ -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; diff --git a/bluesky/file.c b/bluesky/file.c index 9b9f916..2df979e 100644 --- a/bluesky/file.c +++ b/bluesky/file.c @@ -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; + } + } +} diff --git a/bluesky/inode.c b/bluesky/inode.c index 05f63bf..55781ca 100644 --- a/bluesky/inode.c +++ b/bluesky/inode.c @@ -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); -- 2.20.1