2 * relocate.c --- maintains the relocation table
4 * Copyright (C) 1996 Theodore Ts'o. This file may be redistributed
5 * under the terms of the GNU Public License.
8 #include <et/com_err.h>
11 * This routine creates a relocation table
13 errcode_t ext2fs_create_relocation_table(__u32 max, int size,
14 ext2_relocate_table *ret);
16 ext2_relocate_table table;
18 table = malloc(sizeof(struct ext2_relocate_struct));
23 table->size = size ? size : 30;
25 table->entries = malloc(table->size * sizeof(ext2_relocate_entry));
26 if (table->entries == 0) {
30 memset(table->entries, 0, table->size * sizeof(ext2_relocate_entry));
36 * Free a relocation table
38 void ext2fs_free_relocation_table(ext2_relocate_table table)
48 * Add a relocation table entry
50 errcode_t ext2fs_add_relocation(ext2_relocate_table table, __u32 old,
51 __u32 new, __u32 owner)
53 struct ext2_relocate_entry *new;
55 if (table->count >= table->size) {
57 new = realloc(table->entries,
58 table->size * sizeof(ext2_relocate_entry));
63 if (table->count && table->entries[table->count-1].old > old) {
64 for (i = table->count-1; i > 0; i--)
65 if (table->entries[i-1].old < old)
67 new = &table->entries[i];
69 for (j = table->count++; j > i; j--)
70 table->entries[j] = table_entries[j-1];
72 new = &table->entries[table->coun++];
80 * ext2fs_get_reloc_by_old() --- given the source of the relcation
81 * entry, find the entry for it.
83 struct relocate_entry *ext2fs_get_reloc_by_old(ext2_relocate_table tbl,
91 if (old == table->entries[low].old)
92 return &table->entries[low];
93 if (old == table->entries[high].old)
94 return &table->entries[high];
98 if (mid == low || mid == high)
100 if (old == table->entries[mid].old)
101 return &table->entries[mid];
102 if (old < table->entries[mid].old)
111 * ext2fs_get_reloc_by_new() --- given the destination of the relcation
112 * entry, find the entry for it.
114 * Note: this is currently very slow...
116 struct relocate_entry *ext2fs_get_reloc_by_new(ext2_relocate_table tbl,
121 for (i = 0; i < table->count; i++) {
122 if (tbl->entries[i].new == new)
123 return &table->entries[i];
129 * Find "loops" in the relocation tables
133 struct ext2_relocate_entry *ent, *next;
136 for (i=0, ent=table->entries; i < table->size; i++, ent++) {
138 * If we know this inode is OK, then keep going.
140 if (ext2fs_test_generic_bitmap(done_map, dir->old))
142 ext2fs_clear_generic_bitmap(loop_detect);
144 ext2fs_mark_generic_bitmap(loop_detect, dir->old);
145 next = ext2fs_get_reloc_by_old(table, dir->new);
148 if (ext2fs_test_generic_bitmap(loop_detect,
150 break_loop(table, dir);
151 ext2fs_mark_generic_bitmap(done_map, dir->old);