diff options
Diffstat (limited to 'e2fsprogs/ext2fs/irel_ma.c')
-rw-r--r-- | e2fsprogs/ext2fs/irel_ma.c | 367 |
1 files changed, 0 insertions, 367 deletions
diff --git a/e2fsprogs/ext2fs/irel_ma.c b/e2fsprogs/ext2fs/irel_ma.c deleted file mode 100644 index c871b1891..000000000 --- a/e2fsprogs/ext2fs/irel_ma.c +++ /dev/null | |||
@@ -1,367 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * irel_ma.c | ||
4 | * | ||
5 | * Copyright (C) 1996, 1997 Theodore Ts'o. | ||
6 | * | ||
7 | * %Begin-Header% | ||
8 | * This file may be redistributed under the terms of the GNU Public | ||
9 | * License. | ||
10 | * %End-Header% | ||
11 | */ | ||
12 | |||
13 | #include <fcntl.h> | ||
14 | #include <stdio.h> | ||
15 | #include <string.h> | ||
16 | #if HAVE_UNISTD_H | ||
17 | #include <unistd.h> | ||
18 | #endif | ||
19 | #if HAVE_ERRNO_H | ||
20 | #include <errno.h> | ||
21 | #endif | ||
22 | |||
23 | #include "ext2_fs.h" | ||
24 | #include "ext2fs.h" | ||
25 | #include "irel.h" | ||
26 | |||
27 | static errcode_t ima_put(ext2_irel irel, ext2_ino_t old, | ||
28 | struct ext2_inode_relocate_entry *ent); | ||
29 | static errcode_t ima_get(ext2_irel irel, ext2_ino_t old, | ||
30 | struct ext2_inode_relocate_entry *ent); | ||
31 | static errcode_t ima_get_by_orig(ext2_irel irel, ext2_ino_t orig, ext2_ino_t *old, | ||
32 | struct ext2_inode_relocate_entry *ent); | ||
33 | static errcode_t ima_start_iter(ext2_irel irel); | ||
34 | static errcode_t ima_next(ext2_irel irel, ext2_ino_t *old, | ||
35 | struct ext2_inode_relocate_entry *ent); | ||
36 | static errcode_t ima_add_ref(ext2_irel irel, ext2_ino_t ino, | ||
37 | struct ext2_inode_reference *ref); | ||
38 | static errcode_t ima_start_iter_ref(ext2_irel irel, ext2_ino_t ino); | ||
39 | static errcode_t ima_next_ref(ext2_irel irel, struct ext2_inode_reference *ref); | ||
40 | static errcode_t ima_move(ext2_irel irel, ext2_ino_t old, ext2_ino_t new); | ||
41 | static errcode_t ima_delete(ext2_irel irel, ext2_ino_t old); | ||
42 | static errcode_t ima_free(ext2_irel irel); | ||
43 | |||
44 | /* | ||
45 | * This data structure stores the array of inode references; there is | ||
46 | * a structure for each inode. | ||
47 | */ | ||
48 | struct inode_reference_entry { | ||
49 | __u16 num; | ||
50 | struct ext2_inode_reference *refs; | ||
51 | }; | ||
52 | |||
53 | struct irel_ma { | ||
54 | __u32 magic; | ||
55 | ext2_ino_t max_inode; | ||
56 | ext2_ino_t ref_current; | ||
57 | int ref_iter; | ||
58 | ext2_ino_t *orig_map; | ||
59 | struct ext2_inode_relocate_entry *entries; | ||
60 | struct inode_reference_entry *ref_entries; | ||
61 | }; | ||
62 | |||
63 | errcode_t ext2fs_irel_memarray_create(char *name, ext2_ino_t max_inode, | ||
64 | ext2_irel *new_irel) | ||
65 | { | ||
66 | ext2_irel irel = 0; | ||
67 | errcode_t retval; | ||
68 | struct irel_ma *ma = 0; | ||
69 | size_t size; | ||
70 | |||
71 | *new_irel = 0; | ||
72 | |||
73 | /* | ||
74 | * Allocate memory structures | ||
75 | */ | ||
76 | retval = ext2fs_get_mem(sizeof(struct ext2_inode_relocation_table), | ||
77 | &irel); | ||
78 | if (retval) | ||
79 | goto errout; | ||
80 | memset(irel, 0, sizeof(struct ext2_inode_relocation_table)); | ||
81 | |||
82 | retval = ext2fs_get_mem(strlen(name)+1, &irel->name); | ||
83 | if (retval) | ||
84 | goto errout; | ||
85 | strcpy(irel->name, name); | ||
86 | |||
87 | retval = ext2fs_get_mem(sizeof(struct irel_ma), &ma); | ||
88 | if (retval) | ||
89 | goto errout; | ||
90 | memset(ma, 0, sizeof(struct irel_ma)); | ||
91 | irel->priv_data = ma; | ||
92 | |||
93 | size = (size_t) (sizeof(ext2_ino_t) * (max_inode+1)); | ||
94 | retval = ext2fs_get_mem(size, &ma->orig_map); | ||
95 | if (retval) | ||
96 | goto errout; | ||
97 | memset(ma->orig_map, 0, size); | ||
98 | |||
99 | size = (size_t) (sizeof(struct ext2_inode_relocate_entry) * | ||
100 | (max_inode+1)); | ||
101 | retval = ext2fs_get_mem(size, &ma->entries); | ||
102 | if (retval) | ||
103 | goto errout; | ||
104 | memset(ma->entries, 0, size); | ||
105 | |||
106 | size = (size_t) (sizeof(struct inode_reference_entry) * | ||
107 | (max_inode+1)); | ||
108 | retval = ext2fs_get_mem(size, &ma->ref_entries); | ||
109 | if (retval) | ||
110 | goto errout; | ||
111 | memset(ma->ref_entries, 0, size); | ||
112 | ma->max_inode = max_inode; | ||
113 | |||
114 | /* | ||
115 | * Fill in the irel data structure | ||
116 | */ | ||
117 | irel->put = ima_put; | ||
118 | irel->get = ima_get; | ||
119 | irel->get_by_orig = ima_get_by_orig; | ||
120 | irel->start_iter = ima_start_iter; | ||
121 | irel->next = ima_next; | ||
122 | irel->add_ref = ima_add_ref; | ||
123 | irel->start_iter_ref = ima_start_iter_ref; | ||
124 | irel->next_ref = ima_next_ref; | ||
125 | irel->move = ima_move; | ||
126 | irel->delete = ima_delete; | ||
127 | irel->free = ima_free; | ||
128 | |||
129 | *new_irel = irel; | ||
130 | return 0; | ||
131 | |||
132 | errout: | ||
133 | ima_free(irel); | ||
134 | return retval; | ||
135 | } | ||
136 | |||
137 | static errcode_t ima_put(ext2_irel irel, ext2_ino_t old, | ||
138 | struct ext2_inode_relocate_entry *ent) | ||
139 | { | ||
140 | struct inode_reference_entry *ref_ent; | ||
141 | struct irel_ma *ma; | ||
142 | errcode_t retval; | ||
143 | size_t size, old_size; | ||
144 | |||
145 | ma = irel->priv_data; | ||
146 | if (old > ma->max_inode) | ||
147 | return EXT2_ET_INVALID_ARGUMENT; | ||
148 | |||
149 | /* | ||
150 | * Force the orig field to the correct value; the application | ||
151 | * program shouldn't be messing with this field. | ||
152 | */ | ||
153 | if (ma->entries[(unsigned) old].new == 0) | ||
154 | ent->orig = old; | ||
155 | else | ||
156 | ent->orig = ma->entries[(unsigned) old].orig; | ||
157 | |||
158 | /* | ||
159 | * If max_refs has changed, reallocate the refs array | ||
160 | */ | ||
161 | ref_ent = ma->ref_entries + (unsigned) old; | ||
162 | if (ref_ent->refs && ent->max_refs != | ||
163 | ma->entries[(unsigned) old].max_refs) { | ||
164 | size = (sizeof(struct ext2_inode_reference) * ent->max_refs); | ||
165 | old_size = (sizeof(struct ext2_inode_reference) * | ||
166 | ma->entries[(unsigned) old].max_refs); | ||
167 | retval = ext2fs_resize_mem(old_size, size, &ref_ent->refs); | ||
168 | if (retval) | ||
169 | return retval; | ||
170 | } | ||
171 | |||
172 | ma->entries[(unsigned) old] = *ent; | ||
173 | ma->orig_map[(unsigned) ent->orig] = old; | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static errcode_t ima_get(ext2_irel irel, ext2_ino_t old, | ||
178 | struct ext2_inode_relocate_entry *ent) | ||
179 | { | ||
180 | struct irel_ma *ma; | ||
181 | |||
182 | ma = irel->priv_data; | ||
183 | if (old > ma->max_inode) | ||
184 | return EXT2_ET_INVALID_ARGUMENT; | ||
185 | if (ma->entries[(unsigned) old].new == 0) | ||
186 | return ENOENT; | ||
187 | *ent = ma->entries[(unsigned) old]; | ||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | static errcode_t ima_get_by_orig(ext2_irel irel, ext2_ino_t orig, ext2_ino_t *old, | ||
192 | struct ext2_inode_relocate_entry *ent) | ||
193 | { | ||
194 | struct irel_ma *ma; | ||
195 | ext2_ino_t ino; | ||
196 | |||
197 | ma = irel->priv_data; | ||
198 | if (orig > ma->max_inode) | ||
199 | return EXT2_ET_INVALID_ARGUMENT; | ||
200 | ino = ma->orig_map[(unsigned) orig]; | ||
201 | if (ino == 0) | ||
202 | return ENOENT; | ||
203 | *old = ino; | ||
204 | *ent = ma->entries[(unsigned) ino]; | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | static errcode_t ima_start_iter(ext2_irel irel) | ||
209 | { | ||
210 | irel->current = 0; | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static errcode_t ima_next(ext2_irel irel, ext2_ino_t *old, | ||
215 | struct ext2_inode_relocate_entry *ent) | ||
216 | { | ||
217 | struct irel_ma *ma; | ||
218 | |||
219 | ma = irel->priv_data; | ||
220 | while (++irel->current < ma->max_inode) { | ||
221 | if (ma->entries[(unsigned) irel->current].new == 0) | ||
222 | continue; | ||
223 | *old = irel->current; | ||
224 | *ent = ma->entries[(unsigned) irel->current]; | ||
225 | return 0; | ||
226 | } | ||
227 | *old = 0; | ||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static errcode_t ima_add_ref(ext2_irel irel, ext2_ino_t ino, | ||
232 | struct ext2_inode_reference *ref) | ||
233 | { | ||
234 | struct irel_ma *ma; | ||
235 | size_t size; | ||
236 | struct inode_reference_entry *ref_ent; | ||
237 | struct ext2_inode_relocate_entry *ent; | ||
238 | errcode_t retval; | ||
239 | |||
240 | ma = irel->priv_data; | ||
241 | if (ino > ma->max_inode) | ||
242 | return EXT2_ET_INVALID_ARGUMENT; | ||
243 | |||
244 | ref_ent = ma->ref_entries + (unsigned) ino; | ||
245 | ent = ma->entries + (unsigned) ino; | ||
246 | |||
247 | /* | ||
248 | * If the inode reference array doesn't exist, create it. | ||
249 | */ | ||
250 | if (ref_ent->refs == 0) { | ||
251 | size = (size_t) ((sizeof(struct ext2_inode_reference) * | ||
252 | ent->max_refs)); | ||
253 | retval = ext2fs_get_mem(size, &ref_ent->refs); | ||
254 | if (retval) | ||
255 | return retval; | ||
256 | memset(ref_ent->refs, 0, size); | ||
257 | ref_ent->num = 0; | ||
258 | } | ||
259 | |||
260 | if (ref_ent->num >= ent->max_refs) | ||
261 | return EXT2_ET_TOO_MANY_REFS; | ||
262 | |||
263 | ref_ent->refs[(unsigned) ref_ent->num++] = *ref; | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | static errcode_t ima_start_iter_ref(ext2_irel irel, ext2_ino_t ino) | ||
268 | { | ||
269 | struct irel_ma *ma; | ||
270 | |||
271 | ma = irel->priv_data; | ||
272 | if (ino > ma->max_inode) | ||
273 | return EXT2_ET_INVALID_ARGUMENT; | ||
274 | if (ma->entries[(unsigned) ino].new == 0) | ||
275 | return ENOENT; | ||
276 | ma->ref_current = ino; | ||
277 | ma->ref_iter = 0; | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static errcode_t ima_next_ref(ext2_irel irel, | ||
282 | struct ext2_inode_reference *ref) | ||
283 | { | ||
284 | struct irel_ma *ma; | ||
285 | struct inode_reference_entry *ref_ent; | ||
286 | |||
287 | ma = irel->priv_data; | ||
288 | |||
289 | ref_ent = ma->ref_entries + ma->ref_current; | ||
290 | |||
291 | if ((ref_ent->refs == NULL) || | ||
292 | (ma->ref_iter >= ref_ent->num)) { | ||
293 | ref->block = 0; | ||
294 | ref->offset = 0; | ||
295 | return 0; | ||
296 | } | ||
297 | *ref = ref_ent->refs[ma->ref_iter++]; | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | |||
302 | static errcode_t ima_move(ext2_irel irel, ext2_ino_t old, ext2_ino_t new) | ||
303 | { | ||
304 | struct irel_ma *ma; | ||
305 | |||
306 | ma = irel->priv_data; | ||
307 | if ((old > ma->max_inode) || (new > ma->max_inode)) | ||
308 | return EXT2_ET_INVALID_ARGUMENT; | ||
309 | if (ma->entries[(unsigned) old].new == 0) | ||
310 | return ENOENT; | ||
311 | |||
312 | ma->entries[(unsigned) new] = ma->entries[(unsigned) old]; | ||
313 | ext2fs_free_mem(&ma->ref_entries[(unsigned) new].refs); | ||
314 | ma->ref_entries[(unsigned) new] = ma->ref_entries[(unsigned) old]; | ||
315 | |||
316 | ma->entries[(unsigned) old].new = 0; | ||
317 | ma->ref_entries[(unsigned) old].num = 0; | ||
318 | ma->ref_entries[(unsigned) old].refs = 0; | ||
319 | |||
320 | ma->orig_map[ma->entries[new].orig] = new; | ||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static errcode_t ima_delete(ext2_irel irel, ext2_ino_t old) | ||
325 | { | ||
326 | struct irel_ma *ma; | ||
327 | |||
328 | ma = irel->priv_data; | ||
329 | if (old > ma->max_inode) | ||
330 | return EXT2_ET_INVALID_ARGUMENT; | ||
331 | if (ma->entries[(unsigned) old].new == 0) | ||
332 | return ENOENT; | ||
333 | |||
334 | ma->entries[old].new = 0; | ||
335 | ext2fs_free_mem(&ma->ref_entries[(unsigned) old].refs); | ||
336 | ma->orig_map[ma->entries[(unsigned) old].orig] = 0; | ||
337 | |||
338 | ma->ref_entries[(unsigned) old].num = 0; | ||
339 | ma->ref_entries[(unsigned) old].refs = 0; | ||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | static errcode_t ima_free(ext2_irel irel) | ||
344 | { | ||
345 | struct irel_ma *ma; | ||
346 | ext2_ino_t ino; | ||
347 | |||
348 | if (!irel) | ||
349 | return 0; | ||
350 | |||
351 | ma = irel->priv_data; | ||
352 | |||
353 | if (ma) { | ||
354 | ext2fs_free_mem(&ma->orig_map); | ||
355 | ext2fs_free_mem(&ma->entries); | ||
356 | if (ma->ref_entries) { | ||
357 | for (ino = 0; ino <= ma->max_inode; ino++) { | ||
358 | ext2fs_free_mem(&ma->ref_entries[(unsigned) ino].refs); | ||
359 | } | ||
360 | ext2fs_free_mem(&ma->ref_entries); | ||
361 | } | ||
362 | ext2fs_free_mem(&ma); | ||
363 | } | ||
364 | ext2fs_free_mem(&irel->name); | ||
365 | ext2fs_free_mem(&irel); | ||
366 | return 0; | ||
367 | } | ||