Make the directory hashtable optional and controled via restore -H
authorStelian Pop <stelian@popies.net>
Thu, 7 Jul 2005 09:16:03 +0000 (09:16 +0000)
committerStelian Pop <stelian@popies.net>
Thu, 7 Jul 2005 09:16:03 +0000 (09:16 +0000)
CHANGES
restore/main.c
restore/restore.8.in
restore/restore.c
restore/restore.h
restore/symtab.c
restore/utilities.c

diff --git a/CHANGES b/CHANGES
index 2099f0eaf6202940514f7a840fc3c6aab3770e69..2a5170561fc69d0702b1d8606371e074540b5641 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,4 @@
-$Id: CHANGES,v 1.278 2005/07/07 08:47:13 stelian Exp $
+$Id: CHANGES,v 1.279 2005/07/07 09:16:03 stelian Exp $
 
 Changes between versions 0.4b40 and 0.4b41 (released ???????????)
 =================================================================
@@ -12,6 +12,10 @@ Changes between versions 0.4b40 and 0.4b41 (released ???????????)
 
 3.     Fix restore when the symtab is over 2GB in size.
 
+4.     Made the directory hash indexing an optional feature,
+       accessible by the '-H' option of restore, and disable it
+       by default.
+
 Changes between versions 0.4b39 and 0.4b40 (released May 2, 2005)
 =================================================================
 
index dfbe8c6ce557ca18d282e67c290b0f8f0ad911ef..496391d759f612660c3568407edb78a5e3f3f723 100644 (file)
@@ -37,7 +37,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: main.c,v 1.49 2005/01/14 13:04:56 stelian Exp $";
+       "$Id: main.c,v 1.50 2005/07/07 09:16:08 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -113,6 +113,7 @@ static const char *stdin_opt = NULL;
 char   *bot_script = NULL;
 dump_ino_t volinfo[TP_NINOS];
 int    wdfd;
+int    dirhash_size = 1;
 
 #ifdef USE_QFA
 FILE   *gTapeposfp;
@@ -177,7 +178,7 @@ main(int argc, char *argv[])
                ;                                                               
        obsolete(&argc, &argv);
        while ((ch = getopt(argc, argv, 
-               "aA:b:CcdD:f:F:hi"
+               "aA:b:CcdD:f:F:hH:i"
 #ifdef KERBEROS
                "k"
 #endif
@@ -227,6 +228,13 @@ main(int argc, char *argv[])
                case 'h':
                        hflag = 0;
                        break;
+               case 'H':
+                       dirhash_size = strtol(optarg, &p, 10);
+                       if (*p)
+                               errx(1, "illegal hash size -- %s", optarg);
+                       if (dirhash_size < 1)
+                               errx(1, "hash size must be greater than 0");
+                       break;
 #ifdef KERBEROS
                case 'k':
                        dokerberos = 1;
@@ -679,21 +687,21 @@ usage(void)
 
        fprintf(stderr,
                "usage:"
-               "\t%s -C [-cd" kerbflag "lMvVy] [-b blocksize] [-D filesystem] [-f file]\n"
+               "\t%s -C [-cdH" kerbflag "lMvVy] [-b blocksize] [-D filesystem] [-f file]\n"
                "\t%s    [-F script] [-L limit] [-s fileno]\n"
-               "\t%s -i [-acdh" kerbflag "lmMouvVy] [-A file] [-b blocksize] [-f file]\n"
+               "\t%s -i [-acdhH" kerbflag "lmMouvVy] [-A file] [-b blocksize] [-f file]\n"
                "\t%s    [-F script] " qfaflag "[-s fileno]\n"
 #ifdef USE_QFA
-               "\t%s -P file [-acdh" kerbflag "lmMuvVy] [-A file] [-b blocksize]\n"
+               "\t%s -P file [-acdhH" kerbflag "lmMuvVy] [-A file] [-b blocksize]\n"
                "\t%s    [-f file] [-F script] [-s fileno] [-X filelist] [file ...]\n"
 #endif
-               "\t%s -r [-cd" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script]\n"
+               "\t%s -r [-cdH" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script]\n"
                "\t%s    [-s fileno] [-T directory]\n"
-               "\t%s -R [-cd" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script]\n"
+               "\t%s -R [-cdH" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script]\n"
                "\t%s    [-s fileno] [-T directory]\n"
