Hi guys.  I've been following this thread and it occured to me
    that it might be possible to write a very quick cache if we 
    ignored shareability between forked dumps.

    I've done so.   It actually does appear to make a considerable
    difference even with a tiny (4MB default) cache.  Please try the 
    below patch and tell me what you think.  It isn't perfect and 
    I'm sure bad things could happen on machines which do not have
    much memory, and I haven't tested it all that much, but....

                                                -Matt

:Peter,
:
:many thanks for the reply, I had already given up hope of seeing one
:at all :-)
:
:I have already been looking at the NetBSD dump shortly after my initial
:message. Their version has a _considerably_ improved internal buffering
:architecture.  However, my time-limited porting efforts have not been
:...
:So, it appears some more effort is required here.  I plan to look into
:this more closely, but I am currently swamped at work.  However, the
:potential gains seem to be worthwhile:  On our preliminary benchmarks,
:NetBSD dump running on a low-end Athlon (from a 7.2K rpm SCSI disk)
:_easily_ beats the backup throughput of Solaris 2.8 dump (mirrored 15K
:rpm SCSI disks) on a U280R (2x USIII+ 1GHz).
:
:Andreas Koch
: -- for now making do with the dump | team kludge ...
:-- 
:Andreas Koch                                      Email  : [EMAIL PROTECTED]


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:15:21 -0000
@@ -0,0 +1,129 @@
+/*
+ * 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)
+               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 [EMAIL PROTECTED]
with "unsubscribe freebsd-stable" in the body of the message

Reply via email to