Add a more aggressive mode of cleaning up disk space.
[bluesky.git] / bluesky / bluesky.h
index 205da74..a4dfbbe 100644 (file)
@@ -33,6 +33,9 @@ typedef struct {
     /* Should frontends handle requests serially or allow operations to proceed
      * in parallel? */
     int sync_frontends;
+
+    /* Target size of the disk cache at the proxy, in kilobytes. */
+    int cache_size;
 } BlueSkyOptions;
 
 extern BlueSkyOptions bluesky_options;
@@ -63,41 +66,25 @@ void bluesky_init(void);
 
 gchar *bluesky_lowercase(const gchar *s);
 
-/* Reference-counted blocks of memory, used for passing data in and out of
- * storage backends and in other places.  This may also refer to read-only
- * mmaped data. */
-typedef struct {
-    gint refcount;
-    const char *addr;
-    size_t len;
-} BlueSkyMmap;
+struct _BlueSkyCacheFile;
+typedef struct _BlueSkyCacheFile BlueSkyCacheFile;
 
 typedef struct {
     gint refcount;
-    BlueSkyMmap *mmap;
+    BlueSkyCacheFile *mmap;
     gchar *data;
     gsize len;
 } BlueSkyRCStr;
 
 BlueSkyRCStr *bluesky_string_new(gpointer data, gsize len);
 BlueSkyRCStr *bluesky_string_new_from_gstring(GString *s);
-BlueSkyRCStr *bluesky_string_new_from_mmap(BlueSkyMmap *mmap,
+BlueSkyRCStr *bluesky_string_new_from_mmap(BlueSkyCacheFile *mmap,
                                            int offset, gsize len);
 void bluesky_string_ref(BlueSkyRCStr *string);
 void bluesky_string_unref(BlueSkyRCStr *string);
 BlueSkyRCStr *bluesky_string_dup(BlueSkyRCStr *string);
 void bluesky_string_resize(BlueSkyRCStr *string, gsize len);
 
-/* Cryptographic operations. */
-#define CRYPTO_BLOCK_SIZE 16        /* 128-bit AES */
-#define CRYPTO_KEY_SIZE   16
-
-void bluesky_crypt_init();
-void bluesky_crypt_hash_key(const char *keystr, uint8_t *out);
-void bluesky_crypt_random_bytes(guchar *buf, gint len);
-BlueSkyRCStr *bluesky_crypt_encrypt(BlueSkyRCStr *in, const uint8_t *key);
-BlueSkyRCStr *bluesky_crypt_decrypt(BlueSkyRCStr *in, const uint8_t *key);
-
 /* Storage interface.  This presents a key-value store abstraction, and can
  * have multiple implementations: in-memory, on-disk, in-cloud. */
 struct _BlueSkyStore;
@@ -137,6 +124,8 @@ typedef enum {
 
 /* Filesystem state.  Each filesystem which is exported is represented by a
  * single bluesky_fs structure in memory. */
+struct BlueSkyCryptKeys;
+
 typedef struct {
     GMutex *lock;
 
@@ -148,11 +137,24 @@ typedef struct {
     BlueSkyLog *log;
     BlueSkyCloudLogState *log_state;
 
+    /* Filesystem crypto keys */
+    char *master_key;
+    struct BlueSkyCryptKeys *keys;
+
     /* Accounting for memory used for caches.  Space is measured in blocks, not
-     * bytes.  We track both total data in the caches and dirty data (total
-     * data includes dirty data).  Updates to these variables must be made
-     * atomically. */
-    gint cache_total, cache_dirty;
+     * bytes.  Updates to these variables must be made atomically. */
+    gint cache_dirty;
+
+    /* Like above, but tracking data stored in the cloudlog entries
+     * specifically:
+     *  - cache_log_dirty: data uncommitted to journal and cloud
+     *  - cache_log_writeback: data being written to journal
+     *  - cache_log_journal: data committed to journal
+     *  - cache_log_cloud: data written to cloud as well
+     * Log entries should progress from the top state to the bottom, and are
+     * only ever counted in one category at a time. */
+    gint cache_log_dirty, cache_log_writeback,
+         cache_log_journal, cache_log_cloud;
 
     /* Linked list of inodes, sorted by access/modification times for cache
      * management.  Editing these lists is protected by the filesystem lock; to
@@ -166,9 +168,22 @@ typedef struct {
     /* Mutex for the flush daemon, to prevent concurrent execution. */
     GMutex *flushd_lock;
 
+    /* Used to wait for the cache daemon to free up space */
+    GCond *flushd_cond;
+
     /* Mapping of object identifiers (blocks, inodes) to physical location (in
      * the local cache or in the logs in the cloud). */
     GHashTable *locations;
+
+    /* The inode map, which maps inode numbers to the location of the most
+     * recent version. */
+    GSequence *inode_map;
+
+    /* Queue for asynchronous cloudlog unrefs, where needed. */
+    GAsyncQueue *unref_queue;
+
+    /* Thread pool for asynchronous inode fetches */
+    GThreadPool *inode_fetch_thread_pool;
 } BlueSkyFS;
 
 /* Inode number of the root directory. */
@@ -230,9 +245,6 @@ typedef struct {
     /* 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 */
-
     /* Version of the object last serialized and committed to storage. */
     BlueSkyCloudLog *committed_item;
 
@@ -281,19 +293,18 @@ typedef struct {
 #define BLUESKY_MAX_FILE_SIZE (BLUESKY_BLOCK_SIZE << 24)
 typedef enum {
     BLUESKY_BLOCK_ZERO = 0,     /* Data is all zeroes, not explicitly stored */
-    BLUESKY_BLOCK_REF = 1,      /* Reference to key/value store, not cached */
-    BLUESKY_BLOCK_CACHED = 2,   /* Data is cached in memory, clean */
-    BLUESKY_BLOCK_DIRTY = 3,    /* Data needs to be committed to store */
+    BLUESKY_BLOCK_REF = 1,      /* Reference to cloud log item, data clean */
+    BLUESKY_BLOCK_DIRTY = 2,    /* Data needs to be committed to store */
 } BlueSkyBlockType;
 
 typedef struct {
     BlueSkyBlockType type;
-    BlueSkyRCStr *data;         /* Pointer to data in memory if cached */
-    BlueSkyCloudLog *cloudref;  /* Reference to cloud log entry with data */
+    BlueSkyCloudLog *ref;       /* if REF: cloud log entry with data */
+    BlueSkyRCStr *dirty;        /* if DIRTY: raw data in memory */
 } BlueSkyBlock;
 
-BlueSkyFS *bluesky_init_fs(gchar *name, BlueSkyStore *store);
-void bluesky_superblock_flush(BlueSkyFS *fs);
+BlueSkyFS *bluesky_init_fs(gchar *name, BlueSkyStore *store,
+                           const gchar *master_key);
 
 gboolean bluesky_inode_is_ready(BlueSkyInode *inode);