agendafs

A filesystem for your calendar.

git clone git://mccd.space/agendafs
commit 8012839b00211d0472286e7cac293fea40d79f12
parent ad9a15f657a08caea2c3183847021f6014540212
Author: Marc Coquand <marc@coquand.email>
Date:   Tue, 26 Aug 2025 16:20:07 +0200

Rename memory region to arena

Diffstat:
Magenda_entry.c | 10+++++-----
Magenda_entry.h | 4++--
Aarena.c | 188+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aarena.h | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mfuse_node.c | 220++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mfuse_node.h | 62+++++++++++++++++++++++++++++++-------------------------------
Mfuse_node_store.c | 4++--
Mfuse_node_store.h | 2+-
Mhashmap.c | 6+++---
Mhashmap.h | 4++--
Mical_extra.c | 42+++++++++++++++++++++---------------------
Mical_extra.h | 18+++++++++---------
Mmain.c | 143++++++++++++++++++++++++++++++++++++++++---------------------------------------
Dmregion.c | 188-------------------------------------------------------------------------------
Dmregion.h | 73-------------------------------------------------------------------------
Mpath.c | 16++++++++--------
Mpath.h | 12++++++------
Mtree.c | 4++--
Mtree.h | 4++--
19 files changed, 540 insertions(+), 536 deletions(-)
diff --git a/agenda_entry.c b/agenda_entry.c
@@ -1,5 +1,5 @@
 #include "agenda_entry.h"
-#include "mregion.h"
+#include "arena.h"
 #include "util.h"
 #include <dirent.h>
 #include <libical/ical.h>
@@ -43,11 +43,11 @@ free_agenda_entry(struct agenda_entry *entry)
 }
 
 struct agenda_entry *
