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#include "crc16.h"
29#include "ubifs.h"
30
31
32
33
34
35static void free_obsolete_cnodes(struct ubifs_info *c)
36{
37 struct ubifs_cnode *cnode, *cnext;
38
39 cnext = c->lpt_cnext;
40 if (!cnext)
41 return;
42 do {
43 cnode = cnext;
44 cnext = cnode->cnext;
45 if (test_bit(OBSOLETE_CNODE, &cnode->flags))
46 kfree(cnode);
47 else
48 cnode->cnext = NULL;
49 } while (cnext != c->lpt_cnext);
50 c->lpt_cnext = NULL;
51}
52
53
54
55
56
57
58
59
60
61static struct ubifs_nnode *first_nnode(struct ubifs_info *c, int *hght)
62{
63 struct ubifs_nnode *nnode;
64 int h, i, found;
65
66 nnode = c->nroot;
67 *hght = 0;
68 if (!nnode)
69 return NULL;
70 for (h = 1; h < c->lpt_hght; h++) {
71 found = 0;
72 for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
73 if (nnode->nbranch[i].nnode) {
74 found = 1;
75 nnode = nnode->nbranch[i].nnode;
76 *hght = h;
77 break;
78 }
79 }
80 if (!found)
81 break;
82 }
83 return nnode;
84}
85
86
87
88
89
90
91
92
93
94
95static struct ubifs_nnode *next_nnode(struct ubifs_info *c,
96 struct ubifs_nnode *nnode, int *hght)
97{
98 struct ubifs_nnode *parent;
99 int iip, h, i, found;
100
101 parent = nnode->parent;
102 if (!parent)
103 return NULL;
104 if (nnode->iip == UBIFS_LPT_FANOUT - 1) {
105 *hght -= 1;
106 return parent;
107 }
108 for (iip = nnode->iip + 1; iip < UBIFS_LPT_FANOUT; iip++) {
109 nnode = parent->nbranch[iip].nnode;
110 if (nnode)
111 break;
112 }
113 if (!nnode) {
114 *hght -= 1;
115 return parent;
116 }
117 for (h = *hght + 1; h < c->lpt_hght; h++) {
118 found = 0;
119 for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
120 if (nnode->nbranch[i].nnode) {
121 found = 1;
122 nnode = nnode->nbranch[i].nnode;
123 *hght = h;
124 break;
125 }
126 }
127 if (!found)
128 break;
129 }
130 return nnode;
131}
132
133
134
135
136
137
138void ubifs_lpt_free(struct ubifs_info *c, int wr_only)
139{
140 struct ubifs_nnode *nnode;
141 int i, hght;
142
143
144
145 free_obsolete_cnodes(c);
146
147 vfree(c->ltab_cmt);
148 c->ltab_cmt = NULL;
149 vfree(c->lpt_buf);
150 c->lpt_buf = NULL;
151 kfree(c->lsave);
152 c->lsave = NULL;
153
154 if (wr_only)
155 return;
156
157
158
159 nnode = first_nnode(c, &hght);
160 while (nnode) {
161 for (i = 0; i < UBIFS_LPT_FANOUT; i++)
162 kfree(nnode->nbranch[i].nnode);
163 nnode = next_nnode(c, nnode, &hght);
164 }
165 for (i = 0; i < LPROPS_HEAP_CNT; i++)
166 kfree(c->lpt_heap[i].arr);
167 kfree(c->dirty_idx.arr);
168 kfree(c->nroot);
169 vfree(c->ltab);
170 kfree(c->lpt_nod_buf);
171}
172