{
GTimeVal t;
g_get_current_time(&t);
- return t.tv_sec * 1000000 + t.tv_usec;
+ return (int64_t)t.tv_sec * 1000000 + t.tv_usec;
+}
+
+/* Update an inode to indicate that a modification was made. This increases
+ * the change counter, updates the ctime to the current time, and optionally
+ * updates the mtime. */
+void bluesky_inode_update_ctime(BlueSkyInode *inode, gboolean update_mtime)
+{
+ int64_t now = bluesky_get_current_time();
+ inode->change_count++;
+ inode->ctime = now;
+ if (update_mtime)
+ inode->mtime = now;
}
/* Unfortunately a glib hash table is only guaranteed to be able to store
switch (type) {
case BLUESKY_REGULAR:
+ i->blocks = g_array_new(FALSE, TRUE, sizeof(BlueSkyBlock));
break;
case BLUESKY_DIRECTORY:
i->dirents = g_sequence_new(bluesky_dirent_destroy);
+ i->dirhash = g_hash_table_new(g_str_hash, g_str_equal);
+ break;
case BLUESKY_BLOCK:
case BLUESKY_CHARACTER:
case BLUESKY_SYMLINK:
g_hash_table_insert(fs->inodes, &inode->inum, inode);
g_mutex_unlock(fs->lock);
}
+
+/* Set the size of a file. This will truncate or extend the file as needed.
+ * Newly-allocated bytes are zeroed. */
+void bluesky_file_truncate(BlueSkyInode *inode, uint64_t size)
+{
+ g_return_if_fail(size <= BLUESKY_MAX_FILE_SIZE);
+
+ if (size == inode->size)
+ return;
+
+ uint64_t blocks = (size + BLUESKY_BLOCK_SIZE - 1) / BLUESKY_MAX_FILE_SIZE;
+
+ if (blocks > inode->blocks->len) {
+ /* Need to add new blocks to the end of a file. New block structures
+ * are automatically zeroed, which initializes them to be pointers to
+ * zero blocks so we don't need to do any more work. */
+ g_array_set_size(inode->blocks, blocks);
+ } else if (blocks < inode->blocks->len) {
+ /* Delete blocks from a file. Must reclaim memory. */
+ for (guint i = inode->blocks->len; i < blocks; i++) {
+ BlueSkyBlock *b = &g_array_index(inode->blocks, BlueSkyBlock, i);
+ g_free(b->ref);
+ g_free(b->data);
+ }
+ g_array_set_size(inode->blocks, blocks);
+ }
+
+ /* TODO: Zero out partial blocks if needed? */
+
+ inode->size = size;
+ inode->change_count++;
+}