/* 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;
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;
-typedef struct _BlueSkyStore BlueSkyStore;
+struct BlueSkyStore;
+typedef struct BlueSkyStore BlueSkyStore;
-struct _BlueSkyLog;
-typedef struct _BlueSkyLog BlueSkyLog;
+struct BlueSkyLog;
+typedef struct BlueSkyLog BlueSkyLog;
-struct _BlueSkyCloudLogState;
-typedef struct _BlueSkyCloudLogState BlueSkyCloudLogState;
+struct BlueSkyCloudLogState;
+typedef struct BlueSkyCloudLogState BlueSkyCloudLogState;
-struct _BlueSkyCloudLog;
-typedef struct _BlueSkyCloudLog BlueSkyCloudLog;
+struct BlueSkyCloudLog;
+typedef struct BlueSkyCloudLog BlueSkyCloudLog;
void bluesky_store_init();
BlueSkyStore *bluesky_store_new(const gchar *type);
/* Filesystem state. Each filesystem which is exported is represented by a
* single bluesky_fs structure in memory. */
+struct BlueSkyCryptKeys;
+
typedef struct {
GMutex *lock;
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
/* 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. */
/* 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;
#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);