+ bluesky_inode_flush(dir->fs, dir);
+
+ return TRUE;
+}
+
+/* Rename a file. If desired (if overwrite is true) and if the target already
+ * exists, it will be unlinked first. */
+gboolean bluesky_rename(BlueSkyInode *dir1, gchar *name1,
+ BlueSkyInode *dir2, gchar *name2,
+ gboolean case_sensitive,
+ gboolean overwrite)
+{
+ g_return_val_if_fail(dir1->type == BLUESKY_DIRECTORY, FALSE);
+ g_return_val_if_fail(dir2->type == BLUESKY_DIRECTORY, FALSE);
+
+ BlueSkyDirent *d1, *d2;
+
+ d1 = g_hash_table_lookup(case_sensitive ? dir1->dirhash
+ : dir1->dirhash_folded, name1);
+ d2 = g_hash_table_lookup(case_sensitive ? dir2->dirhash
+ : dir2->dirhash_folded, name2);
+
+ if (d1 == NULL)
+ return FALSE;
+
+ uint64_t inum = d1->inum;
+
+ /* Check that this rename does not cause a directory to be moved into one
+ * of its descendants, as that would create a loop of directories
+ * disconnected from the root. */
+ /* TODO */
+
+ if (d2 != NULL) {
+ if (!overwrite)
+ return FALSE;
+
+ bluesky_directory_remove(dir2, name2);
+
+ // TODO: Drop inode reference
+ }
+
+ bluesky_directory_remove(dir1, name1);
+ bluesky_directory_insert(dir2, name2, inum);