-               "\t%s -t [-cdh" kerbflag "lMuvVy] [-A file] [-b blocksize] [-f file]\n"
+               "\t%s -t [-cdhH" kerbflag "lMuvVy] [-A file] [-b blocksize] [-f file]\n"
                "\t%s    [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]\n"
-               "\t%s -x [-acdh" kerbflag "lmMouvVy] [-A file] [-b blocksize] [-f file]\n"
+               "\t%s -x [-acdhH" kerbflag "lmMouvVy] [-A file] [-b blocksize] [-f file]\n"
                "\t%s    [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]\n",
                __progname, white, 
                __progname, white, 
@@ -742,6 +750,7 @@ obsolete(int *argcp, char **argvp[])
                case 'D':
                case 'f':
                case 'F':
+               case 'H':
                case 'L':
                case 'Q':
                case 's':
index 1d9234220e6415a807626bb04c6b719dcefa8e5d..9f813ca4b17c376f6250f6c7a5f9abee19175dae 100644 (file)
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\"    $Id: restore.8.in,v 1.32 2004/07/13 08:17:32 stelian Exp $
+.\"    $Id: restore.8.in,v 1.33 2005/07/07 09:16:08 stelian Exp $
 .\"
 .TH RESTORE 8 "version __VERSION__ of __DATE__" BSD "System management commands"
 .SH NAME
 restore \- restore files or file systems from backups made with dump
 .SH SYNOPSIS
 .B restore \-C 
-[\fB\-cdklMvVy\fR]
+[\fB\-cdHklMvVy\fR]
 [\fB\-b \fIblocksize\fR]
 [\fB\-D \fIfilesystem\fR]
 [\fB\-f \fIfile\fR]
@@ -42,7 +42,7 @@ restore \- restore files or file systems from backups made with dump
 [\fB\-T \fIdirectory\fR]
 .PP
 .B restore \-i
-[\fB\-acdhklmMNouvVy\fR]
+[\fB\-acdhHklmMNouvVy\fR]
 [\fB\-A \fIfile\fR]
 [\fB\-b \fIblocksize\fR]
 [\fB\-f \fIfile\fR]
@@ -53,7 +53,7 @@ restore \- restore files or file systems from backups made with dump
 .PP
 .B restore \-P 
 .I file
-[\fB\-acdhklmMNuvVy\fR]
+[\fB\-acdhHklmMNuvVy\fR]
 [\fB\-A \fIfile\fR]
 [\fB\-b \fIblocksize\fR]
 [\fB\-f \fIfile\fR]
@@ -64,7 +64,7 @@ restore \- restore files or file systems from backups made with dump
 [ \fIfile ... \fR]
 .PP
 .B restore \-R
-[\fB\-cdklMNuvVy\fR]
+[\fB\-cdHklMNuvVy\fR]
 [\fB\-b \fIblocksize\fR]
 [\fB\-f \fIfile\fR]
 [\fB\-F \fIscript\fR]
@@ -72,7 +72,7 @@ restore \- restore files or file systems from backups made with dump
 [\fB\-T \fIdirectory\fR]
 .PP
 .B restore \-r 
-[\fB\-cdklMNuvVy\fR]
+[\fB\-cdHklMNuvVy\fR]
 [\fB\-b \fIblocksize\fR]
 [\fB\-f \fIfile\fR]
 [\fB\-F \fIscript\fR]
@@ -80,7 +80,7 @@ restore \- restore files or file systems from backups made with dump
 [\fB\-T \fIdirectory\fR]
 .PP
 .B restore \-t
-[\fB\-cdhklMNuvVy\fR]
+[\fB\-cdhHklMNuvVy\fR]
 [\fB\-A \fIfile\fR]
 [\fB\-b \fIblocksize\fR]
 [\fB\-f \fIfile\fR]
