aboutsummaryrefslogtreecommitdiffstats
path: root/main/apk-tools/0001-db-optionally-remove-dirs-when-unref.patch
blob: e6497dda49e25a75425a6f090f6980667a1441e7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
From 5c4583a9027de2a26d3bff8b443f7db7f0c37074 Mon Sep 17 00:00:00 2001
From: Natanael Copa <ncopa@alpinelinux.org>
Date: Wed, 22 Sep 2010 14:16:18 +0000
Subject: [PATCH] db: optionally remove dirs when unref

We want remove dirs when they are unreferenced so we remove all dirs on
apk del, but we don't want remove dirs when closing database. So we make
removing dir optional when unreferencing it.

This partially reverts commit c7ffc96a16c6963fe0a07be7ee75e8f1f7426882.

fixes #406
---
 src/database.c |   28 +++++++++++++++-------------
 1 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/src/database.c b/src/database.c
index 925aa4a..0054837 100644
--- a/src/database.c
+++ b/src/database.c
@@ -30,6 +30,11 @@
 #include "apk_archive.h"
 #include "apk_print.h"
 
+enum {
+	APK_DISALLOW_RMDIR = 0,
+	APK_ALLOW_RMDIR = 1
+};
+
 int apk_verbosity = 1;
 unsigned int apk_flags = 0;
 
@@ -188,16 +193,19 @@ struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name)
 	return pn;
 }
 
-static void apk_db_dir_unref(struct apk_database *db, struct apk_db_dir *dir)
+static void apk_db_dir_unref(struct apk_database *db, struct apk_db_dir *dir,
+			     int allow_rmdir)
 {
 	dir->refs--;
 	if (dir->refs > 0)
 		return;
 
 	db->installed.stats.dirs--;
+	if (allow_rmdir)
+		unlinkat(db->root_fd, dir->name, AT_REMOVEDIR);
 
 	if (dir->parent != NULL)
-		apk_db_dir_unref(db, dir->parent);
+		apk_db_dir_unref(db, dir->parent, allow_rmdir);
 }
 
 static struct apk_db_dir *apk_db_dir_ref(struct apk_db_dir *dir)
@@ -307,16 +315,11 @@ static void apk_db_diri_mkdir(struct apk_database *db, struct apk_db_dir_instanc
 	}
 }
 
-static void apk_db_diri_rmdir(struct apk_database *db, struct apk_db_dir_instance *diri)
-{
-	if (diri->dir->refs == 1)
-		unlinkat(db->root_fd, diri->dir->name, 1);
-}
-
 static void apk_db_diri_free(struct apk_database *db,
-			     struct apk_db_dir_instance *diri)
+			     struct apk_db_dir_instance *diri,
+			     int allow_rmdir)
 {
-	apk_db_dir_unref(db, diri->dir);
+	apk_db_dir_unref(db, diri->dir, allow_rmdir);
 	free(diri);
 }
 
@@ -1265,7 +1268,7 @@ void apk_db_close(struct apk_database *db)
 
 	list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
 		hlist_for_each_entry_safe(diri, dc, dn, &ipkg->owned_dirs, pkg_dirs_list) {
-			apk_db_diri_free(db, diri);
+			apk_db_diri_free(db, diri, APK_DISALLOW_RMDIR);
 		}
 	}
 
@@ -1884,9 +1887,8 @@ static void apk_db_purge_pkg(struct apk_database *db,
 				db->installed.stats.files--;
 			}
 		}
-		apk_db_diri_rmdir(db, diri);
 		__hlist_del(dc, &ipkg->owned_dirs.first);
-		apk_db_diri_free(db, diri);
+		apk_db_diri_free(db, diri, APK_ALLOW_RMDIR);
 	}
 }
 
-- 
1.7.2.3