Skip site navigation (1)Skip section navigation (2)
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>