Date: Mon, 22 Jul 2002 12:43:18 -0700 (PDT) From: Matthew Dillon <dillon@apollo.backplane.com> To: Andreas Koch <koch@eis.cs.tu-bs.de>, freebsd-stable@FreeBSD.ORG Subject: Re: 4.6-RC: Glacial speed of dump backups Message-ID: <200207221943.g6MJhIBX054785@apollo.backplane.com> References: <20020606204948.GA4540@ultra4.eis.cs.tu-bs.de> <20020722081614.E367@gsmx07.alcatel.com.au> <20020722100408.GP26095@ultra4.eis.cs.tu-bs.de>
next in thread | previous in thread | raw e-mail | index | archive | help
Here are the preliminary results when I test this dumping /usr to /dev/null: DUMP: finished in 140 seconds, throughput 6413 KBytes/sec (8 MB cache) DUMP: finished in 144 seconds, throughput 6235 KBytes/sec (4 MB cache) DUMP: finished in 234 seconds, throughput 3836 KBytes/sec (0 MB cache) Slightly new patch then the last one I posted (this one allowed you to specify a cache size of 0): -Matt Index: Makefile =================================================================== RCS file: /home/ncvs/src/sbin/dump/Makefile,v retrieving revision 1.12.2.2 diff -u -r1.12.2.2 Makefile --- Makefile 5 Oct 2001 15:49:11 -0000 1.12.2.2 +++ Makefile 22 Jul 2002 17:31:09 -0000 @@ -17,7 +17,7 @@ LINKS= ${BINDIR}/dump ${BINDIR}/rdump CFLAGS+=-DRDUMP CFLAGS+=-I${.CURDIR}/../../libexec/rlogind -SRCS= itime.c main.c optr.c dumprmt.c tape.c traverse.c unctime.c +SRCS= itime.c main.c optr.c dumprmt.c tape.c traverse.c unctime.c cache.c MAN= dump.8 MLINKS+=dump.8 rdump.8 Index: cache.c =================================================================== RCS file: cache.c diff -N cache.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ cache.c 22 Jul 2002 19:29:20 -0000 @@ -0,0 +1,132 @@ +/* + * CACHE.C + * + * Block cache for dump + * + * $FreeBSD$ + */ + +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/mman.h> + +#ifdef sunos +#include <sys/vnode.h> + +#include <ufs/fs.h> +#include <ufs/fsdir.h> +#include <ufs/inode.h> +#else +#include <ufs/ufs/dir.h> +#include <ufs/ufs/dinode.h> +#include <ufs/ffs/fs.h> +#endif + +#include <protocols/dumprestore.h> + +#include <ctype.h> +#include <stdio.h> +#ifdef __STDC__ +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#endif +#include "dump.h" + +typedef struct Block { + struct Block *b_HNext; /* must be first field */ + off_t b_Offset; + char *b_Data; +} Block; + +#define HFACTOR 4 + +static char *DataBase; +static Block **BlockHash; +static int BlockSize; +static int HSize; +static int NBlocks; + +static void +cinit(void) +{ + int i; + int hi; + Block *base; + + if ((BlockSize = sblock->fs_bsize * 4) > MAXBSIZE) + BlockSize = MAXBSIZE; + NBlocks = cachesize / BlockSize; + HSize = NBlocks / HFACTOR; + + msg("Cache %d MB, blocksize = %d\n", NBlocks * BlockSize, BlockSize); + + base = calloc(sizeof(Block), NBlocks); + BlockHash = calloc(sizeof(Block *), HSize); + DataBase = mmap(NULL, NBlocks * BlockSize, + PROT_READ|PROT_WRITE, MAP_ANON, -1, 0); + for (i = 0; i < NBlocks; ++i) { + base[i].b_Data = DataBase + i * BlockSize; + base[i].b_Offset = (off_t)-1; + hi = i / HFACTOR; + base[i].b_HNext = BlockHash[hi]; + BlockHash[hi] = &base[i]; + } +} + +ssize_t +cread(int fd, void *buf, size_t nbytes, off_t offset) +{ + Block *blk; + Block **pblk; + Block **ppblk; + int hi; + int n; + off_t mask; + + if (sblock->fs_bsize && DataBase == NULL) { + if (cachesize <= 0) + return(pread(fd, buf, nbytes, offset)); + cinit(); + } + mask = ~(off_t)(BlockSize - 1); + if (nbytes > BlockSize || + ((offset ^ (offset + nbytes - 1)) & mask) != 0) { + return(pread(fd, buf, nbytes, offset)); + } + hi = (offset / BlockSize) % HSize; + pblk = &BlockHash[hi]; + ppblk = NULL; + while ((blk = *pblk) != NULL) { + if (((blk->b_Offset ^ offset) & mask) == 0) { +#if 0 + fprintf(stderr, "%08llx %d (%08x)\n", offset, nbytes, + sblock->fs_size * sblock->fs_fsize); +#endif + break; + } + ppblk = pblk; + pblk = &blk->b_HNext; + } + if (blk == NULL) { + blk = *ppblk; + pblk = ppblk; + blk->b_Offset = offset & mask; + n = pread(fd, blk->b_Data, BlockSize, blk->b_Offset); + if (n != BlockSize) { + blk->b_Offset = (off_t)-1; + blk = NULL; + } + } + if (blk) { + bcopy(blk->b_Data + (offset - blk->b_Offset), buf, nbytes); + *pblk = blk->b_HNext; + blk->b_HNext = BlockHash[hi]; + BlockHash[hi] = blk; + return(nbytes); + } else { + return(pread(fd, buf, nbytes, offset)); + } +} + Index: dump.h =================================================================== RCS file: /home/ncvs/src/sbin/dump/dump.h,v retrieving revision 1.7.6.3 diff -u -r1.7.6.3 dump.h --- dump.h 23 Feb 2002 22:32:51 -0000 1.7.6.3 +++ dump.h 22 Jul 2002 18:21:01 -0000 @@ -77,6 +77,7 @@ int etapes; /* estimated number of tapes */ int nonodump; /* if set, do not honor UF_NODUMP user flags */ int unlimited; /* if set, write to end of medium */ +int cachesize; /* size of block cache */ int notify; /* notify operator flag */ int blockswritten; /* number of blocks written on current tape */ Index: main.c =================================================================== RCS file: /home/ncvs/src/sbin/dump/main.c,v retrieving revision 1.20.2.8 diff -u -r1.20.2.8 main.c --- main.c 1 Jul 2002 00:35:49 -0000 1.20.2.8 +++ main.c 22 Jul 2002 18:51:37 -0000 @@ -84,6 +84,7 @@ int ntrec = NTREC; /* # tape blocks in each tape record */ int cartridge = 0; /* Assume non-cartridge tape */ int dokerberos = 0; /* Use Kerberos authentication */ +int cachesize = 4 * 1024 * 1024; /* block cache size */ long dev_bsize = 1; /* recalculated below */ long blocksperfile; /* output blocks per file */ char *host = NULL; /* remote host (if any) */ @@ -125,9 +126,9 @@ obsolete(&argc, &argv); #ifdef KERBEROS -#define optstring "0123456789aB:b:cd:f:h:kns:ST:uWwD:" +#define optstring "0123456789aB:b:cd:f:h:kns:ST:uWwD:C:" #else -#define optstring "0123456789aB:b:cd:f:h:ns:ST:uWwD:" +#define optstring "0123456789aB:b:cd:f:h:ns:ST:uWwD:C:" #endif while ((ch = getopt(argc, argv, optstring)) != -1) #undef optstring @@ -168,6 +169,10 @@ case 'D': dumpdates = optarg; + break; + + case 'C': + cachesize = numarg("cachesize", 0, 0) * 1024 * 1024; break; case 'h': Index: traverse.c =================================================================== RCS file: /home/ncvs/src/sbin/dump/traverse.c,v retrieving revision 1.10.2.4 diff -u -r1.10.2.4 traverse.c --- traverse.c 14 Jul 2001 13:51:37 -0000 1.10.2.4 +++ traverse.c 22 Jul 2002 17:31:33 -0000 @@ -601,7 +601,7 @@ int cnt, i; loop: - if ((cnt = pread(diskfd, buf, size, ((off_t)blkno << dev_bshift))) == + if ((cnt = cread(diskfd, buf, size, ((off_t)blkno << dev_bshift))) == size) return; if (blkno + (size / dev_bsize) > fsbtodb(sblock, sblock->fs_size)) { To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-stable" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200207221943.g6MJhIBX054785>