]> git.wh0rd.org - dump.git/blobdiff - restore/restore.c
Properly deal with inodes excluded from incremental dump
[dump.git] / restore / restore.c
index 94e0bb6cc8f853c5a4243aeaf0c2dcf738568a2c..780fd76f04bdd0a3d61297acf9719c0295a6a805 100644 (file)
@@ -37,7 +37,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: restore.c,v 1.36 2005/03/18 22:12:55 stelian Exp $";
+       "$Id: restore.c,v 1.39 2010/03/22 16:08:10 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -566,6 +566,9 @@ keyval(int key)
 
 /*
  * Find unreferenced link names.
+ *
+ * This also takes care of directories which were missed by removeoldleaves(),
+ * because their inode has been reused, but excluded from the dump.
  */
 void
 findunreflinks(void)
@@ -581,14 +584,21 @@ findunreflinks(void)
                        continue;
                if (ep->e_entries == NULL)
                        continue;
-               for (j = 0; j < DIRHASH_SIZE; j++) {
+               for (j = 0; j < dirhash_size; j++) {
                        for (np = ep->e_entries[j]; np != NULL; np = np->e_sibling) {
-                               if (np->e_flags == 0) {
+                               if ((np->e_flags & ~TMPNAME) == 0) {
                                        Dprintf(stdout,
                                            "%s: remove unreferenced name\n",
                                            myname(np));
-                                       removeleaf(np);
-                                       freeentry(np);
+                                       if (np->e_type == LEAF) {
+                                               removeleaf(np);
+                                               freeentry(np);
+                                       } else {
+                                               np->e_flags |= TMPNAME;
+                                               deleteino(np->e_ino);
+                                               np->e_next = removelist;
+                                               removelist = np;
+                                       }
                                }
                        }
                }
@@ -599,7 +609,7 @@ findunreflinks(void)
        for (ep = removelist; ep != NULL; ep = ep->e_next) {
                if (ep->e_entries == NULL)
                        continue;
-               for (j = 0; j < DIRHASH_SIZE; j++) {
+               for (j = 0; j < dirhash_size; j++) {
                        for (np = ep->e_entries[j]; np != NULL; np = np->e_sibling) {
                                if (np->e_type == LEAF) {
                                        if (np->e_flags != 0)
@@ -609,6 +619,17 @@ findunreflinks(void)
                                            myname(np));
                                        removeleaf(np);
                                        freeentry(np);
+                               } else {
+                                       if ((np->e_flags & ~TMPNAME) != 0)
+                                               badentry(np, "unreferenced with flags");
+
+                                       if (np->e_flags == 0) {
+                                               Dprintf(stdout,
+                                                   "%s: remove unreferenced name\n",
+                                                   myname(np));
+                                               np->e_next = ep->e_next;
+                                               ep->e_next = np;
+                                       }
                                }
                        }
                }
@@ -638,7 +659,7 @@ removeoldnodes(void)
                        int docont = 0;
                        if (ep->e_entries != NULL) {
                                int i;
-                               for (i = 0; i < DIRHASH_SIZE; i++) {
+                               for (i = 0; i < dirhash_size; i++) {
                                        if (ep->e_entries[i] != NULL) {
                                                prev = &ep->e_next;
                                                docont = 1;
@@ -716,7 +737,6 @@ compareleaves(void)
                if (first != curfile.ino) {
                        fprintf(stderr, "expected next file %ld, got %lu\n",
                                (long)first, (unsigned long)curfile.ino);
-                       do_compare_error;
                        skipfile();
                        goto next;
                }