CMake reorganization.
[bluesky.git] / bluesky / bluesky.h
1 /* Blue Sky: File Systems in the Cloud
2  *
3  * Copyright (C) 2009  The Regents of the University of California
4  * Written by Michael Vrable <mvrable@cs.ucsd.edu>
5  *
6  * TODO: Licensing
7  */
8
9 #ifndef _BLUESKY_H
10 #define _BLUESKY_H
11
12 #include <stdint.h>
13 #include <glib.h>
14
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18
19 struct S3Store;
20
21 /* Reference-counted blocks of memory, used for passing data in and out of
22  * storage backends and in other places. */
23 typedef struct {
24     gint refcount;
25     gchar *data;
26     gsize len;
27 } BlueSkyRCStr;
28
29 BlueSkyRCStr *bluesky_string_new(gpointer data, gsize len);
30 void bluesky_string_ref(BlueSkyRCStr *string);
31 void bluesky_string_unref(BlueSkyRCStr *string);
32 BlueSkyRCStr *bluesky_string_dup(BlueSkyRCStr *string);
33
34 /* File types.  The numeric values are chosen to match with those used in
35  * NFSv3. */
36 typedef enum {
37     BLUESKY_REGULAR = 1,
38     BLUESKY_DIRECTORY = 2,
39     BLUESKY_BLOCK = 3,
40     BLUESKY_CHARACTER = 4,
41     BLUESKY_SYMLINK = 5,
42     BLUESKY_SOCKET = 6,
43     BLUESKY_FIFO = 7,
44 } BlueSkyFileType;
45
46 /* Filesystem state.  Each filesystem which is exported is represented by a
47  * single bluesky_fs structure in memory. */
48 typedef struct {
49     GMutex *lock;
50
51     gchar *name;                /* Descriptive name for the filesystem */
52     GHashTable *inodes;         /* Cached inodes */
53     uint64_t next_inum;         /* Next available inode for allocation */
54
55     struct S3Store *store;
56 } BlueSkyFS;
57
58 /* Inode number of the root directory. */
59 #define BLUESKY_ROOT_INUM 1
60
61 /* Timestamp, measured in microseconds since the Unix epoch. */
62 typedef int64_t bluesky_time;
63
64 /* In-memory representation of an inode within a Blue Sky server.  This
65  * corresponds roughly with information that is committed to persistent
66  * storage. */
67 typedef struct {
68     gint refcnt;                /* May be accessed atomically without lock */
69     GMutex *lock;
70
71     BlueSkyFS *fs;
72
73     BlueSkyFileType type;
74     uint32_t mode;
75     uint32_t uid, gid;
76     uint32_t nlink;
77
78     /* Rather than track an inode number and generation number, we will simply
79      * never re-use a fileid after a file is deleted.  64 bits should be enough
80      * that we don't exhaust the identifier space. */
81     uint64_t inum;
82
83     uint64_t change_count;      /* Incremented each with each change made */
84     int64_t atime;              /* Microseconds since the Unix epoch */
85     int64_t ctime;
86     int64_t mtime;
87     int64_t ntime;              /* "new time": time object was created */
88
89     /* File-specific fields */
90     uint64_t size;
91     GArray *blocks;
92
93     /* Directory-specific fields */
94     GSequence *dirents;         /* List of entries for READDIR */
95     GHashTable *dirhash;        /* Hash table by name for LOOKUP */
96     uint64_t parent_inum;       /* inode for ".."; 0 if the root directory */
97 } BlueSkyInode;
98
99 /* A directory entry.  The name is UTF-8 and is a freshly-allocated string.
100  * Each directory entry is listed in two indices: dirents is indexed by cookie
101  * and dirhash by name.  The cookie is a randomly-assigned 32-bit value, unique
102  * within the directory, that remains unchanged until the entry is deleted.  It
103  * is used to provide a stable key for restarting a READDIR call. */
104 typedef struct {
105     gchar *name;
106     uint32_t cookie;
107     uint64_t inum;
108 } BlueSkyDirent;
109
110 /* File data is divided into fixed-size blocks (except the last block which may
111  * be short?).  These blocks are backed by storage in a key/value store, but
112  * may also be dirty if modifications have been made in-memory that have not
113  * been committed. */
114 #define BLUESKY_BLOCK_SIZE 32768ULL
115 #define BLUESKY_MAX_FILE_SIZE (BLUESKY_BLOCK_SIZE << 24)
116 typedef enum {
117     BLUESKY_BLOCK_ZERO = 0,     /* Data is all zeroes, not explicitly stored */
118     BLUESKY_BLOCK_REF = 1,      /* Reference to key/value store, not cached */
119     BLUESKY_BLOCK_CACHED = 2,   /* Data is cached in memory, clean */
120     BLUESKY_BLOCK_DIRTY = 3,    /* Data needs to be committed to store */
121 } BlueSkyBlockType;
122
123 typedef struct {
124     BlueSkyBlockType type;
125     gchar *ref;                 /* Name of data block in the backing store */
126     BlueSkyRCStr *data;         /* Pointer to data in memory if cached */
127 } BlueSkyBlock;
128
129 BlueSkyFS *bluesky_new_fs(gchar *name);
130 int64_t bluesky_get_current_time();
131 void bluesky_inode_update_ctime(BlueSkyInode *inode, gboolean update_mtime);
132 uint64_t bluesky_fs_alloc_inode(BlueSkyFS *fs);
133 BlueSkyInode *bluesky_new_inode(uint64_t inum, BlueSkyFS *fs, BlueSkyFileType type);
134
135 BlueSkyInode *bluesky_get_inode(BlueSkyFS *fs, uint64_t inum);
136 void bluesky_insert_inode(BlueSkyFS *fs, BlueSkyInode *inode);
137
138 void bluesky_dirent_destroy(gpointer dirent);
139 uint64_t bluesky_directory_hash(gchar *name);
140 uint64_t bluesky_directory_lookup(BlueSkyInode *inode, gchar *name);
141 gboolean bluesky_directory_insert(BlueSkyInode *dir, gchar *name,
142                                   uint64_t inum);
143 void bluesky_directory_dump(BlueSkyInode *dir);
144
145 void bluesky_block_touch(BlueSkyInode *inode, uint64_t i);
146 void bluesky_block_fetch(BlueSkyFS *fs, BlueSkyBlock *block);
147 void bluesky_block_flush(BlueSkyFS *fs, BlueSkyBlock *block);
148 void bluesky_file_truncate(BlueSkyInode *inode, uint64_t size);
149 void bluesky_file_write(BlueSkyInode *inode, uint64_t offset,
150                         const char *data, gint len);
151 void bluesky_file_read(BlueSkyInode *inode, uint64_t offset,
152                        char *buf, gint len);
153
154 struct S3Store *s3store_new();
155 BlueSkyRCStr *s3store_get(struct S3Store *store, const gchar *key);
156 void s3store_put(struct S3Store *store, const gchar *key, BlueSkyRCStr *val);
157
158 #ifdef __cplusplus
159 }
160 #endif
161
162 #endif