dave@onfcanim.UUCP (Dave Martindale) (11/29/85)
When writing out the contents of a file to the tape, dump does all its calculations in terms of the frag size of the filesystem it is dumping. Thus the amount of data written to tape is always a multiple of the frag size (rounded up to a multiple of TP_BSIZE, if the frag size is smaller than TP_BSIZE). Unfortunately, restore expects the length of data on tape to be the size listed in the inode rounded up to a multiple of TP_BSIZE. It doesn't care what the filesystem's frag size was (and indeed it shouldn't, since it may be restoring to a filesystem with a different frag size). The result is that when you dump a filesystem with a frag size bigger than 1024 (TP_BSIZE) and then try to restore from that tape, restore will produce a large number of messages (almost 1 per file) about skipping blocks to resync if you try to restore from that tape. As far as I can tell, the extra data written will always be zero, and thus restore will always be able to resynchronize without losing anything, but this is very annoying. From the looks of the code, I think dump will also mess up royally trying to dump a filesystem with a block size that is smaller than TP_BSIZE. Since I don't see why you'd ever want such a filesystem, I'm not going to worry about it. To fix the first problem, just pass blksout() the number of tape blocks rather than frags to write: *** old/dumptraverse.c Tue Feb 5 01:02:55 1985 --- dumptraverse.c Thu Nov 28 23:40:43 1985 *************** *** 163,169 return; } if (ip->di_size > NDADDR * sblock->fs_bsize) ! i = NDADDR * sblock->fs_frag; else i = howmany(ip->di_size, sblock->fs_fsize); blksout(&ip->di_db[0], i); --- 163,169 ----- return; } if (ip->di_size > NDADDR * sblock->fs_bsize) ! i = howmany(NDADDR * sblock->fs_bsize, TP_BSIZE); else i = howmany(ip->di_size, TP_BSIZE); blksout(&ip->di_db[0], i); *************** *** 165,171 if (ip->di_size > NDADDR * sblock->fs_bsize) i = NDADDR * sblock->fs_frag; else ! i = howmany(ip->di_size, sblock->fs_fsize); blksout(&ip->di_db[0], i); size = ip->di_size - NDADDR * sblock->fs_bsize; if (size <= 0) --- 165,171 ----- if (ip->di_size > NDADDR * sblock->fs_bsize) i = howmany(NDADDR * sblock->fs_bsize, TP_BSIZE); else ! i = howmany(ip->di_size, TP_BSIZE); blksout(&ip->di_db[0], i); size = ip->di_size - NDADDR * sblock->fs_bsize; if (size <= 0) *************** *** 191,197 bzero(idblk, sblock->fs_bsize); if (lvl <= 0) { if (*size < NINDIR(sblock) * sblock->fs_bsize) ! cnt = howmany(*size, sblock->fs_fsize); else cnt = NINDIR(sblock) * sblock->fs_frag; *size -= NINDIR(sblock) * sblock->fs_bsize; --- 191,197 ----- bzero(idblk, sblock->fs_bsize); if (lvl <= 0) { if (*size < NINDIR(sblock) * sblock->fs_bsize) ! cnt = howmany(*size, TP_BSIZE); else cnt = howmany(NINDIR(sblock) * sblock->fs_bsize, TP_BSIZE); *************** *** 193,199 if (*size < NINDIR(sblock) * sblock->fs_bsize) cnt = howmany(*size, sblock->fs_fsize); else ! cnt = NINDIR(sblock) * sblock->fs_frag; *size -= NINDIR(sblock) * sblock->fs_bsize; blksout(&idblk[0], cnt); return; --- 193,200 ----- if (*size < NINDIR(sblock) * sblock->fs_bsize) cnt = howmany(*size, TP_BSIZE); else ! cnt = howmany(NINDIR(sblock) * sblock->fs_bsize, ! TP_BSIZE); *size -= NINDIR(sblock) * sblock->fs_bsize; blksout(&idblk[0], cnt); return; *************** *** 206,212 } } ! blksout(blkp, frags) daddr_t *blkp; int frags; { --- 207,213 ----- } } ! blksout(blkp, blks) daddr_t *blkp; int blks; { *************** *** 208,214 blksout(blkp, frags) daddr_t *blkp; ! int frags; { int i, j, count, blks, tbperdb; --- 209,215 ----- blksout(blkp, blks) daddr_t *blkp; ! int blks; { int i, j, count, tbperdb; *************** *** 210,216 daddr_t *blkp; int frags; { ! int i, j, count, blks, tbperdb; blks = howmany(frags * sblock->fs_fsize, TP_BSIZE); tbperdb = sblock->fs_bsize / TP_BSIZE; --- 211,217 ----- daddr_t *blkp; int blks; { ! int i, j, count, tbperdb; tbperdb = sblock->fs_bsize / TP_BSIZE; for (i = 0; i < blks; i += TP_NINDIR) { *************** *** 212,218 { int i, j, count, blks, tbperdb; - blks = howmany(frags * sblock->fs_fsize, TP_BSIZE); tbperdb = sblock->fs_bsize / TP_BSIZE; for (i = 0; i < blks; i += TP_NINDIR) { if (i + TP_NINDIR > blks) --- 213,218 ----- { int i, j, count, tbperdb; tbperdb = sblock->fs_bsize / TP_BSIZE; for (i = 0; i < blks; i += TP_NINDIR) { if (i + TP_NINDIR > blks)