@@ -92,7 +92,7 @@ restore \- restore files or file systems from backups made with dump
 [ \fIfile ... \fR]
 .PP
 .B restore \-x 
-[\fB\-adchklmMNouvVy\fR]
+[\fB\-adchHklmMNouvVy\fR]
 [\fB\-A \fIfile\fR]
 [\fB\-b \fIblocksize\fR]
 [\fB\-f \fIfile\fR]
@@ -375,6 +375,14 @@ script.
 Extract the actual directory, rather than the files that it references. This 
 prevents hierarchical restoration of complete subtrees from the dump.
 .TP
+.BI \-H " hash_size"
+Use a hashtable having the specified number of entries for storing the
+directories entries instead of a linked list. This hashtable will
+considerably speed up inode lookups (visible especialy in interactive
+mode when adding/removing files from the restore list), but at the
+price of much more memory usage. The default value is 1, meaning no
+hashtable is used.
+.TP
 .B \-k
 Use Kerberos authentication when contacting the remote tape server. (Only 
 available if this options was enabled when
index 94e0bb6cc8f853c5a4243aeaf0c2dcf738568a2c..67a8465904dd26f81a911f249cd7cc8e0c80b77a 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.37 2005/07/07 09:16:08 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -581,7 +581,7 @@ 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) {
                                        Dprintf(stdout,
@@ -599,7 +599,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)
@@ -638,7 +638,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;
index 4f5236f4ac7466c17bbe8bf3c01a4c959db5e6df..3d2a5de310c517ca8f3ac5608dbdb84c6ab635ca 100644 (file)
@@ -5,7 +5,7 @@
  *     Stelian Pop <stelian@popies.net>, 1999-2000
  *     Stelian Pop <stelian@popies.net> - AlcĂ´ve <www.alcove.com>, 2000-2002
  *
- *     $Id: restore.h,v 1.32 2005/05/02 15:10:46 stelian Exp $
+ *     $Id: restore.h,v 1.33 2005/07/07 09:16:08 stelian Exp $
  */
 
 /*
@@ -92,8 +92,7 @@ extern int    compare_errors; /* did we encounter any compare errors? */
 extern char    filesys[NAMELEN];/* name of dumped filesystem */
 extern dump_ino_t volinfo[];   /* which inode on which volume archive info */
 extern int     wdfd;           /* original working directory */
-
-#define DIRHASH_SIZE 1024
+extern int     dirhash_size;   /* size of the directory hash table */
 
 /*
  * Each file in the file system is described by one of these entries
index 06548bcee6e5a84c7bbd0e8eae6c614eb877b57d..7e5605730db48ce73ca6472178b1bcd6f5b668cd 100644 (file)
@@ -37,7 +37,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: symtab.c,v 1.26 2005/07/07 08:47:16 stelian Exp $";
+       "$Id: symtab.c,v 1.27 2005/07/07 09:16:08 stelian Exp $";
 #endif /* not lint */
 
 /*
@@ -118,7 +118,7 @@ dir_hash(char *name)
                hash1 = hash0;
                hash0 = hash; 
        }       
-       return hash0 % DIRHASH_SIZE;
+       return hash0 % dirhash_size;
 }
 
 /*
@@ -220,7 +220,7 @@ lookupname(char *name)
                        /* search all hash lists for renamed inodes */
                        if (ep == NULL) {
                                int j;
-                               for (j = 0; j < DIRHASH_SIZE; j++) {
+                               for (j = 0; j < dirhash_size; j++) {
                                        ep = oldep->e_entries[j];
                                        for ( ; ep != NULL; ep = ep->e_sibling)
                                                if (strcmp(ep->e_name, buf) == 0)
@@ -307,7 +307,7 @@ addentry(char *name, dump_ino_t inum, int type)
        }
        np->e_type = type & ~LINK;
        if (type & NODE) {
-               np->e_entries = calloc(1, DIRHASH_SIZE * sizeof(struct entry *));
+               np->e_entries = calloc(1, dirhash_size * sizeof(struct entry *));
                if (np->e_entries == NULL)
                        panic("unable to allocate directory entries\n");
        }
@@ -357,7 +357,7 @@ freeentry(struct entry *ep)
                        badentry(ep, "freeing referenced directory");
                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) 
                                        badentry(ep, "freeing non-empty directory");
                        }
@@ -439,7 +439,7 @@ removeentry(struct entry *ep)
 
                        /* search all hash lists for renamed inodes */
                        int j;
-                       for (j = 0; j < DIRHASH_SIZE; j++) {
+                       for (j = 0; j < dirhash_size; j++) {
                                np = ep->e_parent;
                                entry = np->e_entries[j];
                                if (entry == ep) {
@@ -550,7 +550,7 @@ dumpsymtable(char *filename, long checkpt)
        long mynum = 1, stroff = 0, hashoff = 0;
        FILE *fd;
        struct symtableheader hdr;
-       struct entry *temphash[DIRHASH_SIZE];
+       struct entry **temphash;
 
        Vprintf(stdout, "Check pointing the restore\n");
        if (Nflag)
@@ -575,19 +575,24 @@ dumpsymtable(char *filename, long checkpt)
        /*
         * Write out e_entries tables
         */
+       temphash = calloc(1, dirhash_size * sizeof(struct entry *));
+       if (temphash == NULL)
+               errx(1, "no memory for saving hashtable");
        for (i = WINO; i <= maxino; i++) {
                for (ep = lookupino(i); ep != NULL; ep = ep->e_links) {
                        if (ep->e_entries != NULL) {
                                int j;
-                               memcpy(temphash, ep->e_entries, DIRHASH_SIZE * sizeof(struct entry *));
-                               for (j = 0; j < DIRHASH_SIZE; j++) {
+                               memcpy(temphash, ep->e_entries, dirhash_size * sizeof(struct entry *));
+                               for (j = 0; j < dirhash_size; j++) {
                                        if (temphash[j])
                                                temphash[j] = (struct entry *)ep->e_entries[j]->e_index;
                                }
-                               fwrite(temphash, DIRHASH_SIZE, sizeof(struct entry *), fd);
+                               fwrite(temphash, dirhash_size, sizeof(struct entry *), fd);
                        }
                }
        }
+       free(temphash);
+
        /*
         * Convert pointers to indexes, and output
         */
@@ -608,7 +613,7 @@ dumpsymtable(char *filename, long checkpt)
                                        (struct entry *)ep->e_sibling->e_index;
                        if (ep->e_entries != NULL) {
                                tep->e_entries = (struct entry **)hashoff;
-                               hashoff += DIRHASH_SIZE * sizeof(struct entry *);
+                               hashoff += dirhash_size * sizeof(struct entry *);
                        }
                        if (ep->e_next != NULL)
                                tep->e_next =
@@ -737,7 +742,7 @@ initsymtable(char *filename)
                if (ep->e_type == NODE) {
                        int i;
                        ep->e_entries = (struct entry **)(base + hdr.stringsize + (long)ep->e_entries);
-                       for (i = 0; i < DIRHASH_SIZE; i++) {
+                       for (i = 0; i < dirhash_size; i++) {
                                if (ep->e_entries[i])
                                        ep->e_entries[i] = &baseep[(long)ep->e_entries[i]];
                        }
index f17bd9ce458a7214ab50050f787c794d79a033a1..4dbc13fd139bf31d8c1e8311f411dbc10a4ead8a 100644 (file)
@@ -37,7 +37,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: utilities.c,v 1.28 2005/03/30 13:21:45 stelian Exp $";
+       "$Id: utilities.c,v 1.29 2005/07/07 09:16:08 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -189,7 +189,7 @@ removenode(struct entry *ep)
                badentry(ep, "removenode: not a node");
        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)
                                badentry(ep, "removenode: non-empty directory");
                }
@@ -378,7 +378,7 @@ badentry(struct entry *ep, const char *msg)
                fprintf(stderr, "sibling name: %s\n", myname(ep->e_sibling));
        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) {
                                fprintf(stderr, "next entry name: %s\n", myname(ep->e_entries[i]));
                                break;