Subject: bin/8317: Generalization of filestore information for dump_*
To: None <gnats-bugs@gnats.netbsd.org>
From: None <perseant@netbsd.org>
List: netbsd-bugs
Date: 09/03/1999 17:36:05
>Number:         8317
>Category:       bin
>Synopsis:       Use ufs filestore-independent abstraction for dump
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Fri Sep  3 17:35:00 1999
>Last-Modified:
>Originator:     Konrad Schroder
>Organization:
						Konrad Schroder
						perseant@hhhh.org
>Release:        1999-09-01
>Environment:
System: NetBSD gro.hhhh.org 1.4 NetBSD 1.4 (GRO) #2: Tue Aug 10 13:01:04 PDT 1999 root@:/usr/src/sys/arch/i386/compile/GRO i386


>Description:
As it stands now the "dump" command is only useful for ffs.  However, with
the addition of a filestore-independent (but still ufs-specific) abstraction,
almost all of the code becomes usable for purposes of a dump_lfs (and possibly
a dump_ext2fs, though I haven't looked at ext2fs specifically).

(Ideally all of the UFS parameters would sit at the head of the superblock
for all UFS filesystems, for use by common fs utilities and boot blocks,
but alas, they were not written so.)
>How-To-Repeat:
Inspection.
>Fix:

The following diff illustrates the change I'd like to make.  Note that
ffs_inode.c is a new file.

Index: Makefile
===================================================================
RCS file: /cvsroot/basesrc/sbin/dump/Makefile,v
retrieving revision 1.22
diff -u -r1.22 Makefile
--- Makefile	1999/03/23 14:22:59	1.22
+++ Makefile	1999/09/04 00:16:34
@@ -15,10 +15,10 @@
 
 PROG=	dump
 LINKS=	${BINDIR}/dump ${BINDIR}/rdump
-CPPFLAGS+=-DRDUMP
+CPPFLAGS+=-DRDUMP -I${.CURDIR}
 # CPPFLAGS+= -DDEBUG -DTDEBUG -DFDEBUG -DWRITEDEBUG -DSTATS -DDIAGNOSTICS
 SRCS=	itime.c main.c optr.c dumprmt.c rcache.c tape.c traverse.c unctime.c \
-	ffs_bswap.c
+	ffs_inode.c ffs_bswap.c
 BINGRP=	tty
 BINMODE=2555
 MAN=	dump.8
Index: dump.h
===================================================================
RCS file: /cvsroot/basesrc/sbin/dump/dump.h,v
retrieving revision 1.16
diff -u -r1.16 dump.h
--- dump.h	1999/03/23 14:22:59	1.16
+++ dump.h	1999/09/04 00:16:35
@@ -41,6 +41,36 @@
 #define MAXNINDIR	(MAXBSIZE / sizeof(daddr_t))
 
 /*
+ * Filestore-independent UFS data, so code can be more easily shared
+ * between ffs, lfs, and maybe ext2fs and others as well.
+ */
+struct ufsi {
+	int64_t ufs_dsize;	/* filesystem size, in sectors */
+	int32_t ufs_bsize;	/* block size */
+	int32_t ufs_bshift;	/* log2(ufs_bsize) */
+	int32_t ufs_fsize;	/* fragment size */
+	int32_t ufs_frag;       /* block size / frag size */
+	int32_t ufs_fsatoda;	/* disk address conversion constant */
+	int32_t	ufs_nindir;	/* disk addresses per indirect block */
+	int32_t ufs_inopb;      /* inodes per block */
+	int32_t ufs_maxsymlinklen; /* max symlink length */
+	int32_t ufs_bmask;      /* block mask */
+	int32_t ufs_fmask;      /* frag mask */
+	int64_t ufs_qbmask;     /* ~ufs_bmask */
+	int64_t ufs_qfmask;     /* ~ufs_fmask */
+};
+#define fsatoda(u,a) ((a) << (u)->ufs_fsatoda)
+#define ufs_fragroundup(u,size) /* calculates roundup(size, ufs_fsize) */ \
+        (((size) + (u)->ufs_qfmask) & (u)->ufs_fmask)
+#define ufs_blkoff(u,loc)   /* calculates (loc % u->ufs_bsize) */ \
+        ((loc) & (u)->ufs_qbmask)
+#define ufs_dblksize(u,d,b) \
+	((((b) >= NDADDR || (d)->di_size >= ((b)+1) << (u)->ufs_bshift \
+		? (u)->ufs_bsize \
+		: (ufs_fragroundup((u), ufs_blkoff(u, (d)->di_size))))))
+struct ufsi *ufsib;
+
+/*
  * Dump maps used to describe what is to be dumped.
  */
 int	mapsize;	/* size of the state maps */
@@ -84,8 +114,7 @@
 int	tapeno;		/* current tape number */
 time_t	tstart_writing;	/* when started writing the first tape block */
 int	xferrate;	/* averaged transfer rate of all volumes */
-struct	fs *sblock;	/* the file system super block */
-char	sblock_buf[MAXBSIZE];
+char	sblock_buf[MAXBSIZE]; /* buffer to hold the superblock */
 long	dev_bsize;	/* block size of underlying disk device */
 int	dev_bshift;	/* log2(dev_bsize) */
 int	tp_bshift;	/* log2(TP_BSIZE) */
Index: ffs_inode.c
===================================================================
RCS file: ffs_inode.c
diff -N ffs_inode.c
--- /dev/null	Fri Sep  3 16:51:08 1999
+++ ffs_inode.c	Fri Sep  3 17:16:35 1999
@@ -0,0 +1,52 @@
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/stat.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>
+#include <ufs/ffs/ffs_extern.h>
+#endif
+
+#include <protocols/dumprestore.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fts.h>
+#include <stdio.h>
+#ifdef __STDC__
+#include <string.h>
+#include <unistd.h>
+#endif
+
+#include "dump.h"
+
+extern struct fs *sblock;
+
+
+struct dinode *
+getino(inum)
+	ino_t inum;
+{
+	static daddr_t minino, maxino;
+	static struct dinode inoblock[MAXINOPB];
+	int i;
+
+	curino = inum;
+	if (inum >= minino && inum < maxino)
+		return (&inoblock[inum - minino]);
+	bread(fsatoda(ufsib, ino_to_fsba(sblock, inum)), (char *)inoblock,
+	    (int)ufsib->ufs_bsize);
+	if (needswap)
+		for (i = 0; i < MAXINOPB; i++)
+			ffs_dinode_swap(&inoblock[i], &inoblock[i]);
+	minino = inum - (inum % INOPB(sblock));
+	maxino = minino + INOPB(sblock);
+	return (&inoblock[inum - minino]);
+}
Index: main.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/dump/main.c,v
retrieving revision 1.22
diff -u -r1.22 main.c
--- main.c	1999/03/23 14:22:59	1.22
+++ main.c	1999/09/04 00:16:35
@@ -95,6 +95,7 @@
 char	*host = NULL;		/* remote host (if any) */
 int	readcache = -1;		/* read cache size (in readblksize blks) */
 int	readblksize = 32 * 1024; /* read block size */
+struct fs *sblock;		/* ffs superblock */
 
 int	main __P((int, char *[]));
 static long numarg __P((char *, long, long));
@@ -119,6 +120,7 @@
 	char *toplevel;
 	int just_estimate = 0;
 	char labelstr[LBLSIZE];
+	struct ufsi ufsi;
 
 	spcl.c_date = 0;
 	(void)time((time_t *)&spcl.c_date);
@@ -420,6 +422,22 @@
 	else
 		msgtail("to %s\n", tape);
 	msg("Label: %s\n", labelstr);
+
+	/* Fill out ufsi struct */
+	ufsi.ufs_dsize = fsbtodb(sblock,sblock->fs_size);
+	ufsi.ufs_bsize = sblock->fs_bsize;
+	ufsi.ufs_bshift = sblock->fs_bshift;
+	ufsi.ufs_fsize = sblock->fs_fsize;
+	ufsi.ufs_frag = sblock->fs_frag;
+	ufsi.ufs_fsatoda = sblock->fs_fsbtodb;
+	ufsi.ufs_nindir = sblock->fs_nindir;
+	ufsi.ufs_inopb = sblock->fs_inopb;
+	ufsi.ufs_maxsymlinklen = sblock->fs_maxsymlinklen;
+	ufsi.ufs_bmask = sblock->fs_bmask;
+	ufsi.ufs_fmask = sblock->fs_fmask;
+	ufsi.ufs_qbmask = sblock->fs_qbmask;
+	ufsi.ufs_qfmask = sblock->fs_qfmask;
+	ufsib = &ufsi;
 
 	dev_bsize = sblock->fs_fsize / fsbtodb(sblock, 1);
 	dev_bshift = ffs(dev_bsize) - 1;
Index: rcache.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/dump/rcache.c,v
retrieving revision 1.1
diff -u -r1.1 rcache.c
--- rcache.c	1999/03/23 14:22:59	1.1
+++ rcache.c	1999/09/04 00:16:35
@@ -43,7 +43,6 @@
 #include <sys/param.h>
 #include <sys/sysctl.h>
 #include <ufs/ufs/dinode.h>
-#include <ufs/ffs/fs.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -100,7 +99,7 @@
 	size_t len;
 	size_t  sharedSize;
 
-	nblksread = (readblksize + sblock->fs_bsize - 1) / sblock->fs_bsize;
+	nblksread = (readblksize + ufsib->ufs_bsize - 1) / ufsib->ufs_bsize;
 	if(cachesize == -1) {	/* Compute from memory available */
 		int usermem;
 		int mib[2] = { CTL_HW, HW_USERMEM };
@@ -359,9 +358,11 @@
 			blockBlkNo = (blkno / nblksread) * nblksread;
 			idx = findlru();
 			rsize = min(nblksread,
-			    fsbtodb(sblock, sblock->fs_size) - blockBlkNo) *
+			    ufsib->ufs_dsize - blockBlkNo) *
 			    dev_bsize;
-
+			if(rsize < 0)
+				fprintf(stderr,"blk %d, rsize=%d (dsize=%d)\n",
+					blockBlkNo, rsize, ufsib->ufs_dsize);
 #ifdef DIAGNOSTICS
 			if (cdesc[idx].owner)
 				fprintf(stderr, "Owner is set (%d, me=%d), can"
Index: tape.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/dump/tape.c,v
retrieving revision 1.18
diff -u -r1.18 tape.c
--- tape.c	1999/03/23 14:22:59	1.18
+++ tape.c	1999/09/04 00:16:35
@@ -53,7 +53,6 @@
 #include <ufs/inode.h>
 #else
 #include <ufs/ufs/dinode.h>
-#include <ufs/ffs/fs.h>
 #endif
 
 #include <protocols/dumprestore.h>
@@ -202,7 +201,7 @@
 {
 	int avail, tpblks, dblkno;
 
-	dblkno = fsbtodb(sblock, blkno);
+	dblkno = fsatoda(ufsib, blkno);
 	tpblks = size >> tp_bshift;
 	while ((avail = MIN(tpblks, ntrec - trecno)) > 0) {
 		slp->req[trecno].dblk = dblkno;
Index: traverse.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/dump/traverse.c,v
retrieving revision 1.25
diff -u -r1.25 traverse.c
--- traverse.c	1999/05/05 16:53:46	1.25
+++ traverse.c	1999/09/04 00:16:35
@@ -117,10 +117,10 @@
 	sizeest = howmany(dp->di_size, TP_BSIZE);
 	if (blkest > sizeest)
 		blkest = sizeest;
-	if (dp->di_size > sblock->fs_bsize * NDADDR) {
+	if (dp->di_size > ufsib->ufs_bsize * NDADDR) {
 		/* calculate the number of indirect blocks on the dump tape */
 		blkest +=
-			howmany(sizeest - NDADDR * sblock->fs_bsize / TP_BSIZE,
+			howmany(sizeest - NDADDR * ufsib->ufs_bsize / TP_BSIZE,
 			TP_NINDIR);
 	}
 	return (blkest + 1);
@@ -330,12 +330,12 @@
 		for (ret = 0, i = 0; filesize > 0 && i < NDADDR; i++) {
 			if (di.di_db[i] != 0)
 				ret |= searchdir(ino, iswap32(di.di_db[i]),
-					(long)dblksize(sblock, &di, i),
+					(long)ufs_dblksize(ufsib, &di, i),
 					filesize, tapesize, nodump);
 			if (ret & HASDUMPEDFILE)
 				filesize = 0;
 			else
-				filesize -= sblock->fs_bsize;
+				filesize -= ufsib->ufs_bsize;
 		}
 		for (i = 0; filesize > 0 && i < NIADDR; i++) {
 			if (di.di_ib[i] == 0)
@@ -381,24 +381,24 @@
 	int i;
 	daddr_t	idblk[MAXNINDIR];
 
-	bread(fsbtodb(sblock, iswap32(blkno)), (char *)idblk,
-		(int)sblock->fs_bsize);
+	bread(fsatoda(ufsib, iswap32(blkno)), (char *)idblk,
+		(int)ufsib->ufs_bsize);
 	if (ind_level <= 0) {
-		for (i = 0; *filesize > 0 && i < NINDIR(sblock); i++) {
+		for (i = 0; *filesize > 0 && i < ufsib->ufs_nindir; i++) {
 			blkno = idblk[i];
 			if (blkno != 0)
 				ret |= searchdir(ino, iswap32(blkno),
-				    sblock->fs_bsize, *filesize,
+				    ufsib->ufs_bsize, *filesize,
 				    tapesize, nodump);
 			if (ret & HASDUMPEDFILE)
 				*filesize = 0;
 			else
-				*filesize -= sblock->fs_bsize;
+				*filesize -= ufsib->ufs_bsize;
 		}
 		return (ret);
 	}
 	ind_level--;
-	for (i = 0; *filesize > 0 && i < NINDIR(sblock); i++) {
+	for (i = 0; *filesize > 0 && i < ufsib->ufs_nindir; i++) {
 		blkno = idblk[i];
 		if (blkno != 0)
 			ret |= dirindir(ino, blkno, ind_level, filesize,
@@ -427,7 +427,7 @@
 	char dblk[MAXBSIZE];
 	ino_t ino;
 
-	bread(fsbtodb(sblock, blkno), dblk, (int)size);
+	bread(fsatoda(ufsib, blkno), dblk, (int)size);
 	if (filesize < size)
 		size = filesize;
 	for (loc = 0; loc < size; ) {
@@ -513,8 +513,8 @@
 		 */
 		if (dp->di_size > 0 &&
 #ifdef FS_44INODEFMT
-		    (dp->di_size < sblock->fs_maxsymlinklen ||
-		     (sblock->fs_maxsymlinklen == 0 && dp->di_blocks == 0))) {
+		    (dp->di_size < ufsib->ufs_maxsymlinklen ||
+		     (ufsib->ufs_maxsymlinklen == 0 && dp->di_blocks == 0))) {
 #else
 		    dp->di_blocks == 0) {
 #endif
@@ -545,12 +545,12 @@
 		msg("Warning: undefined file type 0%o\n", dp->di_mode & IFMT);
 		return;
 	}
-	if (dp->di_size > NDADDR * sblock->fs_bsize)
-		cnt = NDADDR * sblock->fs_frag;
+	if (dp->di_size > NDADDR * ufsib->ufs_bsize)
+		cnt = NDADDR * ufsib->ufs_frag;
 	else
-		cnt = howmany(dp->di_size, sblock->fs_fsize);
+		cnt = howmany(dp->di_size, ufsib->ufs_fsize);
 	blksout(&dp->di_db[0], cnt, ino);
-	if ((size = dp->di_size - NDADDR * sblock->fs_bsize) <= 0)
+	if ((size = dp->di_size - NDADDR * ufsib->ufs_bsize) <= 0)
 		return;
 	for (ind_level = 0; ind_level < NIADDR; ind_level++) {
 		dmpindir(ino, dp->di_ib[ind_level], ind_level, &size);
@@ -573,21 +573,21 @@
 	daddr_t idblk[MAXNINDIR];
 
 	if (blk != 0)
-		bread(fsbtodb(sblock, iswap32(blk)), (char *)idblk,
-			(int) sblock->fs_bsize);
+		bread(fsatoda(ufsib, iswap32(blk)), (char *)idblk,
+			(int) ufsib->ufs_bsize);
 	else
-		memset(idblk, 0, (int)sblock->fs_bsize);
+		memset(idblk, 0, (int)ufsib->ufs_bsize);
 	if (ind_level <= 0) {
-		if (*size < NINDIR(sblock) * sblock->fs_bsize)
-			cnt = howmany(*size, sblock->fs_fsize);
+		if (*size < ufsib->ufs_nindir * ufsib->ufs_bsize)
+			cnt = howmany(*size, ufsib->ufs_fsize);
 		else
-			cnt = NINDIR(sblock) * sblock->fs_frag;
-		*size -= NINDIR(sblock) * sblock->fs_bsize;
+			cnt = ufsib->ufs_nindir * ufsib->ufs_frag;
+		*size -= ufsib->ufs_nindir * ufsib->ufs_bsize;
 		blksout(&idblk[0], cnt, ino);
 		return;
 	}
 	ind_level--;
-	for (i = 0; i < NINDIR(sblock); i++) {
+	for (i = 0; i < ufsib->ufs_nindir; i++) {
 		dmpindir(ino, idblk[i], ind_level, size);
 		if (*size <= 0)
 			return;
@@ -606,8 +606,8 @@
 	daddr_t *bp;
 	int i, j, count, blks, tbperdb;
 
-	blks = howmany(frags * sblock->fs_fsize, TP_BSIZE);
-	tbperdb = sblock->fs_bsize >> tp_bshift;
+	blks = howmany(frags * ufsib->ufs_fsize, TP_BSIZE);
+	tbperdb = ufsib->ufs_bsize >> tp_bshift;
 	for (i = 0; i < blks; i += TP_NINDIR) {
 		if (i + TP_NINDIR > blks)
 			count = blks;
@@ -624,7 +624,7 @@
 		for (j = i; j < count; j += tbperdb, bp++)
 			if (*bp != 0) {
 				if (j + tbperdb <= count)
-					dumpblock(iswap32(*bp), (int)sblock->fs_bsize);
+					dumpblock(iswap32(*bp), (int)ufsib->ufs_bsize);
 				else
 					dumpblock(iswap32(*bp), (count - j) * TP_BSIZE);
 			}
@@ -674,25 +674,4 @@
 	}
 	spcl.c_checksum = iswap32(CHECKSUM - sum);
 	writerec((char *)&spcl, 1);
-}
-
-struct dinode *
-getino(inum)
-	ino_t inum;
-{
-	static daddr_t minino, maxino;
-	static struct dinode inoblock[MAXINOPB];
-	int i;
-
-	curino = inum;
-	if (inum >= minino && inum < maxino)
-		return (&inoblock[inum - minino]);
-	bread(fsbtodb(sblock, ino_to_fsba(sblock, inum)), (char *)inoblock,
-	    (int)sblock->fs_bsize);
-	if (needswap)
-		for (i = 0; i < MAXINOPB; i++)
-			ffs_dinode_swap(&inoblock[i], &inoblock[i]);
-	minino = inum - (inum % INOPB(sblock));
-	maxino = minino + INOPB(sblock);
-	return (&inoblock[inum - minino]);
 }
>Audit-Trail:
>Unformatted: