+ 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. */
+static void drop_caches(BlueSkyInode *inode)
+{
+ if (inode->type == BLUESKY_REGULAR)
+ bluesky_file_drop_cached(inode);
+
+ BlueSkyCloudLog *log = inode->committed_item;
+ if (log != NULL) {
+ g_mutex_lock(log->lock);
+ if (log->data != NULL
+ && g_atomic_int_get(&log->data_lock_count) == 0
+ && (log->location_flags != 0))
+ {
+ bluesky_cloudlog_stats_update(log, -1);
+ bluesky_string_unref(log->data);
+ log->data = NULL;
+ bluesky_cloudlog_stats_update(log, 1);
+ }
+ g_mutex_unlock(log->lock);
+ }
+}
+
+/* Drop clean data from the cache if needed. Clean data should generally be
+ * 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.
+ *
+ * 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);
+
+ size_t inode_count = g_hash_table_size(fs->inodes);
+ if (!inode_count)
+ inode_count = 1;
+
+ while (inode_count-- > 0) {
+ BlueSkyInode *inode;
+ if (fs->accessed_list.prev == NULL)
+ break;
+ inode = fs->accessed_list.prev->data;
+
+ uint64_t elapsed = bluesky_get_current_time() - inode->access_time;
+ if (elapsed < CACHE_DROP_DELAY && !aggressive)
+ break;
+
+ if (bluesky_verbose) {
+ g_log("bluesky/flushd", G_LOG_LEVEL_DEBUG,
+ "Considering dropping cached data for inode %"PRIu64,
+ inode->inum);
+ }
+
+ bluesky_inode_ref(inode);
+
+ g_mutex_unlock(fs->lock);
+
+ g_mutex_lock(inode->lock);
+
+ g_mutex_lock(fs->lock);
+ bluesky_list_unlink(&fs->accessed_list, inode->accessed_list);
+ inode->accessed_list = bluesky_list_prepend(&fs->accessed_list, inode);
+ g_mutex_unlock(fs->lock);
+
+ drop_caches(inode);
+