-create_agenda_entry(memory_region *mreg, const char *filename,
+create_agenda_entry(arena *ar, const char *filename,
 		    const char *filename_vdir)
 {
-	struct agenda_entry *copy = rmalloc(mreg, sizeof(struct agenda_entry));
-	copy->filename = rstrdup(mreg, filename);
-	copy->filename_vdir = rstrdup(mreg, filename_vdir);
+	struct agenda_entry *copy = rmalloc(ar, sizeof(struct agenda_entry));
+	copy->filename = rstrdup(ar, filename);
+	copy->filename_vdir = rstrdup(ar, filename_vdir);
 	return copy;
 }
diff --git a/agenda_entry.h b/agenda_entry.h
@@ -2,7 +2,7 @@
 #define agenda_entry_h_INCLUDED
 
 #include "hashmap.h"
-#include "mregion.h"
+#include "arena.h"
 #include "path.h"
 #include "tree.h"
 #include "util.h"
@@ -37,7 +37,7 @@ void
 free_agenda_entry(struct agenda_entry *entry);
 
 struct agenda_entry *
-create_agenda_entry(memory_region *mreg, const char *filename,
+create_agenda_entry(arena *ar, const char *filename,
 		    const char *filename_vdir);
 #endif // agenda_entry_h_INCLUDED
 
diff --git a/arena.c b/arena.c
@@ -0,0 +1,188 @@
+#include "arena.h"
+#include "util.h"
+#include <assert.h>
+#include <libical/ical.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef void (*free_func_t)(void *);
+
+arena *
+create_arena(void)
+{
+	arena *region = xmalloc(sizeof(arena));
+	region->head = NULL;
+	return region;
+}
+
+void
+arena_register(arena *region, void *ptr, free_func_t free_func)
+{
+	assert(free_func);
+	memory_block *block = xmalloc(sizeof(memory_block));
+	block->ptr = ptr;
+	block->free_func = free_func;
+	block->next = region->head;
+	region->head = block;
+}
+
+void *
+rmalloc(arena *region, size_t size)
+{
+	void *ptr = xmalloc(size);
+	arena_register(region, ptr, free);
+	return ptr;
+}
+
+// Copies and null terminates a string
+char *
+rstrndup(arena *ar, const char *src, size_t len)
+{
+	char *buf = rmalloc(ar, len + 1);
+	memcpy(buf, src, len);
+	buf[len] = '\0';
+	return buf;
+}
+
+void
+free_all(arena *region)
+{
+	if (!region)
+		return;
+	memory_block *block = region->head;
+	while (block) {
+		memory_block *next = block->next;
+		if (block->free_func)
+			block->free_func(block->ptr);
+		free(block);
+		block = next;
+	}
+	region->head = NULL;
+	free(region);
+}
+
+// String functions
+char *
+rstrdup(arena *region, const char *str)
+{
+	char *copy = xstrdup(str);
+	arena_register(region, copy, free);
+	return copy;
+}
+
+char *
+rstrins(arena *region, const char *str, size_t offset, const char *buf,
+	size_t size)
+{
+	size_t str_len = strlen(str);
+
+	size_t previous_new_len = (offset <= str_len) ? offset : str_len;
+
+	char *result = NULL;
+	size_t result_len = 0;
+
+	FILE *stream = open_memstream(&result, &result_len);
+	assert(stream);
+
+	fwrite(str, 1, previous_new_len, stream);
+	fwrite(buf, 1, size, stream);
+
+	fclose(stream);
+
+	arena_register(region, result, free);
+
+	return result;
+}
+
+int
+rasprintf(arena *region, char **strp, const char *fmt, ...)
+{
+	// Calculate length
+	va_list args;
+	va_start(args, fmt);
+	int len = vsnprintf(NULL, 0, fmt, args);
+	va_end(args);
+
+	if (len < 0) {
+		*strp = NULL;
+		return -1;
+	}
+
+	char *buffer = rmalloc(region, len + 1);
+	va_start(args, fmt);
+	int ret = vsnprintf(buffer, len + 1, fmt, args);
+	va_end(args);
+	if (ret < 0) {
+		*strp = NULL;
+		return -1;
+	}
+	*strp = buffer;
+	return ret;
+}
+
+// iCal functions
+
+icalparser *
+ricalparser_new(arena *region)
+{
+	icalparser *p = icalparser_new();
+	arena_register(region, p, (void *)icalparser_free);
+	return p;
+}
+
+void
+ricalcomponent_free(icalcomponent *ic)
+{
+	if (ic)
+		icalcomponent_free(ic);
+}
+
+icalcomponent *
+ricalcomponent_empty(arena *region)
+{
+	icalcomponent *ic = NULL;
+	arena_register(region, ic, (void *)ricalcomponent_free);
+	return ic;
+}
+
+icalcomponent *
+ricalcomponent_new_clone(arena *region, icalcomponent *ic)
+{
+	icalcomponent *nic = icalcomponent_new_clone(ic);
+	arena_register(region, nic, (void *)ricalcomponent_free);
+	return nic;
+}
+
+icalcomponent *
+ricalcomponent_new_from_string(arena *region, const char *ic)
+{
+	icalcomponent *nic = icalcomponent_new_from_string(ic);
+	arena_register(region, nic, (void *)ricalcomponent_free);
+	return nic;
+}
+
+char *
+ricalcomponent_as_ical_string(arena *region, icalcomponent *ic)
+{
+	char *c = icalcomponent_as_ical_string(ic);
+	arena_register(region, c, free);
+	return c;
+}
+
+char *
+ricalcomponent_as_ical_string_r(arena *region, icalcomponent *ic)
+{
+	char *c = icalcomponent_as_ical_string_r(ic);
+	arena_register(region, c, free);
+	return c;
+}
+
+icalcomponent *
+ricalcomponent_new_vcalendar(arena *region)
+{
+	icalcomponent *new_comp = icalcomponent_new_vcalendar();
+	arena_register(region, new_comp, (void *)ricalcomponent_free);
+	return new_comp;
+}
diff --git a/arena.h b/arena.h
@@ -0,0 +1,76 @@
+#ifndef arena_h_INCLUDED
+#define arena_h_INCLUDED
+#include "util.h"
+#include <assert.h>
+#include <libical/ical.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef void (*free_func_t)(void *);
+
+typedef struct memory_block {
+	void *ptr;
+	free_func_t free_func;
+	struct memory_block *next;
+} memory_block;
+
+/*
+ * Dynamic arena allocator
+ */
+typedef struct {
+	memory_block *head;
+} arena;
+
+arena *
+create_arena(void);
+
+void
+arena_register(arena *region, void *ptr, free_func_t free_func);
+
+void *
+rmalloc(arena *region, size_t size);
+
+void
+free_all(arena *region);
+
+char *
+rstrndup(arena *ar, const char *src, size_t len);
+
+char *
+rstrins(arena *region, const char *str, size_t offset, const char *buf,
+	size_t size);
+// String functions
+char *
+rstrdup(arena *region, const char *str);
+
+int
+rasprintf(arena *region, char **strp, const char *fmt, ...);
+
+// iCal functions
+
+icalparser *
+ricalparser_new(arena *region);
+
+void
+ricalcomponent_free(icalcomponent *ic);
+
+icalcomponent *
+ricalcomponent_empty(arena *region);
+
+icalcomponent *
+ricalcomponent_new_clone(arena *region, icalcomponent *ic);
+
+icalcomponent *
+ricalcomponent_new_from_string(arena *region, const char *ic);
+
+char *
+ricalcomponent_as_ical_string(arena *region, icalcomponent *ic);
+
+char *
+ricalcomponent_as_ical_string_r(arena *region, icalcomponent *ic);
+
+icalcomponent *
+ricalcomponent_new_vcalendar(arena *region);
+#endif // mrgeion_h_INCLUDED
diff --git a/fuse_node.c b/fuse_node.c
@@ -2,7 +2,7 @@
 #include "fuse_node_store.h"
 #include "hashmap.h"
 #include "ical_extra.h"
-#include "mregion.h"
+#include "arena.h"
 #include "path.h"
 #include "tree.h"
 #include "util.h"
@@ -22,12 +22,12 @@
 #include <wordexp.h>
 
 struct tree_node *
-get_node_by_uuid(memory_region *mreg, const char *target_uuid)
+get_node_by_uuid(arena *ar, const char *target_uuid)
 {
 	char *filename_vdir = NULL;
 
 	// Filenames are uid.ics, so we levarage that
-	size_t wRes = rasprintf(mreg, &filename_vdir, "%s.ics", target_uuid);
+	size_t wRes = rasprintf(ar, &filename_vdir, "%s.ics", target_uuid);
 	assert(wRes != -1);
 
 	LOG("Looking for UID: '%s'", target_uuid);
@@ -40,7 +40,7 @@ get_node_by_uuid(memory_region *mreg, const char *target_uuid)
 }
 
 struct tree_node *
-get_node_by_path(memory_region *mreg, const char *path)
+get_node_by_path(arena *ar, const char *path)
 {
 	if (strcmp(path, "/") == 0) {
 		LOG("Is ROOT %s", path);
@@ -48,7 +48,7 @@ get_node_by_path(memory_region *mreg, const char *path)
 	}
 
 	char *segments[255];
-	size_t count = split_path(mreg, path, segments);
+	size_t count = split_path(ar, path, segments);
 
 	struct tree_node *current = fuse_root;
 
@@ -76,7 +76,7 @@ get_node_by_path(memory_region *mreg, const char *path)
 }
 
 bool
-node_is_directory(memory_region *mreg, const struct tree_node *node,
+node_is_directory(arena *ar, const struct tree_node *node,
 		  icalcomponent *node_ics)
 {
 	if (is_root_node(node) || node_has_children(node)) {
@@ -91,7 +91,7 @@ node_is_directory(memory_region *mreg, const struct tree_node *node,
 }
 
 size_t
-write_ical_file(memory_region *mreg, const struct tree_node *node,
+write_ical_file(arena *ar, const struct tree_node *node,
 		icalcomponent *ic)
 {
 
@@ -116,29 +116,29 @@ write_ical_file(memory_region *mreg, const struct tree_node *node,
 		icalcomponent_remove_property(inner, ical_descr_prop);
 	}
 
-	char *ical_str = ricalcomponent_as_ical_string_r(mreg, ic);
+	char *ical_str = ricalcomponent_as_ical_string_r(ar, ic);
 
-	int res = write_to_file(get_vdir_filepath(mreg, node), ical_str);
+	int res = write_to_file(get_vdir_filepath(ar, node), ical_str);
 
 	return res;
 }
 
 // Owner: ctx
 icalcomponent *
-get_icalcomponent_from_node(memory_region *mreg, const struct tree_node *n)
+get_icalcomponent_from_node(arena *ar, const struct tree_node *n)
 {
 	if (is_root_node(n)) {
 		return NULL;
 	}
 
-	const char *orig_path = get_vdir_filepath(mreg, n);
+	const char *orig_path = get_vdir_filepath(ar, n);
 	// TODO: Cache intermediate results within context
-	icalcomponent *ic = parse_ics_file(mreg, orig_path);
+	icalcomponent *ic = parse_ics_file(ar, orig_path);
 	return ic;
 }
 
 int
-write_parent_child_components(memory_region *mreg,
+write_parent_child_components(arena *ar,
 			      const struct tree_node *parent,
 			      icalcomponent *iparent,
 			      const struct tree_node *child,
@@ -146,12 +146,12 @@ write_parent_child_components(memory_region *mreg,
 {
 	LOG("Adding parent and child relation");
 	set_parent_child_relationship_to_component(iparent, ichild);
-	return write_ical_file(mreg, child, ichild);
+	return write_ical_file(ar, child, ichild);
 }
 
 // Writes ics component summary to the filename of the tree_node
 int
-update_summary(memory_region *mreg, icalcomponent *ics,
+update_summary(arena *ar, icalcomponent *ics,
 	       const struct tree_node *node)
 {
 	if (is_directory_component(ics)) {
@@ -159,29 +159,29 @@ update_summary(memory_region *mreg, icalcomponent *ics,
 	}
 	else {
 		char *filename_no_ext =
-		    without_file_extension(mreg, get_node_filename(node));
+		    without_file_extension(ar, get_node_filename(node));
 		icalcomponent_set_summary(ics, filename_no_ext);
 	}
 
-	return write_ical_file(mreg, node, ics);
+	return write_ical_file(ar, node, ics);
 }
 
 int
-update_node_file_extension(memory_region *mreg, icalcomponent *ics,
+update_node_file_extension(arena *ar, icalcomponent *ics,
 			   const struct tree_node *node)
 {
-	const char *ext = get_file_extension(mreg, get_node_filename(node));
+	const char *ext = get_file_extension(ar, get_node_filename(node));
 	if (!ext) {
 		return 0;
 	}
 	icalcomponent_set_file_extension(ics, ext);
-	return write_ical_file(mreg, node, ics);
+	return write_ical_file(ar, node, ics);
 }
 
 struct agenda_entry *
-parse_ics_to_agenda_entry(memory_region *mreg, const char *vdir_filepath)
+parse_ics_to_agenda_entry(arena *ar, const char *vdir_filepath)
 {
-	icalcomponent *component = parse_ics_file(mreg, vdir_filepath);
+	icalcomponent *component = parse_ics_file(ar, vdir_filepath);
 	if (component == NULL) {
 		LOG("No component");
 		return NULL;
@@ -202,7 +202,7 @@ parse_ics_to_agenda_entry(memory_region *mreg, const char *vdir_filepath)
 
 	char *filename = NULL;
 	if (is_directory_component(component)) {
-		filename = rstrdup(mreg, summary);
+		filename = rstrdup(ar, summary);
 	}
 	else {
 		LOG("GETTING FILE EXT");
@@ -214,24 +214,24 @@ parse_ics_to_agenda_entry(memory_region *mreg, const char *vdir_filepath)
 		}
 
 		if (strcmp(extension, "") == 0) {
-			filename = rstrdup(mreg, summary);
+			filename = rstrdup(ar, summary);
 		}
 		else {
-			rasprintf(mreg, &filename, "%s.%s", summary, extension);
+			rasprintf(ar, &filename, "%s.%s", summary, extension);
 		}
 	}
 
 	struct agenda_entry *e =
-	    create_agenda_entry(mreg, filename, get_filename(vdir_filepath));
+	    create_agenda_entry(ar, filename, get_filename(vdir_filepath));
 
 	return e;
 }
 
-// Owner: memory_region
+// Owner: arena
 struct agenda_entry *
-load_agenda_entry_from_ics_file(memory_region *mreg, const char *filename)
+load_agenda_entry_from_ics_file(arena *ar, const char *filename)
 {
-	path *filepath = append_path(mreg, VDIR, filename);
+	path *filepath = append_path(ar, VDIR, filename);
 	LOG("Filepath is %s", filepath);
 
 	struct stat fileStat;
@@ -241,7 +241,7 @@ load_agenda_entry_from_ics_file(memory_region *mreg, const char *filename)
 	}
 
 	struct agenda_entry *new_entry =
-	    parse_ics_to_agenda_entry(mreg, filepath);
+	    parse_ics_to_agenda_entry(ar, filepath);
 	if (!new_entry) {
 		LOG("Could not parse entry");
 		return NULL;
@@ -257,7 +257,7 @@ load_root_node_tree()
 {
 	entries_vdir = hashmap_new(NULL);
 	fuse_root = create_tree_node(NULL, NULL);
-	memory_region *mreg = create_region();
+	arena *ar = create_arena();
 	LOG("Loading journal entries from: %s\n", VDIR);
 
 	DIR *dir = opendir(VDIR);
@@ -275,7 +275,7 @@ load_root_node_tree()
 		if (entry->d_type == DT_REG && strstr(entry->d_name, ".ics")) {
 			LOG("Loading %s", entry->d_name);
 			struct agenda_entry *new_entry =
-			    load_agenda_entry_from_ics_file(mreg,
+			    load_agenda_entry_from_ics_file(ar,
 							    entry->d_name);
 			if (new_entry) {
 				create_fuse_node(new_entry);
@@ -299,7 +299,7 @@ load_root_node_tree()
 		    get_fuse_node_from_vdir_name(vdirname);
 
 		LOG("Parsing %s", vdirname);
-		icalcomponent *ic = get_icalcomponent_from_node(mreg, child);
+		icalcomponent *ic = get_icalcomponent_from_node(ar, child);
 		LOG("Success");
 
 		const char *parent_uid = get_parent_uid(ic);
@@ -307,13 +307,13 @@ load_root_node_tree()
 			LOG("Has parent");
 
 			struct tree_node *parent =
-			    get_node_by_uuid(mreg, parent_uid);
+			    get_node_by_uuid(ar, parent_uid);
 			if (parent) {
 				icalcomponent *pic =
-				    get_icalcomponent_from_node(mreg, parent);
+				    get_icalcomponent_from_node(ar, parent);
 				if (!is_directory_component(pic)) {
 					icalcomponent_mark_as_directory(pic);
-					assert(write_ical_file(mreg, parent,
+					assert(write_ical_file(ar, parent,
 							       pic) == 0);
 				}
 
@@ -331,14 +331,14 @@ load_root_node_tree()
 	LOG("Inserted %zu entries", n_keys);
 
 	hashmap_free_keys(keys, n_keys);
-	rfree_all(mreg);
+	free_all(ar);
 
 	LOG("Done");
 }
 
 // Sets a validated dtstart
 int
-set_dtstart(memory_region *mreg, const char *dtstart_c,
+set_dtstart(arena *ar, const char *dtstart_c,
 	    const struct tree_node *node)
 {
 	struct icaltimetype dtstart = icaltime_from_string(dtstart_c);
@@ -346,18 +346,18 @@ set_dtstart(memory_region *mreg, const char *dtstart_c,
 		return -EINVAL;
 	}
 
-	icalcomponent *comp = get_icalcomponent_from_node(mreg, node);
+	icalcomponent *comp = get_icalcomponent_from_node(ar, node);
 
 	icalcomponent_set_dtstart(comp, dtstart);
 
-	return write_ical_file(mreg, node, comp);
+	return write_ical_file(ar, node, comp);
 }
 
 const char *
-get_dtstart(memory_region *mreg, struct tree_node *n)
+get_dtstart(arena *ar, struct tree_node *n)
 {
 
-	icalcomponent *comp = get_icalcomponent_from_node(mreg, n);
+	icalcomponent *comp = get_icalcomponent_from_node(ar, n);
 
 	struct icaltimetype dtstart = icalcomponent_get_dtstart(comp);
 	if (icaltime_compare(dtstart, icaltime_null_time()) == 0) {
@@ -369,9 +369,9 @@ get_dtstart(memory_region *mreg, struct tree_node *n)
 }
 
 int
-clear_dtstart(memory_region *mreg, struct tree_node *node)
+clear_dtstart(arena *ar, struct tree_node *node)
 {
-	icalcomponent *comp = get_icalcomponent_from_node(mreg, node);
+	icalcomponent *comp = get_icalcomponent_from_node(ar, node);
 
 	icalproperty *p =
 	    icalcomponent_get_first_property(comp, ICAL_DTSTART_PROPERTY);
@@ -380,7 +380,7 @@ clear_dtstart(memory_region *mreg, struct tree_node *node)
 		icalcomponent_remove_property(comp, p);
 	}
 
-	return write_ical_file(mreg, node, comp);
+	return write_ical_file(ar, node, comp);
 }
 
 static int
@@ -400,17 +400,17 @@ append_category_to_memstream(FILE *memstream, const char *category,
 
 // Returns comma separated list of categories for a file
 char *
-get_node_categories(memory_region *mreg, const struct tree_node *node)
+get_node_categories(arena *ar, const struct tree_node *node)
 {
 	// TODO: Take this as parameter instead...
-	icalcomponent *component = get_icalcomponent_from_node(mreg, node);
+	icalcomponent *component = get_icalcomponent_from_node(ar, node);
 	if (!component) {
 		return NULL;
 	}
 
 	FILE *memstream = NULL;
 	char *result_buffer = NULL;
-	region_register(mreg, result_buffer, free);
+	arena_register(ar, result_buffer, free);
 	size_t buffer_size = 0;
 
 	memstream = open_memstream(&result_buffer, &buffer_size);
@@ -438,9 +438,9 @@ get_node_categories(memory_region *mreg, const struct tree_node *node)
 }
 
 int
-delete_node_categories(memory_region *mreg, const struct tree_node *node)
+delete_node_categories(arena *ar, const struct tree_node *node)
 {
-	icalcomponent *component = get_icalcomponent_from_node(mreg, node);
+	icalcomponent *component = get_icalcomponent_from_node(ar, node);
 	if (!component) {
 		return 0;
 	}
@@ -458,14 +458,14 @@ delete_node_categories(memory_region *mreg, const struct tree_node *node)
 		    inner, ICAL_CATEGORIES_PROPERTY);
 	}
 
-	return write_ical_file(mreg, node, component);
+	return write_ical_file(ar, node, component);
 }
 
 int
-set_node_categories(memory_region *mreg, const struct tree_node *node,
+set_node_categories(arena *ar, const struct tree_node *node,
 		    const char *new_categories, size_t s)
 {
-	icalcomponent *component = get_icalcomponent_from_node(mreg, node);
+	icalcomponent *component = get_icalcomponent_from_node(ar, node);
 	if (!component) {
 		return 0;
 	}
@@ -482,24 +482,24 @@ set_node_categories(memory_region *mreg, const struct tree_node *node,
 	}
 
 	if (s == 0) {
-		return write_ical_file(mreg, node, component);
+		return write_ical_file(ar, node, component);
 	}
 
-	char *null_terminated_categories = rstrndup(mreg, new_categories, s);
+	char *null_terminated_categories = rstrndup(ar, new_categories, s);
 
 	icalproperty *new_cat_prop =
 	    icalproperty_new_categories(null_terminated_categories);
 	icalcomponent_add_property(inner, new_cat_prop);
 
-	return write_ical_file(mreg, node, component);
+	return write_ical_file(ar, node, component);
 }
 
 const char *
-get_node_class(memory_region *mreg, const struct tree_node *node)
+get_node_class(arena *ar, const struct tree_node *node)
 {
 
 	// TODO: Take this as parameter instead...
-	icalcomponent *component = get_icalcomponent_from_node(mreg, node);
+	icalcomponent *component = get_icalcomponent_from_node(ar, node);
 	if (!component) {
 		return 0;
 	}
@@ -518,11 +518,11 @@ get_node_class(memory_region *mreg, const struct tree_node *node)
 }
 
 const char *
-get_node_status(memory_region *mreg, const struct tree_node *node)
+get_node_status(arena *ar, const struct tree_node *node)
 {
 
 	// TODO: Take this as parameter instead...
-	icalcomponent *component = get_icalcomponent_from_node(mreg, node);
+	icalcomponent *component = get_icalcomponent_from_node(ar, node);
 	if (!component) {
 		return 0;
 	}
@@ -543,9 +543,9 @@ get_node_status(memory_region *mreg, const struct tree_node *node)
 }
 
 int
-delete_node_class(memory_region *mreg, const struct tree_node *node)
+delete_node_class(arena *ar, const struct tree_node *node)
 {
-	icalcomponent *component = get_icalcomponent_from_node(mreg, node);
+	icalcomponent *component = get_icalcomponent_from_node(ar, node);
 	if (!component) {
 		return 0;
 	}
@@ -555,14 +555,14 @@ delete_node_class(memory_region *mreg, const struct tree_node *node)
 
 	icalcomponent_remove_property(inner, prop);
 
-	return write_ical_file(mreg, node, component);
+	return write_ical_file(ar, node, component);
 }
 
 int
-set_node_class(memory_region *mreg, const struct tree_node *node,
+set_node_class(arena *ar, const struct tree_node *node,
 	       const icalproperty_class new_class)
 {
-	icalcomponent *component = get_icalcomponent_from_node(mreg, node);
+	icalcomponent *component = get_icalcomponent_from_node(ar, node);
 	if (!component) {
 		return 0;
 	}
@@ -577,42 +577,42 @@ set_node_class(memory_region *mreg, const struct tree_node *node,
 	icalproperty *new_class_prop = icalproperty_new_class(new_class);
 	icalcomponent_add_property(inner, new_class_prop);
 
-	return write_ical_file(mreg, node, component);
+	return write_ical_file(ar, node, component);
 }
 
 int
-set_node_status(memory_region *mreg, const struct tree_node *node,
+set_node_status(arena *ar, const struct tree_node *node,
 		const icalproperty_status new_status)
 {
-	icalcomponent *component = get_icalcomponent_from_node(mreg, node);
+	icalcomponent *component = get_icalcomponent_from_node(ar, node);
 	if (!component) {
 		return 0;
 	}
 
 	icalcomponent_set_status(component, new_status);
 
-	return write_ical_file(mreg, node, component);
+	return write_ical_file(ar, node, component);
 }
 
 size_t
-calculate_node_size(memory_region *mreg, const struct tree_node *node,
+calculate_node_size(arena *ar, const struct tree_node *node,
 		    icalcomponent *node_component)
 {
-	if (!node_is_directory(mreg, node, node_component)) {
+	if (!node_is_directory(ar, node, node_component)) {
 		return icalcomponent_get_description_size(node_component);
 	}
 
 	size_t total_size = 0;
 	for (int i = 0; i < node->child_count; i++) {
 		icalcomponent *cic =
-		    get_icalcomponent_from_node(mreg, node->children[i]);
-		total_size += calculate_node_size(mreg, node->children[i], cic);
+		    get_icalcomponent_from_node(ar, node->children[i]);
+		total_size += calculate_node_size(ar, node->children[i], cic);
 	}
 	return total_size;
 }
 
 struct stat
-get_node_stat(memory_region *mreg, const struct tree_node *node,
+get_node_stat(arena *ar, const struct tree_node *node,
 	      icalcomponent *node_component)
 {
 	if (is_root_node(node)) {
@@ -624,12 +624,12 @@ get_node_stat(memory_region *mreg, const struct tree_node *node,
 	}
 	else {
 		struct stat vdir_stat = {0};
-		const char *vdir_path = get_vdir_filepath(mreg, node);
+		const char *vdir_path = get_vdir_filepath(ar, node);
 		int res = stat(vdir_path, &vdir_stat);
 		assert(res == 0);
-		if (node_is_directory(mreg, node, node_component)) {
+		if (node_is_directory(ar, node, node_component)) {
 			vdir_stat.st_size = (off_t)calculate_node_size(
-			    mreg, node, node_component);
+			    ar, node, node_component);
 			vdir_stat.st_mode = S_IFDIR | 0444;
 			vdir_stat.st_nlink = 2;
 		}
@@ -647,33 +647,33 @@ get_node_stat(memory_region *mreg, const struct tree_node *node,
 }
 
 int
-insert_fuse_node_to_path(memory_region *mreg, const char *fuse_path,
+insert_fuse_node_to_path(arena *ar, const char *fuse_path,
 			 struct tree_node *child_node, icalcomponent *child_ics)
 {
-	char *parent_path = get_parent_path(mreg, fuse_path);
+	char *parent_path = get_parent_path(ar, fuse_path);
 	int status = 0;
 	LOG("Parent path is %s", parent_path);
 
-	struct tree_node *parent_node = get_node_by_path(mreg, parent_path);
+	struct tree_node *parent_node = get_node_by_path(ar, parent_path);
 	if (!parent_node) {
 		LOG("Parent does not exist");
 		return -ENOENT;
 	}
 
 	icalcomponent *parent_ics =
-	    get_icalcomponent_from_node(mreg, parent_node);
+	    get_icalcomponent_from_node(ar, parent_node);
 
-	if (!node_is_directory(mreg, parent_node, parent_ics)) {
+	if (!node_is_directory(ar, parent_node, parent_ics)) {
 		LOG("Parent is not a directory");
 		return -ENOTDIR;
 	}
 
 	if (parent_ics) {
 		status = write_parent_child_components(
-		    mreg, parent_node, parent_ics, child_node, child_ics);
+		    ar, parent_node, parent_ics, child_node, child_ics);
 	}
 	else {
-		write_ical_file(mreg, child_node, child_ics);
+		write_ical_file(ar, child_node, child_ics);
 	}
 
 	add_child(parent_node, child_node);
@@ -683,7 +683,7 @@ insert_fuse_node_to_path(memory_region *mreg, const char *fuse_path,
 enum ENTRY_TYPE { ENTRY_DIRECTORY, ENTRY_FILE };
 
 int
-create_entry_from_fuse(memory_region *mreg, const char *fuse_path,
+create_entry_from_fuse(arena *ar, const char *fuse_path,
 		       enum ENTRY_TYPE etype)
 {
 	const char *entry_prefix = "/";
@@ -696,37 +696,37 @@ create_entry_from_fuse(memory_region *mreg, const char *fuse_path,
 
 	switch (etype) {
 	case (ENTRY_DIRECTORY):
-		new_component = create_vjournal_directory(mreg, new_filename);
+		new_component = create_vjournal_directory(ar, new_filename);
 		break;
 	case (ENTRY_FILE):
-		new_component = create_vjournal_entry(mreg, new_filename);
+		new_component = create_vjournal_entry(ar, new_filename);
 		break;
 	}
 
 	char *new_filname_vdir = NULL;
-	rasprintf(mreg, &new_filname_vdir, "%s.ics",
+	rasprintf(ar, &new_filname_vdir, "%s.ics",
 		  icalcomponent_get_uid(new_component));
 
 	struct agenda_entry *new_entry =
-	    create_agenda_entry(mreg, new_filename, new_filname_vdir);
+	    create_agenda_entry(ar, new_filename, new_filname_vdir);
 
 	LOG("Inserting vjournal directory");
 
 	struct tree_node *new_node = create_fuse_node(new_entry);
 
-	return insert_fuse_node_to_path(mreg, fuse_path, new_node,
+	return insert_fuse_node_to_path(ar, fuse_path, new_node,
 					new_component);
 }
 
 int
-update_or_create_fuse_entry_from_vdir(memory_region *mreg,
+update_or_create_fuse_entry_from_vdir(arena *ar,
 				      const char *filepath_vdir)
 {
 	const char *filename_vdir = get_filename(filepath_vdir);
 	LOG("Filename original is %s", filename_vdir);
 
 	struct agenda_entry *updated_entry =
-	    load_agenda_entry_from_ics_file(mreg, filename_vdir);
+	    load_agenda_entry_from_ics_file(ar, filename_vdir);
 
 	if (!updated_entry) {
 		return -EIO;
@@ -734,21 +734,21 @@ update_or_create_fuse_entry_from_vdir(memory_region *mreg,
 
 	struct tree_node *node = upsert_fuse_node(updated_entry);
 
-	icalcomponent *entry_ics = get_icalcomponent_from_node(mreg, node);
+	icalcomponent *entry_ics = get_icalcomponent_from_node(ar, node);
 
 	const char *new_parent_uid = get_parent_uid(entry_ics);
 
 	if (new_parent_uid) {
 		LOG("Has parent");
 		struct tree_node *new_parent =
-		    get_node_by_uuid(mreg, new_parent_uid);
+		    get_node_by_uuid(ar, new_parent_uid);
 		move_fuse_node(new_parent, node);
 
 		icalcomponent *pic =
-		    get_icalcomponent_from_node(mreg, new_parent);
+		    get_icalcomponent_from_node(ar, new_parent);
 		if (!is_directory_component(pic)) {
 			icalcomponent_mark_as_directory(pic);
-			assert(write_ical_file(mreg, new_parent, pic) == 0);
+			assert(write_ical_file(ar, new_parent, pic) == 0);
 		}
 	}
 	else {
@@ -761,9 +761,9 @@ update_or_create_fuse_entry_from_vdir(memory_region *mreg,
 }
 
 int
-do_agenda_rename(memory_region *mreg, const char *old, const char *new)
+do_agenda_rename(arena *ar, const char *old, const char *new)
 {
-	char *new_copy = rstrdup(mreg, new);
+	char *new_copy = rstrdup(ar, new);
 	const char *new_filename = get_filename(new_copy);
 
 	const char *old_filename = get_filename(old);
@@ -771,29 +771,29 @@ do_agenda_rename(memory_region *mreg, const char *old, const char *new)
 		return -EINVAL;
 
 	struct tree_node *new_parent_node =
-	    get_node_by_path(mreg, get_parent_path(mreg, new));
+	    get_node_by_path(ar, get_parent_path(ar, new));
 
 	if (new_parent_node == NULL) {
 		return -EINVAL;
 	}
 
-	struct tree_node *child_node = get_node_by_path(mreg, old);
+	struct tree_node *child_node = get_node_by_path(ar, old);
 	assert(child_node);
 
 	icalcomponent *child_ics =
-	    get_icalcomponent_from_node(mreg, child_node);
+	    get_icalcomponent_from_node(ar, child_node);
 	assert(child_ics);
 
 	icalcomponent *new_parent_ics =
-	    get_icalcomponent_from_node(mreg, new_parent_node);
+	    get_icalcomponent_from_node(ar, new_parent_node);
 
 	struct tree_node *old_parent_node = child_node->parent;
 	icalcomponent *old_parent_ics =
-	    get_icalcomponent_from_node(mreg, old_parent_node);
+	    get_icalcomponent_from_node(ar, old_parent_node);
 
 	set_node_filename(child_node, new_filename);
-	update_summary(mreg, child_ics, child_node);
-	update_node_file_extension(mreg, child_ics, child_node);
+	update_summary(ar, child_ics, child_node);
+	update_node_file_extension(ar, child_ics, child_node);
 
 	if (old_parent_node && old_parent_ics) {
 		remove_parent_child_relationship_from_component(old_parent_ics,
@@ -802,7 +802,7 @@ do_agenda_rename(memory_region *mreg, const char *old, const char *new)
 
 	if (new_parent_ics) {
 		move_node(new_parent_node, child_node);
-		write_parent_child_components(mreg, new_parent_node,
+		write_parent_child_components(ar, new_parent_node,
 					      new_parent_ics, child_node,
 					      child_ics);
 	}
@@ -813,11 +813,11 @@ do_agenda_rename(memory_region *mreg, const char *old, const char *new)
 }
 
 int
-delete_vdir_entry(memory_region *mreg, struct tree_node *node)
+delete_vdir_entry(arena *ar, struct tree_node *node)
 {
 	int res = 0;
 
-	const char *filepath_original = get_vdir_filepath(mreg, node);
+	const char *filepath_original = get_vdir_filepath(ar, node);
 
 	LOG("Deleting file %s", filepath_original);
 
@@ -832,10 +832,10 @@ delete_vdir_entry(memory_region *mreg, struct tree_node *node)
 
 // Caller needs to ensure the node has no children.
 int
-delete_from_vdir_path(memory_region *mreg, const char *filepath)
+delete_from_vdir_path(arena *ar, const char *filepath)
 {
 
-	struct tree_node *node = get_node_by_uuid(mreg, filepath);
+	struct tree_node *node = get_node_by_uuid(ar, filepath);
 	if (!node) {
 		return -ENOENT;
 	}
diff --git a/fuse_node.h b/fuse_node.h
@@ -5,7 +5,7 @@
 #include "fuse_node_store.h"
 #include "hashmap.h"
 #include "ical_extra.h"
-#include "mregion.h"
+#include "arena.h"
 #include "path.h"
 #include "tree.h"
 #include "util.h"
@@ -25,25 +25,25 @@
 #include <wordexp.h>
 
 struct tree_node *
-get_node_by_uuid(memory_region *mreg, const char *target_uuid);
+get_node_by_uuid(arena *ar, const char *target_uuid);
 
 struct tree_node *
-get_node_by_path(memory_region *mreg, const char *path);
+get_node_by_path(arena *ar, const char *path);
 
 bool
-node_is_directory(memory_region *mreg, const struct tree_node *node,
+node_is_directory(arena *ar, const struct tree_node *node,
 		  icalcomponent *node_ics);
 
 size_t
-write_ical_file(memory_region *mreg, const struct tree_node *node,
+write_ical_file(arena *ar, const struct tree_node *node,
 		icalcomponent *ic);
 
 // Owner: ctx
 icalcomponent *
-get_icalcomponent_from_node(memory_region *mreg, const struct tree_node *n);
+get_icalcomponent_from_node(arena *ar, const struct tree_node *n);
 
 int
-write_parent_child_components(memory_region *mreg,
+write_parent_child_components(arena *ar,
 			      const struct tree_node *parent,
 			      icalcomponent *iparent,
 			      const struct tree_node *child,
@@ -51,89 +51,89 @@ write_parent_child_components(memory_region *mreg,
 
 // Writes ics component summary to the filename of the tree_node
 int
-update_summary(memory_region *mreg, icalcomponent *ics,
+update_summary(arena *ar, icalcomponent *ics,
 	       const struct tree_node *node);
 
 struct agenda_entry *
-parse_ics_to_agenda_entry(memory_region *mreg, const char *vdir_filepath);
+parse_ics_to_agenda_entry(arena *ar, const char *vdir_filepath);
 
-// agenda_entry is automatically cleaned up by mreg, use copy_agenda_entry
+// agenda_entry is automatically cleaned up by ar, use copy_agenda_entry
 // to take ownership!
 struct agenda_entry *
-load_agenda_entry_from_ics_file(memory_region *mreg, const char *filename);
+load_agenda_entry_from_ics_file(arena *ar, const char *filename);
 
 void
 load_root_node_tree();
 
 // Returns comma separated list of categories for a file
 char *
-get_node_categories(memory_region *mreg, const struct tree_node *node);
+get_node_categories(arena *ar, const struct tree_node *node);
 
 int
-delete_node_categories(memory_region *mreg, const struct tree_node *node);
+delete_node_categories(arena *ar, const struct tree_node *node);
 
 int
-set_node_categories(memory_region *mreg, const struct tree_node *node,
+set_node_categories(arena *ar, const struct tree_node *node,
 		    const char *new_categories, size_t s);
 
 const char *
-get_node_class(memory_region *mreg, const struct tree_node *node);
+get_node_class(arena *ar, const struct tree_node *node);
 
 const char *
-get_node_status(memory_region *mreg, const struct tree_node *node);
+get_node_status(arena *ar, const struct tree_node *node);
 
 int
-delete_node_class(memory_region *mreg, const struct tree_node *node);
+delete_node_class(arena *ar, const struct tree_node *node);
 
 int
-set_node_class(memory_region *mreg, const struct tree_node *node,
+set_node_class(arena *ar, const struct tree_node *node,
 	       const icalproperty_class new_class);
 
 int
-set_node_status(memory_region *mreg, const struct tree_node *node,
+set_node_status(arena *ar, const struct tree_node *node,
 		const icalproperty_status new_status);
 
 struct stat
-get_node_stat(memory_region *mreg, const struct tree_node *node,
+get_node_stat(arena *ar, const struct tree_node *node,
 	      icalcomponent *node_component);
 
 int
-insert_fuse_node_to_path(memory_region *mreg, const char *fuse_path,
+insert_fuse_node_to_path(arena *ar, const char *fuse_path,
 			 struct tree_node *child_node,
 			 icalcomponent *child_ics);
 
 enum ENTRY_TYPE { ENTRY_DIRECTORY, ENTRY_FILE };
 
 int
-create_entry_from_fuse(memory_region *mreg, const char *fuse_path,
+create_entry_from_fuse(arena *ar, const char *fuse_path,
 		       enum ENTRY_TYPE etype);
 
 const char *
-get_dtstart(memory_region *mreg, struct tree_node *n);
+get_dtstart(arena *ar, struct tree_node *n);
 
 int
-set_dtstart(memory_region *mreg, const char *dtstart_c,
+set_dtstart(arena *ar, const char *dtstart_c,
 	    const struct tree_node *node);
 
 int
-clear_dtstart(memory_region *mreg, struct tree_node *node);
+clear_dtstart(arena *ar, struct tree_node *node);
 int
-create_directory_from_fuse_path(memory_region *mreg, const char *fuse_path);
+create_directory_from_fuse_path(arena *ar, const char *fuse_path);
 
 void
-update_or_create_fuse_entry_from_vdir(memory_region *mreg,
+update_or_create_fuse_entry_from_vdir(arena *ar,
 				      const char *filepath_vdir);
 
 int
-delete_dir_from_fuse_path(memory_region *mreg, const char *filepath);
+delete_dir_from_fuse_path(arena *ar, const char *filepath);
 
 int
-do_agenda_rename(memory_region *mreg, const char *, const char *);
+do_agenda_rename(arena *ar, const char *, const char *);
 
 int
-delete_vdir_entry(memory_region *mreg, struct tree_node *node);
+delete_vdir_entry(arena *ar, struct tree_node *node);
 
 int
-delete_from_vdir_path(memory_region *mreg, const char *filepath);
+delete_from_vdir_path(arena *ar, const char *filepath);
 
 #endif // fuse_node_h_INCLUDED
diff --git a/fuse_node_store.c b/fuse_node_store.c
@@ -82,10 +82,10 @@ get_node_filename(const struct tree_node *node)
 }
 
 const char *
-get_vdir_filepath(memory_region *mreg, const struct tree_node *node)
+get_vdir_filepath(arena *ar, const struct tree_node *node)
 {
 	const struct agenda_entry *entry = get_entry(node);
-	return append_path(mreg, VDIR, entry->filename_vdir);
+	return append_path(ar, VDIR, entry->filename_vdir);
 }
 
 void
diff --git a/fuse_node_store.h b/fuse_node_store.h
@@ -27,7 +27,7 @@ const struct agenda_entry *
 get_entry(const struct tree_node *node);
 
 const char *
-get_vdir_filepath(memory_region *mreg, const struct tree_node *node);
+get_vdir_filepath(arena *ar, const struct tree_node *node);
 
 bool
 is_root_node(const struct tree_node *node);
diff --git a/hashmap.c b/hashmap.c
@@ -1,7 +1,7 @@
 // Taken from https://github.com/prismz/hashmap
 #include "hashmap.h"
 
-#include "mregion.h"
+#include "arena.h"
 #include <assert.h>
 #include <inttypes.h>
 #include <stdint.h>
@@ -435,11 +435,11 @@ hashmap_free_keys(char **keys, size_t n_keys)
 }
 
 struct hashmap *
-rhashmap_new(memory_region *region, void (*val_free_func)(void *))
+rhashmap_new(arena *region, void (*val_free_func)(void *))
 {
 	struct hashmap *h = hashmap_new(val_free_func);
 	assert(h);
 
-	region_register(region, h, (void *)hashmap_free);
+	arena_register(region, h, (void *)hashmap_free);
 	return h;
 }
diff --git a/hashmap.h b/hashmap.h
@@ -3,7 +3,7 @@
 #ifndef HASHMAP_H
 #define HASHMAP_H
 
-#include "mregion.h"
+#include "arena.h"
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -74,5 +74,5 @@ hashmap_get_keys(struct hashmap *hm, size_t *n_keys);
 void
 hashmap_free_keys(char **keys, size_t n_keys);
 struct hashmap *
-rhashmap_new(memory_region *region, void (*val_free_func)(void *));
+rhashmap_new(arena *region, void (*val_free_func)(void *));
 #endif /* HASHMAP_H */
diff --git a/ical_extra.c b/ical_extra.c
@@ -1,6 +1,6 @@
 #include "ical_extra.h"
 #include "libical/ical.h"
-#include "mregion.h"
+#include "arena.h"
 #include "path.h"
 #include "sys/stat.h"
 #include "util.h"
@@ -128,7 +128,7 @@ is_directory_component(icalcomponent *component)
 }
 
 icalcomponent *
-parse_ics_file(memory_region *mreg, const char *filename)
+parse_ics_file(arena *ar, const char *filename)
 {
 
 	FILE *file = fopen(filename, "r");
@@ -139,13 +139,13 @@ parse_ics_file(memory_region *mreg, const char *filename)
 	assert(stat(filename, &st) == 0);
 
 	size_t size = st.st_size;
-	char *buffer = rmalloc(mreg, size + 1);
+	char *buffer = rmalloc(ar, size + 1);
 
 	size_t bytes_read = fread(buffer, 1, size, file);
 	buffer[bytes_read] = '\0';
 	fclose(file);
 
-	icalcomponent *component = ricalcomponent_new_from_string(mreg, buffer);
+	icalcomponent *component = ricalcomponent_new_from_string(ar, buffer);
 
 	return component;
 }
@@ -171,21 +171,21 @@ icalcomponent_get_description_size(icalcomponent *component)
 }
 
 char *
-create_new_unique_ics_uid(memory_region *mreg)
+create_new_unique_ics_uid(arena *ar)
 {
 	uuid_t uuid;
 	char uuid_str[37]; // UUIDs are 36 characters + null terminator
 	uuid_generate(uuid);
 	uuid_unparse(uuid, uuid_str);
 	char *res = NULL;
-	size_t wRes = rasprintf(mreg, &res, "%s-caldavfs", uuid_str);
+	size_t wRes = rasprintf(ar, &res, "%s-caldavfs", uuid_str);
 	assert(wRes != -1);
 
 	return res;
 }
 
 icalcomponent *
-create_vjournal_directory(memory_region *mreg, const char *summary)
+create_vjournal_directory(arena *ar, const char *summary)
 {
 
 	icalcomponent *calendar = icalcomponent_new_vcalendar();
@@ -195,7 +195,7 @@ create_vjournal_directory(memory_region *mreg, const char *summary)
 				   icalproperty_new_prodid("-//caldavfs//EN"));
 
 	icalcomponent *journal = icalcomponent_new_vjournal();
-	char *id = create_new_unique_ics_uid(mreg);
+	char *id = create_new_unique_ics_uid(ar);
 
 	icalcomponent_add_property(journal, icalproperty_new_uid(id));
 
@@ -218,10 +218,10 @@ create_vjournal_directory(memory_region *mreg, const char *summary)
 }
 
 icalcomponent *
-create_vjournal_entry(memory_region *mreg, const char *summary)
+create_vjournal_entry(arena *ar, const char *summary)
 {
 
-	icalcomponent *calendar = ricalcomponent_new_vcalendar(mreg);
+	icalcomponent *calendar = ricalcomponent_new_vcalendar(ar);
 
 	icalcomponent_add_property(calendar, icalproperty_new_version("2.0"));
 	icalcomponent_add_property(calendar,
@@ -229,7 +229,7 @@ create_vjournal_entry(memory_region *mreg, const char *summary)
 
 	// Step 2: Create a VJOURNAL entry
 	icalcomponent *journal = icalcomponent_new_vjournal();
-	char *id = create_new_unique_ics_uid(mreg);
+	char *id = create_new_unique_ics_uid(ar);
 
 	icalcomponent_add_property(journal, icalproperty_new_uid(id));
 	icalcomponent_add_property(journal,
@@ -238,7 +238,7 @@ create_vjournal_entry(memory_region *mreg, const char *summary)
 	icalcomponent_add_property(
 	    journal, icalproperty_new_dtstamp(icaltime_current_time_with_zone(
 			 icaltimezone_get_utc_timezone())));
-	char *file_extension = get_file_extension(mreg, summary);
+	char *file_extension = get_file_extension(ar, summary);
 	if (!file_extension) {
 		file_extension = "";
 	}
@@ -247,7 +247,7 @@ create_vjournal_entry(memory_region *mreg, const char *summary)
 
 	icalcomponent_set_status(journal, ICAL_STATUS_DRAFT);
 
-	char *without_extension = without_file_extension(mreg, summary);
+	char *without_extension = without_file_extension(ar, summary);
 
 	icalcomponent_add_property(journal,
 				   icalproperty_new_summary(without_extension));
@@ -327,7 +327,7 @@ set_parent_child_relationship_to_component(icalcomponent *parent,
 }
 
 void
-icalcomponent_insert_description(memory_region *mreg, icalcomponent *ic,
+icalcomponent_insert_description(arena *ar, icalcomponent *ic,
 				 const char *buf, size_t size, off_t offset)
 {
 
@@ -335,7 +335,7 @@ icalcomponent_insert_description(memory_region *mreg, icalcomponent *ic,
 	if (!old_desc)
 		old_desc = "";
 
-	char *new_desc = rstrins(mreg, old_desc, offset, buf, size);
+	char *new_desc = rstrins(ar, old_desc, offset, buf, size);
 	icalcomponent_set_description(ic, new_desc);
 }
 
@@ -393,12 +393,12 @@ icalcomponent_print_x_props(FILE *memstream, icalcomponent *component)
 }
 
 void
-icalcomponent_remove_custom_prop(memory_region *mreg, icalcomponent *component,
+icalcomponent_remove_custom_prop(arena *ar, icalcomponent *component,
 				 const char *key)
 {
 
 	char *x_key = NULL;
-	rasprintf(mreg, &x_key, "%s%s", CUSTOM_PROPERTY_PREFIX, key);
+	rasprintf(ar, &x_key, "%s%s", CUSTOM_PROPERTY_PREFIX, key);
 	icalcomponent_remove_x_prop(component, x_key);
 }
 
@@ -418,21 +418,21 @@ icalcomponent_set_unique_x_value(icalcomponent *component, const char *key,
 	icalcomponent_add_property(inner, fileext_prop);
 }
 void
-icalcomponent_set_custom_x_value(memory_region *mreg, icalcomponent *component,
+icalcomponent_set_custom_x_value(arena *ar, icalcomponent *component,
 				 const char *key, const char *value)
 {
 	char *x_key = NULL;
-	rasprintf(mreg, &x_key, "%s%s", CUSTOM_PROPERTY_PREFIX, key);
+	rasprintf(ar, &x_key, "%s%s", CUSTOM_PROPERTY_PREFIX, key);
 
 	icalcomponent_set_unique_x_value(component, x_key, value);
 }
 
 const char *
-icalcomponent_get_custom_x_value(memory_region *mreg, icalcomponent *component,
+icalcomponent_get_custom_x_value(arena *ar, icalcomponent *component,
 				 const char *key)
 {
 	char *x_key = NULL;
-	rasprintf(mreg, &x_key, "%s%s", CUSTOM_PROPERTY_PREFIX, key);
+	rasprintf(ar, &x_key, "%s%s", CUSTOM_PROPERTY_PREFIX, key);
 
 	return icalcomponent_get_uniq_x_value(component, x_key);
 }
diff --git a/ical_extra.h b/ical_extra.h
@@ -1,7 +1,7 @@
 #ifndef ical_extra_h_INCLUDED
 #define ical_extra_h_INCLUDED
 #include "libical/ical.h"
-#include "mregion.h"
+#include "arena.h"
 #include "sys/stat.h"
 #include "uuid/uuid.h"
 #include <stdbool.h>
@@ -14,7 +14,7 @@ is_directory_component(icalcomponent *component);
 
 // Owner: ctx
 icalcomponent *
-parse_ics_file(memory_region *mreg, const char *filename);
+parse_ics_file(arena *ar, const char *filename);
 
 icaltimetype
 get_ical_now();
@@ -23,13 +23,13 @@ size_t
 icalcomponent_get_description_size(icalcomponent *component);
 
 char *
-create_new_unique_ics_uid(memory_region *mreg);
+create_new_unique_ics_uid(arena *ar);
 
 icalcomponent *
-create_vjournal_directory(memory_region *mreg, const char *summary);
+create_vjournal_directory(arena *ar, const char *summary);
 
 icalcomponent *
-create_vjournal_entry(memory_region *mreg, const char *summary);
+create_vjournal_entry(arena *ar, const char *summary);
 
 const char *
 get_parent_uid(icalcomponent *component);
@@ -53,7 +53,7 @@ format_ical_class(const enum icalproperty_class iclass);
 const char *
 format_ical_status(const enum icalproperty_status istatus);
 void
-icalcomponent_insert_description(memory_region *mreg, icalcomponent *ic,
+icalcomponent_insert_description(arena *ar, icalcomponent *ic,
 				 const char *buf, size_t size, off_t offset);
 
 void
@@ -67,15 +67,15 @@ void
 icalcomponent_mark_as_directory(icalcomponent *ic);
 
 void
-icalcomponent_set_custom_x_value(memory_region *mreg, icalcomponent *component,
+icalcomponent_set_custom_x_value(arena *ar, icalcomponent *component,
 				 const char *key, const char *value);
 
 const char *
-icalcomponent_get_custom_x_value(memory_region *mreg, icalcomponent *component,
+icalcomponent_get_custom_x_value(arena *ar, icalcomponent *component,
 				 const char *key);
 
 void
-icalcomponent_remove_custom_prop(memory_region *mreg, icalcomponent *component,
+icalcomponent_remove_custom_prop(arena *ar, icalcomponent *component,
 				 const char *key);
 
 void
diff --git a/main.c b/main.c
@@ -3,7 +3,7 @@
 #include "fuse_node.h"
 #include "fuse_node_store.h"
 #include "ical_extra.h"
-#include "mregion.h"
+#include "arena.h"
 #include "tree.h"
 #include "util.h"
 #include <dirent.h>
@@ -35,9 +35,9 @@ static pthread_rwlock_t entries_lock = PTHREAD_RWLOCK_INITIALIZER;
 #define FUSE_WRITE_BEGIN                                                       \
 	LOG("%s", __func__);                                                   \
 	pthread_rwlock_wrlock(&entries_lock);                                  \
-	memory_region *mreg = create_region();                                 \
+	arena *ar = create_arena();                                 \
 	int status = 0;                                                        \
-	if (!mreg) {                                                           \
+	if (!ar) {                                                           \
 		pthread_rwlock_unlock(&entries_lock);                          \
 		return -ENOMEM;                                                \
 	}
@@ -45,16 +45,16 @@ static pthread_rwlock_t entries_lock = PTHREAD_RWLOCK_INITIALIZER;
 #define FUSE_READ_BEGIN                                                        \
 	LOG("%s", __func__);                                                   \
 	pthread_rwlock_rdlock(&entries_lock);                                  \
-	memory_region *mreg = create_region();                                 \
+	arena *ar = create_arena();                                 \
 	int status = 0;                                                        \
-	if (!mreg) {                                                           \
+	if (!ar) {                                                           \
 		pthread_rwlock_unlock(&entries_lock);                          \
 		return -ENOMEM;                                                \
 	}
 
 #define FUSE_CLEANUP                                                           \
 	pthread_rwlock_unlock(&entries_lock);                                  \
-	rfree_all(mreg);
+	free_all(ar);
 
 static int
 fuse_getattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi)
@@ -75,16 +75,16 @@ fuse_getattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi)
 		goto cleanup_return;
 	}
 
-	const struct tree_node *node = get_node_by_path(mreg, path);
+	const struct tree_node *node = get_node_by_path(ar, path);
 	if (!node) {
 		LOG("Entry not found");
 		status = -ENOENT;
 		goto cleanup_return;
 	}
 
-	icalcomponent *ic = get_icalcomponent_from_node(mreg, node);
+	icalcomponent *ic = get_icalcomponent_from_node(ar, node);
 
-	struct stat st = get_node_stat(mreg, node, ic);
+	struct stat st = get_node_stat(ar, node, ic);
 
 	*stbuf = st;
 
@@ -114,7 +114,7 @@ fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset,
 	filler(buf, ".", NULL, 0, 0);
 	filler(buf, "..", NULL, 0, 0);
 
-	const struct tree_node *node = get_node_by_path(mreg, path);
+	const struct tree_node *node = get_node_by_path(ar, path);
 	if (!node) {
 		status = -ENOENT;
 		goto cleanup_return;
@@ -122,10 +122,10 @@ fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset,
 
 	for (size_t i = 0; i < node->child_count; i++) {
 		const struct tree_node *child = node->children[i];
-		icalcomponent *ic = get_icalcomponent_from_node(mreg, child);
+		icalcomponent *ic = get_icalcomponent_from_node(ar, child);
 		assert(ic);
 
-		struct stat st = get_node_stat(mreg, node, ic);
+		struct stat st = get_node_stat(ar, node, ic);
 
 		if (filler(buf, get_node_filename(child), &st, 0, 0) != 0) {
 			status = -ENOMEM;
@@ -143,7 +143,7 @@ fuse_open(const char *path, struct fuse_file_info *fi)
 {
 	FUSE_READ_BEGIN;
 	LOG("%s", path);
-	const struct tree_node *node = get_node_by_path(mreg, path);
+	const struct tree_node *node = get_node_by_path(ar, path);
 	if (!node) {
 		status = -ENOENT;
 	}
@@ -163,13 +163,13 @@ fuse_mkdir(const char *filepath, mode_t mode)
 		goto cleanup_return;
 	}
 
-	struct tree_node *node = get_node_by_path(mreg, filepath);
+	struct tree_node *node = get_node_by_path(ar, filepath);
 	if (node) {
 		status = -EEXIST;
 		goto cleanup_return;
 	}
 
-	status = create_entry_from_fuse(mreg, filepath, ENTRY_DIRECTORY);
+	status = create_entry_from_fuse(ar, filepath, ENTRY_DIRECTORY);
 
 cleanup_return:
 	FUSE_CLEANUP;
@@ -184,12 +184,12 @@ fuse_read(const char *path, char *buf, size_t size, off_t offset,
 
 	LOG("READ: offset=%ld, size=%zu", offset, size);
 
-	const struct tree_node *n = get_node_by_path(mreg, path);
+	const struct tree_node *n = get_node_by_path(ar, path);
 	if (!n) {
 		status = -ENOENT;
 		goto cleanup_return;
 	}
-	icalcomponent *ic = get_icalcomponent_from_node(mreg, n);
+	icalcomponent *ic = get_icalcomponent_from_node(ar, n);
 	if (!ic) {
 		status = -EIO;
 		goto cleanup_return;
@@ -234,20 +234,20 @@ fuse_write(const char *path, const char *buf, size_t size, off_t offset,
 		goto cleanup_return;
 	}
 
-	const struct tree_node *node = get_node_by_path(mreg, path);
+	const struct tree_node *node = get_node_by_path(ar, path);
 	if (!node) {
 		status = -ENONET;
 		goto cleanup_return;
 	}
 
-	icalcomponent *ic = get_icalcomponent_from_node(mreg, node);
+	icalcomponent *ic = get_icalcomponent_from_node(ar, node);
 
 	// It possible to write to "/". The rest have an icalcomponent
 	assert(ic);
 
-	icalcomponent_insert_description(mreg, ic, buf, size, offset);
+	icalcomponent_insert_description(ar, ic, buf, size, offset);
 
-	status = write_ical_file(mreg, node, ic) >= 0 ? size : status;
+	status = write_ical_file(ar, node, ic) >= 0 ? size : status;
 
 cleanup_return:
 	FUSE_CLEANUP;
@@ -261,19 +261,19 @@ fuse_unlink(const char *file)
 	FUSE_WRITE_BEGIN;
 	LOG("%s", file);
 
-	struct tree_node *node = get_node_by_path(mreg, file);
+	struct tree_node *node = get_node_by_path(ar, file);
 	if (!node) {
 		status = -ENOENT;
 		goto cleanup_return;
 	}
 
-	icalcomponent *node_ics = get_icalcomponent_from_node(mreg, node);
-	if (node_is_directory(mreg, node, node_ics)) {
+	icalcomponent *node_ics = get_icalcomponent_from_node(ar, node);
+	if (node_is_directory(ar, node, node_ics)) {
 		status = -EISDIR;
 		goto cleanup_return;
 	}
 
-	status = delete_vdir_entry(mreg, node);
+	status = delete_vdir_entry(ar, node);
 
 cleanup_return:
 	FUSE_CLEANUP;
@@ -286,14 +286,14 @@ fuse_rmdir(const char *filepath)
 	FUSE_WRITE_BEGIN;
 	LOG("%s", filepath);
 
-	struct tree_node *node = get_node_by_path(mreg, filepath);
+	struct tree_node *node = get_node_by_path(ar, filepath);
 	if (!node) {
 		status = -ENOENT;
 		goto cleanup_return;
 	}
 
-	icalcomponent *node_ics = get_icalcomponent_from_node(mreg, node);
-	if (!node_is_directory(mreg, node, node_ics)) {
+	icalcomponent *node_ics = get_icalcomponent_from_node(ar, node);
+	if (!node_is_directory(ar, node, node_ics)) {
 		status = -ENOTDIR;
 		goto cleanup_return;
 	}
@@ -303,7 +303,7 @@ fuse_rmdir(const char *filepath)
 		goto cleanup_return;
 	}
 
-	status = delete_vdir_entry(mreg, node);
+	status = delete_vdir_entry(ar, node);
 
 cleanup_return:
 	FUSE_CLEANUP;
@@ -317,19 +317,19 @@ fuse_rename(const char *old, const char *new, unsigned int flags)
 	FUSE_WRITE_BEGIN;
 	LOG("%s -> %s", old, new);
 
-	struct tree_node *existing_node = get_node_by_path(mreg, new);
+	struct tree_node *existing_node = get_node_by_path(ar, new);
 	if (existing_node) {
 		if (node_has_children(existing_node)) {
 			status = -ENOTEMPTY;
 			goto cleanup_return;
 		}
-		if (delete_vdir_entry(mreg, existing_node) != 0) {
+		if (delete_vdir_entry(ar, existing_node) != 0) {
 			status = -EIO;
 			goto cleanup_return;
 		}
 	}
 
-	status = do_agenda_rename(mreg, old, new);
+	status = do_agenda_rename(ar, old, new);
 
 cleanup_return:
 	FUSE_CLEANUP;
@@ -349,14 +349,14 @@ fuse_create(const char *filepath, mode_t mode, struct fuse_file_info *info)
 		goto cleanup_return;
 	}
 
-	struct tree_node *node = get_node_by_path(mreg, filepath);
+	struct tree_node *node = get_node_by_path(ar, filepath);
 	if (node) {
 		status = -EEXIST;
 		goto cleanup_return;
 	}
 
 	// TODO: Handle mode and fuse_file_info
-	status = create_entry_from_fuse(mreg, filepath, ENTRY_FILE);
+	status = create_entry_from_fuse(ar, filepath, ENTRY_FILE);
 
 cleanup_return:
 	FUSE_CLEANUP;
@@ -369,18 +369,18 @@ fuse_removexattr(const char *path, const char *attribute)
 	FUSE_WRITE_BEGIN;
 	LOG("'%s' '%s'", path, attribute);
 
-	struct tree_node *node = get_node_by_path(mreg, path);
+	struct tree_node *node = get_node_by_path(ar, path);
 	if (!node) {
 		status = -ENONET;
 		goto cleanup_return;
 	}
 
 	if (strcmp(attribute, "user.categories") == 0) {
-		status = set_node_categories(mreg, node, "", 0);
+		status = set_node_categories(ar, node, "", 0);
 		goto cleanup_return;
 	}
 	else if (strcmp(attribute, "user.class") == 0) {
-		status = delete_node_class(mreg, node);
+		status = delete_node_class(ar, node);
 		goto cleanup_return;
 	}
 
@@ -390,15 +390,15 @@ fuse_removexattr(const char *path, const char *attribute)
 		goto cleanup_return;
 	}
 	if (strcmp(attribute, "user.dtstart") == 0) {
-		status = clear_dtstart(mreg, node);
+		status = clear_dtstart(ar, node);
 		goto cleanup_return;
 	}
 	else if (starts_with_str(attribute, "user.")) {
-		icalcomponent *ic = get_icalcomponent_from_node(mreg, node);
+		icalcomponent *ic = get_icalcomponent_from_node(ar, node);
 
 		const char *key = attribute + 5;
-		icalcomponent_remove_custom_prop(mreg, ic, key);
-		status = write_ical_file(mreg, node, ic);
+		icalcomponent_remove_custom_prop(ar, ic, key);
+		status = write_ical_file(ar, node, ic);
 		goto cleanup_return;
 	}
 	else {
@@ -417,7 +417,7 @@ fuse_setxattr(const char *path, const char *attribute, const char *value,
 {
 
 	FUSE_WRITE_BEGIN;
-	LOG("'%s' '%s' '%zu' '%s' '%d'", path, attribute, s, attribute, flags);
+	LOG("'%s' '%s' '%zu' '%s' '%d'", path, attribute, s, value, flags);
 
 	// Limit documented in xattr(7)
 	if (strlen(attribute) >= 256) {
@@ -431,7 +431,7 @@ fuse_setxattr(const char *path, const char *attribute, const char *value,
 		goto cleanup_return;
 	}
 
-	struct tree_node *node = get_node_by_path(mreg, path);
+	struct tree_node *node = get_node_by_path(ar, path);
 	if (!node) {
 		status = -ENONET;
 		goto cleanup_return;
@@ -451,17 +451,17 @@ fuse_setxattr(const char *path, const char *attribute, const char *value,
 
 	else if (strcmp(attribute, "user.dtstart") == 0) {
 		if (strcmp(value, "") == 0) {
-			status = clear_dtstart(mreg, node);
+			status = clear_dtstart(ar, node);
 		}
 		else {
-			status = set_dtstart(mreg, value, node);
+			status = set_dtstart(ar, value, node);
 		}
 		goto cleanup_return;
 	}
 
 	else if (strcmp(attribute, "user.categories") == 0) {
 		LOG("Updating categories");
-		status = set_node_categories(mreg, node, value, s);
+		status = set_node_categories(ar, node, value, s);
 		goto cleanup_return;
 	}
 
@@ -470,11 +470,12 @@ fuse_setxattr(const char *path, const char *attribute, const char *value,
 		enum icalproperty_class iclass = parse_ical_class(value);
 
 		if (iclass == ICAL_CLASS_NONE) {
+			LOG("INVALID CLASS %s", value);
 			status = -EINVAL;
 			goto cleanup_return;
 		}
 
-		status = set_node_class(mreg, node, iclass);
+		status = set_node_class(ar, node, iclass);
 		goto cleanup_return;
 	}
 	else if (strcmp(attribute, "user.status") == 0) {
@@ -487,17 +488,17 @@ fuse_setxattr(const char *path, const char *attribute, const char *value,
 			goto cleanup_return;
 		}
 
-		status = set_node_status(mreg, node, istatus);
+		status = set_node_status(ar, node, istatus);
 		goto cleanup_return;
 	}
 	else if (starts_with_str(attribute, "user.")) {
-		icalcomponent *ic = get_icalcomponent_from_node(mreg, node);
+		icalcomponent *ic = get_icalcomponent_from_node(ar, node);
 
 		const char *rkey = attribute + 5;
 		LOG("Updating %s", rkey);
 
-		icalcomponent_set_custom_x_value(mreg, ic, rkey, value);
-		status = write_ical_file(mreg, node, ic);
+		icalcomponent_set_custom_x_value(ar, ic, rkey, value);
+		status = write_ical_file(ar, node, ic);
 		goto cleanup_return;
 	}
 	else {
@@ -520,7 +521,7 @@ fuse_listxattr(const char *path, char *list, size_t size)
 	char *xattribute_list = NULL;
 	size_t xattr_list_len = 0;
 
-	struct tree_node *node = get_node_by_path(mreg, path);
+	struct tree_node *node = get_node_by_path(ar, path);
 	if (!node) {
 		status = -ENONET;
 		goto cleanup_return_2;
@@ -531,7 +532,7 @@ fuse_listxattr(const char *path, char *list, size_t size)
 		goto cleanup_return_2;
 	}
 
-	icalcomponent *comp = get_icalcomponent_from_node(mreg, node);
+	icalcomponent *comp = get_icalcomponent_from_node(ar, node);
 	assert(comp);
 
 	stream = open_memstream(&xattribute_list, &xattr_list_len);
@@ -540,13 +541,13 @@ fuse_listxattr(const char *path, char *list, size_t size)
 		goto cleanup_return_2;
 	}
 
-	char *cats = get_node_categories(mreg, node);
+	char *cats = get_node_categories(ar, node);
 	if (cats != NULL && strcmp("", cats) != 0) {
 		fprintf(stream, "user.categories");
 		fputc('\0', stream);
 	}
 
-	const char *dtstart = get_dtstart(mreg, node);
+	const char *dtstart = get_dtstart(ar, node);
 	if (dtstart != NULL) {
 		fprintf(stream, "user.dtstart");
 		fputc('\0', stream);
@@ -557,14 +558,14 @@ fuse_listxattr(const char *path, char *list, size_t size)
 	fputc('\0', stream);
 
 	LOG("Checking node class");
-	const char *iclass = get_node_class(mreg, node);
+	const char *iclass = get_node_class(ar, node);
 	if (iclass != NULL && strcmp("", iclass) != 0) {
 		fprintf(stream, "user.class");
 		fputc('\0', stream);
 	}
 
 	LOG("Checking node status");
-	const char *istatus = get_node_status(mreg, node);
+	const char *istatus = get_node_status(ar, node);
 	if (istatus != NULL && strcmp("", istatus) != 0) {
 		fprintf(stream, "user.status");
 		fputc('\0', stream);
@@ -600,7 +601,7 @@ fuse_getxattr(const char *path, const char *attribute, char *buf, size_t s)
 	FUSE_READ_BEGIN;
 	LOG("'%s' '%s' '%zu'\n", path, attribute, s);
 
-	struct tree_node *node = get_node_by_path(mreg, path);
+	struct tree_node *node = get_node_by_path(ar, path);
 	if (!node) {
 		status = -ENONET;
 		goto cleanup_return;
@@ -608,7 +609,7 @@ fuse_getxattr(const char *path, const char *attribute, char *buf, size_t s)
 
 	if (strcmp(attribute, "user.categories") == 0) {
 
-		const char *cats = get_node_categories(mreg, node);
+		const char *cats = get_node_categories(ar, node);
 
 		if (!cats || *cats == '\0') {
 			status = -ENODATA;
@@ -626,7 +627,7 @@ fuse_getxattr(const char *path, const char *attribute, char *buf, size_t s)
 		goto cleanup_return;
 	}
 	if (strcmp(attribute, "user.uid") == 0) {
-		icalcomponent *ic = get_icalcomponent_from_node(mreg, node);
+		icalcomponent *ic = get_icalcomponent_from_node(ar, node);
 		const char *uid = icalcomponent_get_uid(ic);
 		assert(uid);
 
@@ -642,7 +643,7 @@ fuse_getxattr(const char *path, const char *attribute, char *buf, size_t s)
 		goto cleanup_return;
 	}
 	else if (strcmp(attribute, "user.class") == 0) {
-		const char *c = get_node_class(mreg, node);
+		const char *c = get_node_class(ar, node);
 		if (!c || *c == '\0') {
 			status = -ENODATA;
 			goto cleanup_return;
@@ -658,7 +659,7 @@ fuse_getxattr(const char *path, const char *attribute, char *buf, size_t s)
 		goto cleanup_return;
 	}
 	else if (strcmp(attribute, "user.status") == 0) {
-		const char *c = get_node_status(mreg, node);
+		const char *c = get_node_status(ar, node);
 		if (!c || *c == '\0') {
 			status = -ENODATA;
 			goto cleanup_return;
@@ -674,7 +675,7 @@ fuse_getxattr(const char *path, const char *attribute, char *buf, size_t s)
 		goto cleanup_return;
 	}
 	else if (strcmp(attribute, "user.dtstart") == 0) {
-		const char *res = get_dtstart(mreg, node);
+		const char *res = get_dtstart(ar, node);
 		if (!res) {
 			status = -ENODATA;
 			goto cleanup_return;
@@ -692,11 +693,11 @@ fuse_getxattr(const char *path, const char *attribute, char *buf, size_t s)
 		goto cleanup_return;
 	}
 	else if (starts_with_str(attribute, "user.")) {
-		icalcomponent *ic = get_icalcomponent_from_node(mreg, node);
+		icalcomponent *ic = get_icalcomponent_from_node(ar, node);
 
 		const char *key = attribute + 5;
 		const char *value =
-		    icalcomponent_get_custom_x_value(mreg, ic, key);
+		    icalcomponent_get_custom_x_value(ar, ic, key);
 		if (!value) {
 			status = -ENODATA;
 			goto cleanup_return;
@@ -729,29 +730,29 @@ handle_vdir_event(struct inotify_event *event)
 	if (!event->len || !strstr(event->name, ".ics"))
 		return;
 
-	memory_region *mreg = create_region();
+	arena *ar = create_arena();
 	pthread_rwlock_wrlock(&entries_lock);
 
 	LOG("Detected change in ICS file: %s\n", event->name);
 
 	char *full_path = NULL;
-	rasprintf(mreg, &full_path, "%s/%s", VDIR, event->name);
+	rasprintf(ar, &full_path, "%s/%s", VDIR, event->name);
 
 	if (event->mask & IN_DELETE) {
 		LOG("IN_DELETE HOOK");
-		delete_from_vdir_path(mreg, full_path);
+		delete_from_vdir_path(ar, full_path);
 	}
 	else if (event->mask & IN_MODIFY) {
 		LOG("IN_MODIFY HOOK");
-		update_or_create_fuse_entry_from_vdir(mreg, full_path);
+		update_or_create_fuse_entry_from_vdir(ar, full_path);
 	}
 	else if (event->mask & IN_CREATE) {
 		LOG("IN_CREATE HOOK");
-		update_or_create_fuse_entry_from_vdir(mreg, full_path);
+		update_or_create_fuse_entry_from_vdir(ar, full_path);
 	}
 
 	pthread_rwlock_unlock(&entries_lock);
-	rfree_all(mreg);
+	free_all(ar);
 }
 
 static void *
diff --git a/mregion.c b/mregion.c
@@ -1,188 +0,0 @@
-#include "mregion.h"
-#include "util.h"
-#include <assert.h>
-#include <libical/ical.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-typedef void (*free_func_t)(void *);
-
-memory_region *
-create_region(void)
-{
-	memory_region *region = xmalloc(sizeof(memory_region));
-	region->head = NULL;
-	return region;
-}
-
-void
-region_register(memory_region *region, void *ptr, free_func_t free_func)
-{
-	assert(free_func);
-	memory_block *block = xmalloc(sizeof(memory_block));
-	block->ptr = ptr;
-	block->free_func = free_func;
-	block->next = region->head;
-	region->head = block;
-}
-
-void *
-rmalloc(memory_region *region, size_t size)
-{
-	void *ptr = xmalloc(size);
-	region_register(region, ptr, free);
-	return ptr;
-}
-
-// Copies and null terminates a string
-char *
-rstrndup(memory_region *mreg, const char *src, size_t len)
-{
-	char *buf = rmalloc(mreg, len + 1);
-	memcpy(buf, src, len);
-	buf[len] = '\0';
-	return buf;
-}
-
-void
-rfree_all(memory_region *region)
-{
-	if (!region)
-		return;
-	memory_block *block = region->head;
-	while (block) {
-		memory_block *next = block->next;
-		if (block->free_func)
-			block->free_func(block->ptr);
-		free(block);
-		block = next;
-	}
-	region->head = NULL;
-	free(region);
-}
-
-// String functions
-char *
-rstrdup(memory_region *region, const char *str)
-{
-	char *copy = xstrdup(str);
-	region_register(region, copy, free);
-	return copy;
-}
-
-char *
-rstrins(memory_region *region, const char *str, size_t offset, const char *buf,
-	size_t size)
-{
-	size_t str_len = strlen(str);
-
-	size_t previous_new_len = (offset <= str_len) ? offset : str_len;
-
-	char *result = NULL;
-	size_t result_len = 0;
-
-	FILE *stream = open_memstream(&result, &result_len);
-	assert(stream);
-
-	fwrite(str, 1, previous_new_len, stream);
-	fwrite(buf, 1, size, stream);
-
-	fclose(stream);
-
-	region_register(region, result, free);
-
-	return result;
-}
-
-int
-rasprintf(memory_region *region, char **strp, const char *fmt, ...)
-{
-	// Calculate length
-	va_list args;
-	va_start(args, fmt);
-	int len = vsnprintf(NULL, 0, fmt, args);
-	va_end(args);
-
-	if (len < 0) {
-		*strp = NULL;
-		return -1;
-	}
-
-	char *buffer = rmalloc(region, len + 1);
-	va_start(args, fmt);
-	int ret = vsnprintf(buffer, len + 1, fmt, args);
-	va_end(args);
-	if (ret < 0) {
-		*strp = NULL;
-		return -1;
-	}
-	*strp = buffer;
-	return ret;
-}
-
-// iCal functions
-
-icalparser *
-ricalparser_new(memory_region *region)
-{
-	icalparser *p = icalparser_new();
-	region_register(region, p, (void *)icalparser_free);
-	return p;
-}
-
-void
-ricalcomponent_free(icalcomponent *ic)
-{
-	if (ic)
-		icalcomponent_free(ic);
-}
-
-icalcomponent *
-ricalcomponent_empty(memory_region *region)
-{
-	icalcomponent *ic = NULL;
-	region_register(region, ic, (void *)ricalcomponent_free);
-	return ic;
-}
-
-icalcomponent *
-ricalcomponent_new_clone(memory_region *region, icalcomponent *ic)
-{
-	icalcomponent *nic = icalcomponent_new_clone(ic);
-	region_register(region, nic, (void *)ricalcomponent_free);
-	return nic;
-}
-
-icalcomponent *
-ricalcomponent_new_from_string(memory_region *region, const char *ic)
-{
-	icalcomponent *nic = icalcomponent_new_from_string(ic);
-	region_register(region, nic, (void *)ricalcomponent_free);
-	return nic;
-}
-
-char *
-ricalcomponent_as_ical_string(memory_region *region, icalcomponent *ic)
-{
-	char *c = icalcomponent_as_ical_string(ic);
-	region_register(region, c, free);
-	return c;
-}
-
-char *
-ricalcomponent_as_ical_string_r(memory_region *region, icalcomponent *ic)
-{
-	char *c = icalcomponent_as_ical_string_r(ic);
-	region_register(region, c, free);
-	return c;
-}
-
-icalcomponent *
-ricalcomponent_new_vcalendar(memory_region *region)
-{
-	icalcomponent *new_comp = icalcomponent_new_vcalendar();
-	region_register(region, new_comp, (void *)ricalcomponent_free);
-	return new_comp;
-}
diff --git a/mregion.h b/mregion.h
@@ -1,73 +0,0 @@
-#ifndef mregion_h_INCLUDED
-#define mregion_h_INCLUDED
-#include "util.h"
-#include <assert.h>
-#include <libical/ical.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-typedef void (*free_func_t)(void *);
-
-typedef struct memory_block {
-	void *ptr;
-	free_func_t free_func;
-	struct memory_block *next;
-} memory_block;
-
-typedef struct {
-	memory_block *head;
-} memory_region;
-
-memory_region *
-create_region(void);
-
-void
-region_register(memory_region *region, void *ptr, free_func_t free_func);
-
-void *
-rmalloc(memory_region *region, size_t size);
-
-void
-rfree_all(memory_region *region);
-
-char *
-rstrndup(memory_region *mreg, const char *src, size_t len);
-
-char *
-rstrins(memory_region *region, const char *str, size_t offset, const char *buf,
-	size_t size);
-// String functions
-char *
-rstrdup(memory_region *region, const char *str);
-
-int
-rasprintf(memory_region *region, char **strp, const char *fmt, ...);
-
-// iCal functions
-
-icalparser *
-ricalparser_new(memory_region *region);
-
-void
-ricalcomponent_free(icalcomponent *ic);
-
-icalcomponent *
-ricalcomponent_empty(memory_region *region);
-
-icalcomponent *
-ricalcomponent_new_clone(memory_region *region, icalcomponent *ic);
-
-icalcomponent *
-ricalcomponent_new_from_string(memory_region *region, const char *ic);
-
-char *
-ricalcomponent_as_ical_string(memory_region *region, icalcomponent *ic);
-
-char *
-ricalcomponent_as_ical_string_r(memory_region *region, icalcomponent *ic);
-
-icalcomponent *
-ricalcomponent_new_vcalendar(memory_region *region);
-#endif // mrgeion_h_INCLUDED
diff --git a/path.c b/path.c
@@ -1,5 +1,5 @@
 #include "path.h"
-#include "mregion.h"
+#include "arena.h"
 #include <assert.h>
 #include <errno.h>
 #include <stdbool.h>
@@ -8,7 +8,7 @@
 #include <string.h>
 
 path *
-without_file_extension(memory_region *m, const path *p)
+without_file_extension(arena *m, const path *p)
 {
 	char *cpy = rstrdup(m, p);
 	char *last_dot = strrchr(cpy, '.');
@@ -22,7 +22,7 @@ without_file_extension(memory_region *m, const path *p)
 }
 
 path *
-get_file_extension(memory_region *m, const path *p)
+get_file_extension(arena *m, const path *p)
 {
 	char *cpy = rstrdup(m, p);
 	char *last_dot = strrchr(cpy, '.');
@@ -40,12 +40,12 @@ pathIsHidden(const path *p)
 }
 
 path *
-append_path(memory_region *m, const path *parentp, const char *childp)
+append_path(arena *m, const path *parentp, const char *childp)
 {
 	char *filepath = NULL;
 	size_t res = asprintf(&filepath, "%s/%s", parentp, childp);
 	assert(res != -1);
-	region_register(m, filepath, free);
+	arena_register(m, filepath, free);
 	return filepath;
 }
 
@@ -59,9 +59,9 @@ get_filename(const char *full_path)
 }
 
 char *
-get_parent_path(memory_region *mreg, const char *path)
+get_parent_path(arena *ar, const char *path)
 {
-	char *path_copy = rstrdup(mreg, path);
+	char *path_copy = rstrdup(ar, path);
 
 	char *last_slash = strrchr(path_copy, '/');
 	if (last_slash == NULL) {
@@ -78,7 +78,7 @@ get_parent_path(memory_region *mreg, const char *path)
 }
 
 size_t
-split_path(memory_region *m, const path *p, char **segments)
+split_path(arena *m, const path *p, char **segments)
 {
 	char *path_copy = rstrdup(m, p);
 
diff --git a/path.h b/path.h
@@ -1,6 +1,6 @@
 #ifndef path_h_INCLUDED
 #define path_h_INCLUDED
-#include "mregion.h"
+#include "arena.h"
 #include "util.h"
 #include <assert.h>
 #include <errno.h>
@@ -12,10 +12,10 @@
 typedef char path;
 
 path *
-without_file_extension(memory_region *m, const path *p);
+without_file_extension(arena *m, const path *p);
 
 path *
-append_path(memory_region *m, const path *parentp, const char *childp);
+append_path(arena *m, const path *parentp, const char *childp);
 
 bool
 pathIsHidden(const path *p);
@@ -24,13 +24,13 @@ const path *
 get_filename(const char *full_path);
 
 path *
-get_file_extension(memory_region *m, const path *p);
+get_file_extension(arena *m, const path *p);
 
 char *
-get_parent_path(memory_region *mreg, const char *path);
+get_parent_path(arena *ar, const char *path);
 
 size_t
-split_path(memory_region *m, const path *p, char **segments);
+split_path(arena *m, const path *p, char **segments);
 
 size_t
 write_to_file(const path *filepath, const char *content);
diff --git a/tree.c b/tree.c
@@ -1,5 +1,5 @@
 #include "tree.h"
-#include "mregion.h"
+#include "arena.h"
 #include "util.h"
 #include <stdbool.h>
 #include <stdio.h>
@@ -22,7 +22,7 @@ create_tree_node(void *data, void (*free_fn)(void *))
 }
 
 struct tree_node *
-rcreate_tree_node(void *data, memory_region *m)
+rcreate_tree_node(void *data, arena *m)
 {
 	struct tree_node *node = rmalloc(m, sizeof(struct tree_node));
 	if (!node)
diff --git a/tree.h b/tree.h
@@ -1,7 +1,7 @@
 #ifndef tree_h
 #define tree_h
 
-#include "mregion.h"
+#include "arena.h"
 #include <stdbool.h>
 #include <stdlib.h>
 
@@ -20,7 +20,7 @@ struct tree_node *
 create_tree_node(void *data, void (*free_fn)(void *));
 
 struct tree_node *
-rcreate_tree_node(void *data, memory_region *m);
+rcreate_tree_node(void *data, arena *m);
 
 bool
 node_has_children(const struct tree_node *node);