X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=bluesky%2Fcache.c;h=d1c5c84c6725e5b6ac2a2cc8f323e386c777b336;hb=7daddca3715fee8a3bfff417e769ff08dd7f4cbf;hp=a9fda5b8a08a48b46c6a3935b9d599e5950e099a;hpb=774148ec71a99b6acf1023fd990ea975a6b92780;p=bluesky.git diff --git a/bluesky/cache.c b/bluesky/cache.c index a9fda5b..d1c5c84 100644 --- a/bluesky/cache.c +++ b/bluesky/cache.c @@ -107,13 +107,20 @@ static void flushd_dirty(BlueSkyFS *fs) * cloud. When the write completes, we will allow old journal segments (those * that were fully written _before_ the snapshot process started) to be garbage * collected. Newer journal segments can't be collected yet since they may - * still contain data which has not been written persistently to the cloud. */ + * still contain data which has not been written persistently to the cloud. + * + * Note that some of this code relies on the fact that only this thread of + * control (running flushd_cloud) is manipulating the inode map, and so + * concurrent updates to the inode map are prevented even without the + * filesystem lock held. Take great care if allowing multi-threaded access to + * the inode map... */ static void flushd_cloud(BlueSkyFS *fs) { g_mutex_lock(fs->lock); /* TODO: Locking? Since we're reading a single variable this is probably * atomic but a lock could be safer. */ + BlueSkyCloudLog *marker = bluesky_log_get_commit_point(fs); int journal_seq_start = fs->log->seq_num; while (1) { @@ -132,14 +139,14 @@ static void flushd_cloud(BlueSkyFS *fs) g_mutex_unlock(fs->lock); g_mutex_lock(inode->lock); - flushd_dirty_inode(inode); + g_assert(inode->change_cloud == inode->change_commit); g_mutex_lock(fs->lock); bluesky_list_unlink(&fs->dirty_list, inode->dirty_list); inode->dirty_list = NULL; g_mutex_unlock(fs->lock); BlueSkyCloudLog *log = inode->committed_item; - bluesky_cloudlog_ref(log); + inode->committed_item = NULL; g_mutex_unlock(inode->lock); if (log != NULL) @@ -149,8 +156,17 @@ static void flushd_cloud(BlueSkyFS *fs) g_mutex_lock(fs->lock); } - g_mutex_unlock(fs->lock); + + /* Write out any updated inode map entries, so that all inodes just written + * can be located, and then a final commit record. */ + BlueSkyCloudLog *commit_record = bluesky_inode_map_serialize(fs); + if (commit_record != NULL) { + bluesky_cloudlog_serialize(commit_record, fs); + } else { + g_print("No need for a checkpoint record...\n"); + } + bluesky_cloudlog_flush(fs); /* Wait until all segments have been written to the cloud, so that it @@ -172,10 +188,15 @@ static void flushd_cloud(BlueSkyFS *fs) fs->log_state->pending_segments); } + bluesky_log_write_commit_point(fs, marker); + bluesky_cloudlog_unref(commit_record); + g_print("All segments have been flushed, journal < %d is clean\n", journal_seq_start); fs->log->journal_watermark = journal_seq_start; + + bluesky_inode_map_minimize(fs); } /* Drop cached data for a given inode, if it is clean. inode must be locked. */