From df3d2ef98b911ebb7a7b7c6137e60e28eb39e5f1 Mon Sep 17 00:00:00 2001 From: Stelian Pop Date: Thu, 7 Jul 2005 09:16:03 +0000 Subject: [PATCH] Make the directory hashtable optional and controled via restore -H --- CHANGES | 6 +++++- restore/main.c | 27 ++++++++++++++++++--------- restore/restore.8.in | 24 ++++++++++++++++-------- restore/restore.c | 8 ++++---- restore/restore.h | 5 ++--- restore/symtab.c | 29 +++++++++++++++++------------ restore/utilities.c | 6 +++--- 7 files changed, 65 insertions(+), 40 deletions(-) diff --git a/CHANGES b/CHANGES index 2099f0e..2a51705 100644 --- 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) ================================================================= diff --git a/restore/main.c b/restore/main.c index dfbe8c6..496391d 100644 --- a/restore/main.c +++ b/restore/main.c @@ -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 @@ -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': diff --git a/restore/restore.8.in b/restore/restore.8.in index 1d92342..9f813ca 100644 --- a/restore/restore.8.in +++ b/restore/restore.8.in @@ -25,14 +25,14 @@ .\" 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 diff --git a/restore/restore.c b/restore/restore.c index 94e0bb6..67a8465 100644 --- a/restore/restore.c +++ b/restore/restore.c @@ -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 @@ -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; diff --git a/restore/restore.h b/restore/restore.h index 4f5236f..3d2a5de 100644 --- a/restore/restore.h +++ b/restore/restore.h @@ -5,7 +5,7 @@ * Stelian Pop , 1999-2000 * Stelian Pop - AlcĂ´ve , 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 diff --git a/restore/symtab.c b/restore/symtab.c index 06548bc..7e56057 100644 --- a/restore/symtab.c +++ b/restore/symtab.c @@ -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]]; } diff --git a/restore/utilities.c b/restore/utilities.c index f17bd9c..4dbc13f 100644 --- a/restore/utilities.c +++ b/restore/utilities.c @@ -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 @@ -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; -- 2.39.5