diff --git a/src/database.c b/src/database.c
index a35bab2de7c9687f1db240191ffbaef3d6f13b26..162ce1ab33432a7ceb66b18dc22140187740f3b7 100644
--- a/src/database.c
+++ b/src/database.c
@@ -262,12 +262,16 @@ void apk_db_dir_unref(struct apk_database *db, struct apk_db_dir *dir, int rmdir
 	db->installed.stats.dirs--;
 	apk_protected_path_array_free(&dir->protected_paths);
 	if (dir->namelen != 0) {
-		if (rmdir_mode == APK_DIR_REMOVE && !(apk_flags & APK_SIMULATE))
-			if (unlinkat(db->root_fd, dir->name, AT_REMOVEDIR))
+		if (rmdir_mode == APK_DIR_REMOVE) {
+			dir->modified = 1;
+			if (!(apk_flags & APK_SIMULATE) &&
+			    unlinkat(db->root_fd, dir->name, AT_REMOVEDIR) != 0)
 				;
+		}
 		apk_db_dir_unref(db, dir->parent, rmdir_mode);
+		dir->parent = NULL;
 	}
-	apk_hash_delete_hashed(&db->installed.dirs, APK_BLOB_PTR_LEN(dir->name, dir->namelen), dir->hash);
+	dir->seen = dir->created = dir->update_permissions = 0;
 }
 
 struct apk_db_dir *apk_db_dir_ref(struct apk_db_dir *dir)
@@ -291,26 +295,25 @@ struct apk_db_dir *apk_db_dir_get(struct apk_database *db, apk_blob_t name)
 	unsigned long hash = apk_hash_from_key(&db->installed.dirs, name);
 	char *relative_name;
 
-	if (name.len && name.ptr[name.len-1] == '/')
-		name.len--;
+	if (name.len && name.ptr[name.len-1] == '/') name.len--;
 
 	dir = (struct apk_db_dir *) apk_hash_get_hashed(&db->installed.dirs, name, hash);
-	if (dir != NULL)
-		return apk_db_dir_ref(dir);
+	if (dir != NULL && dir->refs) return apk_db_dir_ref(dir);
+	if (dir == NULL) {
+		dir = calloc(1, sizeof(*dir) + name.len + 1);
+		dir->rooted_name[0] = '/';
+		memcpy(dir->name, name.ptr, name.len);
+		dir->name[name.len] = 0;
+		dir->namelen = name.len;
+		dir->hash = hash;
+		apk_protected_path_array_init(&dir->protected_paths);
+		apk_hash_insert_hashed(&db->installed.dirs, dir, hash);
+	}
 
 	db->installed.stats.dirs++;
-	dir = malloc(sizeof(*dir) + name.len + 1);
-	memset(dir, 0, sizeof(*dir));
 	dir->refs = 1;
 	dir->uid = (uid_t) -1;
 	dir->gid = (gid_t) -1;
-	dir->rooted_name[0] = '/';
-	memcpy(dir->name, name.ptr, name.len);
-	dir->name[name.len] = 0;
-	dir->namelen = name.len;
-	dir->hash = hash;
-	apk_protected_path_array_init(&dir->protected_paths);
-	apk_hash_insert_hashed(&db->installed.dirs, dir, hash);
 
 	if (name.len == 0) {
 		dir->parent = NULL;
diff --git a/src/fix.c b/src/fix.c
index 60bbfbfd64b70e59eda7278d73ba66a1b45c95b5..ae068b7c0b08959075ede1bf30a7d9cc057b7e84 100644
--- a/src/fix.c
+++ b/src/fix.c
@@ -67,6 +67,7 @@ static const struct apk_option_group optgroup_applet = {
 static int mark_recalculate(apk_hash_item item, void *ctx)
 {
 	struct apk_db_dir *dir = (struct apk_db_dir *) item;
+	if (dir->refs == 0) return 0;
 	dir->update_permissions = 1;
 	return 0;
 }