diff options
Diffstat (limited to 'sbin/dump')
-rw-r--r-- | sbin/dump/dump.h | 18 | ||||
-rw-r--r-- | sbin/dump/itime.c | 8 | ||||
-rw-r--r-- | sbin/dump/main.c | 53 | ||||
-rw-r--r-- | sbin/dump/optr.c | 2 | ||||
-rw-r--r-- | sbin/dump/tape.c | 22 | ||||
-rw-r--r-- | sbin/dump/traverse.c | 270 |
6 files changed, 250 insertions, 123 deletions
diff --git a/sbin/dump/dump.h b/sbin/dump/dump.h index 4b42755..cd84596 100644 --- a/sbin/dump/dump.h +++ b/sbin/dump/dump.h @@ -35,9 +35,6 @@ * $FreeBSD$ */ -#define MAXINOPB (MAXBSIZE / sizeof(struct dinode)) -#define MAXNINDIR (MAXBSIZE / sizeof(ufs_daddr_t)) - /* * Dump maps used to describe what is to be dumped. */ @@ -102,22 +99,23 @@ void timeest(void); time_t unctime(char *str); /* mapping rouintes */ -struct dinode; -long blockest(struct dinode *dp); +union dinode; +long blockest(union dinode *dp); int mapfiles(ino_t maxino, long *tapesize); int mapdirs(ino_t maxino, long *tapesize); /* file dumping routines */ -void blksout(ufs_daddr_t *blkp, int frags, ino_t ino); -void bread(ufs_daddr_t blkno, char *buf, int size); -void dumpino(struct dinode *dp, ino_t ino); +void ufs1_blksout(ufs1_daddr_t *blkp, int frags, ino_t ino); +void ufs2_blksout(ufs2_daddr_t *blkp, int frags, ino_t ino); +void bread(ufs2_daddr_t blkno, char *buf, int size); +void dumpino(union dinode *dp, ino_t ino); void dumpmap(char *map, int type, ino_t ino); void writeheader(ino_t ino); /* tape writing routines */ int alloctape(void); void close_rewind(void); -void dumpblock(ufs_daddr_t blkno, int size); +void dumpblock(ufs2_daddr_t blkno, int size); void startnewtape(int top); void trewind(void); void writerec(char *dp, int isspcl); @@ -127,7 +125,7 @@ void dumpabort(int signo); void getfstab(void); char *rawname(char *cp); -struct dinode *getino(ino_t inum); +union dinode *getino(ino_t inum, int *mode); /* rdump routines */ #ifdef RDUMP diff --git a/sbin/dump/itime.c b/sbin/dump/itime.c index b4c8f98..c875013 100644 --- a/sbin/dump/itime.c +++ b/sbin/dump/itime.c @@ -152,9 +152,9 @@ getdumptime(void) continue; if (ddp->dd_level >= level) continue; - if (ddp->dd_ddate <= _time32_to_time(spcl.c_ddate)) + if (ddp->dd_ddate <= _time64_to_time(spcl.c_ddate)) continue; - spcl.c_ddate = _time_to_time32(ddp->dd_ddate); + spcl.c_ddate = _time_to_time64(ddp->dd_ddate); lastlevel = ddp->dd_level; } } @@ -202,7 +202,7 @@ putdumptime(void) found: (void) strncpy(dtwalk->dd_name, fname, sizeof (dtwalk->dd_name)); dtwalk->dd_level = level; - dtwalk->dd_ddate = _time32_to_time(spcl.c_date); + dtwalk->dd_ddate = _time64_to_time(spcl.c_date); ITITERATE(i, dtwalk) { dumprecout(df, dtwalk); @@ -215,7 +215,7 @@ putdumptime(void) if (spcl.c_date == 0) { tmsg = "the epoch\n"; } else { - time_t t = _time32_to_time(spcl.c_date); + time_t t = _time64_to_time(spcl.c_date); tmsg = ctime(&t); } msg("level %c dump on %s", level, tmsg); diff --git a/sbin/dump/main.c b/sbin/dump/main.c index 860457b..270ea81 100644 --- a/sbin/dump/main.c +++ b/sbin/dump/main.c @@ -68,10 +68,6 @@ static const char rcsid[] = #include "dump.h" #include "pathnames.h" -#ifndef SBOFF -#define SBOFF (SBLOCK * DEV_BSIZE) -#endif - int notify = 0; /* notify operator flag */ int blockswritten = 0; /* number of blocks written on current tape */ int tapeno = 0; /* current tape number */ @@ -83,6 +79,11 @@ long dev_bsize = 1; /* recalculated below */ long blocksperfile; /* output blocks per file */ char *host = NULL; /* remote host (if any) */ +/* + * Possible superblock locations ordered from most to least likely. + */ +static int sblock_try[] = SBLOCKSEARCH; + static long numarg(const char *, long, long); static void obsolete(int *, char **[]); static void usage(void) __dead2; @@ -93,17 +94,17 @@ main(int argc, char *argv[]) struct stat sb; ino_t ino; int dirty; - struct dinode *dp; + union dinode *dp; struct fstab *dt; char *map; - int ch; + int ch, mode; int i, anydirskipped, bflag = 0, Tflag = 0, honorlevel = 1; int just_estimate = 0; ino_t maxino; char *tmsg; time_t t; - spcl.c_date = _time_to_time32(time(NULL)); + spcl.c_date = _time_to_time64(time(NULL)); tsize = 0; /* Default later, based on 'c' option for cart tapes */ if ((tape = getenv("TAPE")) == NULL) @@ -316,14 +317,14 @@ main(int argc, char *argv[]) if (spcl.c_date == 0) { tmsg = "the epoch\n"; } else { - time_t t = _time32_to_time(spcl.c_date); + time_t t = _time64_to_time(spcl.c_date); tmsg = ctime(&t); } msg("Date of this level %c dump: %s", level, tmsg); if (spcl.c_ddate == 0) { tmsg = "the epoch\n"; } else { - time_t t = _time32_to_time(spcl.c_ddate); + time_t t = _time64_to_time(spcl.c_ddate); tmsg = ctime(&t); } msg("Date of last level %c dump: %s", lastlevel, tmsg); @@ -343,9 +344,18 @@ main(int argc, char *argv[]) errx(X_STARTUP, "%s: unknown filesystem", disk); sync(); sblock = (struct fs *)sblock_buf; - bread(SBOFF, (char *) sblock, SBSIZE); - if (sblock->fs_magic != FS_MAGIC) - quit("bad sblock magic number\n"); + for (i = 0; sblock_try[i] != -1; i++) { + bread(sblock_try[i] >> dev_bshift, (char *) sblock, SBLOCKSIZE); + if ((sblock->fs_magic == FS_UFS1_MAGIC || + (sblock->fs_magic == FS_UFS2_MAGIC && + sblock->fs_sblockloc == + numfrags(sblock, sblock_try[i]))) && + sblock->fs_bsize <= MAXBSIZE && + sblock->fs_bsize >= sizeof(struct fs)) + break; + } + if (sblock_try[i] == -1) + quit("Cannot find filesystem superblock\n"); dev_bsize = sblock->fs_fsize / fsbtodb(sblock, 1); dev_bshift = ffs(dev_bsize) - 1; if (dev_bsize != (1 << dev_bshift)) @@ -353,10 +363,6 @@ main(int argc, char *argv[]) tp_bshift = ffs(TP_BSIZE) - 1; if (TP_BSIZE != (1 << tp_bshift)) quit("TP_BSIZE (%d) is not a power of 2", TP_BSIZE); -#ifdef FS_44INODEFMT - if (sblock->fs_inodefmt >= FS_44INODEFMT) - spcl.c_flags |= DR_NEWINODEFMT; -#endif maxino = sblock->fs_ipg * sblock->fs_ncg; mapsize = roundup(howmany(maxino, NBBY), TP_BSIZE); usedinomap = (char *)calloc((unsigned) mapsize, sizeof(char)); @@ -456,8 +462,8 @@ main(int argc, char *argv[]) /* * Skip directory inodes deleted and maybe reallocated */ - dp = getino(ino); - if ((dp->di_mode & IFMT) != IFDIR) + dp = getino(ino, &mode); + if (mode != IFDIR) continue; (void)dumpino(dp, ino); } @@ -466,8 +472,6 @@ main(int argc, char *argv[]) setproctitle("%s: pass 4: regular files", disk); msg("dumping (Pass IV) [regular files]\n"); for (map = dumpinomap, ino = 1; ino < maxino; ino++) { - int mode; - if (((ino - 1) % NBBY) == 0) /* map is offset by 1 */ dirty = *map++; else @@ -477,8 +481,7 @@ main(int argc, char *argv[]) /* * Skip inodes deleted and reallocated as directories. */ - dp = getino(ino); - mode = dp->di_mode & IFMT; + dp = getino(ino, &mode); if (mode == IFDIR) continue; (void)dumpino(dp, ino); @@ -489,9 +492,9 @@ main(int argc, char *argv[]) for (i = 0; i < ntrec; i++) writeheader(maxino - 1); if (pipeout) - msg("DUMP: %ld tape blocks\n", spcl.c_tapea); + msg("DUMP: %qd tape blocks\n", spcl.c_tapea); else - msg("DUMP: %ld tape blocks on %d volume%s\n", + msg("DUMP: %qd tape blocks on %d volume%s\n", spcl.c_tapea, spcl.c_volume, (spcl.c_volume == 1) ? "" : "s"); @@ -499,7 +502,7 @@ main(int argc, char *argv[]) if (tend_writing - tstart_writing == 0) msg("finished in less than a second\n"); else - msg("finished in %d seconds, throughput %d KBytes/sec\n", + msg("finished in %d seconds, throughput %qd KBytes/sec\n", tend_writing - tstart_writing, spcl.c_tapea / (tend_writing - tstart_writing)); diff --git a/sbin/dump/optr.c b/sbin/dump/optr.c index b0ff473..5fa1a02 100644 --- a/sbin/dump/optr.c +++ b/sbin/dump/optr.c @@ -44,6 +44,8 @@ static const char rcsid[] = #include <sys/wait.h> #include <sys/time.h> +#include <ufs/ufs/dinode.h> + #include <errno.h> #include <fstab.h> #include <grp.h> diff --git a/sbin/dump/tape.c b/sbin/dump/tape.c index 215d73b2..d13142e 100644 --- a/sbin/dump/tape.c +++ b/sbin/dump/tape.c @@ -62,7 +62,7 @@ static const char rcsid[] = #include "dump.h" int writesize; /* size of malloc()ed buffer for tape */ -long lastspclrec = -1; /* tape block number of last written header */ +int64_t lastspclrec = -1; /* tape block number of last written header */ int trecno = 0; /* next record to write in current block */ extern long blocksperfile; /* number of blocks per output file */ long blocksthisvol; /* number of blocks on current output file */ @@ -87,21 +87,21 @@ static void rollforward(void); * The following structure defines the instruction packets sent to slaves. */ struct req { - ufs_daddr_t dblk; + ufs2_daddr_t dblk; int count; }; int reqsiz; #define SLAVES 3 /* 1 slave writing, 1 reading, 1 for slack */ struct slave { - int tapea; /* header number at start of this chunk */ + int64_t tapea; /* header number at start of this chunk */ + int64_t firstrec; /* record number of this block */ int count; /* count to next header (used for TS_TAPE */ /* after EOT) */ int inode; /* inode that we are currently dealing with */ int fd; /* FD for this slave */ int pid; /* PID for this slave */ int sent; /* 1 == we've sent this slave requests */ - int firstrec; /* record number of this block */ char (*tblock)[TP_BSIZE]; /* buffer for data blocks */ struct req *req; /* buffer for requests */ } slaves[SLAVES+1]; @@ -161,7 +161,7 @@ void writerec(char *dp, int isspcl) { - slp->req[trecno].dblk = (ufs_daddr_t)0; + slp->req[trecno].dblk = (ufs2_daddr_t)0; slp->req[trecno].count = 1; /* Can't do a structure assignment due to alignment problems */ bcopy(dp, *(nextblock)++, sizeof (union u_spcl)); @@ -174,9 +174,10 @@ writerec(char *dp, int isspcl) } void -dumpblock(ufs_daddr_t blkno, int size) +dumpblock(ufs2_daddr_t blkno, int size) { - int avail, tpblks, dblkno; + int avail, tpblks; + ufs2_daddr_t dblkno; dblkno = fsbtodb(sblock, blkno); tpblks = size >> tp_bshift; @@ -226,7 +227,7 @@ static void flushtape(void) { int i, blks, got; - long lastfirstrec; + int64_t lastfirstrec; int siz = (char *)nextblock - (char *)slp->req; @@ -385,7 +386,8 @@ rollforward(void) { struct req *p, *q, *prev; struct slave *tslp; - int i, size, savedtapea, got; + int i, size, got; + int64_t savedtapea; union u_spcl *ntb, *otb; tslp = &slaves[SLAVES]; ntb = (union u_spcl *)tslp->tblock[1]; @@ -618,9 +620,7 @@ restore_check_point: spcl.c_firstrec = slp->firstrec; spcl.c_volume++; spcl.c_type = TS_TAPE; - spcl.c_flags |= DR_NEWHEADER; writeheader((ino_t)slp->inode); - spcl.c_flags &=~ DR_NEWHEADER; if (tapeno > 1) msg("Volume %d begins with blocks from inode %d\n", tapeno, slp->inode); diff --git a/sbin/dump/traverse.c b/sbin/dump/traverse.c index 622e32e..e5842b8 100644 --- a/sbin/dump/traverse.c +++ b/sbin/dump/traverse.c @@ -53,22 +53,25 @@ static const char rcsid[] = #include <errno.h> #include <string.h> #include <unistd.h> +#include <stdlib.h> #include "dump.h" +union dinode { + struct ufs1_dinode dp1; + struct ufs2_dinode dp2; +}; +#define DIP(dp, field) \ + ((sblock->fs_magic == FS_UFS1_MAGIC) ? \ + (dp)->dp1.field : (dp)->dp2.field) + #define HASDUMPEDFILE 0x1 #define HASSUBDIRS 0x2 -#ifdef FS_44INODEFMT -typedef quad_t fsizeT; -#else -typedef long fsizeT; -#endif - -static int dirindir(ino_t ino, ufs_daddr_t blkno, int level, long *size, +static int dirindir(ino_t ino, ufs2_daddr_t blkno, int level, long *size, long *tapesize, int nodump); -static void dmpindir(ino_t ino, ufs_daddr_t blk, int level, fsizeT *size); -static int searchdir(ino_t ino, ufs_daddr_t blkno, long size, long filesize, +static void dmpindir(ino_t ino, ufs2_daddr_t blk, int level, off_t *size); +static int searchdir(ino_t ino, ufs2_daddr_t blkno, long size, long filesize, long *tapesize, int nodump); /* @@ -79,7 +82,7 @@ static int searchdir(ino_t ino, ufs_daddr_t blkno, long size, long filesize, * hence the estimate may be high. */ long -blockest(struct dinode *dp) +blockest(union dinode *dp) { long blkest, sizeest; @@ -97,11 +100,11 @@ blockest(struct dinode *dp) * dump blocks (sizeest vs. blkest in the indirect block * calculation). */ - blkest = howmany(dbtob(dp->di_blocks), TP_BSIZE); - sizeest = howmany(dp->di_size, TP_BSIZE); + blkest = howmany(dbtob(DIP(dp, di_blocks)), TP_BSIZE); + sizeest = howmany(DIP(dp, di_size), TP_BSIZE); if (blkest > sizeest) blkest = sizeest; - if (dp->di_size > sblock->fs_bsize * NDADDR) { + if (DIP(dp, di_size) > sblock->fs_bsize * NDADDR) { /* calculate the number of indirect blocks on the dump tape */ blkest += howmany(sizeest - NDADDR * sblock->fs_bsize / TP_BSIZE, @@ -112,13 +115,13 @@ blockest(struct dinode *dp) /* Auxiliary macro to pick up files changed since previous dump. */ #define CHANGEDSINCE(dp, t) \ - ((dp)->di_mtime >= (t) || (dp)->di_ctime >= (t)) + (DIP(dp, di_mtime) >= (t) || DIP(dp, di_ctime) >= (t)) /* The WANTTODUMP macro decides whether a file should be dumped. */ #ifdef UF_NODUMP #define WANTTODUMP(dp) \ (CHANGEDSINCE(dp, spcl.c_ddate) && \ - (nonodump || ((dp)->di_flags & UF_NODUMP) != UF_NODUMP)) + (nonodump || (DIP(dp, di_flags) & UF_NODUMP) != UF_NODUMP)) #else #define WANTTODUMP(dp) CHANGEDSINCE(dp, spcl.c_ddate) #endif @@ -135,12 +138,12 @@ mapfiles(ino_t maxino, long *tapesize) { int mode; ino_t ino; - struct dinode *dp; + union dinode *dp; int anydirskipped = 0; for (ino = ROOTINO; ino < maxino; ino++) { - dp = getino(ino); - if ((mode = (dp->di_mode & IFMT)) == 0) + dp = getino(ino, &mode); + if (mode == 0) continue; /* * Everything must go in usedinomap so that a check @@ -160,7 +163,7 @@ mapfiles(ino_t maxino, long *tapesize) continue; } if (mode == IFDIR) { - if (!nonodump && (dp->di_flags & UF_NODUMP)) + if (!nonodump && (DIP(dp, di_flags) & UF_NODUMP)) CLRINO(ino, usedinomap); anydirskipped = 1; } @@ -188,11 +191,11 @@ mapfiles(ino_t maxino, long *tapesize) int mapdirs(ino_t maxino, long *tapesize) { - struct dinode *dp; + union dinode *dp; int i, isdir, nodump; char *map; ino_t ino; - struct dinode di; + union dinode di; long filesize; int ret, change = 0; @@ -212,23 +215,29 @@ mapdirs(ino_t maxino, long *tapesize) nodump = !nonodump && (TSTINO(ino, usedinomap) == 0); if ((isdir & 1) == 0 || (TSTINO(ino, dumpinomap) && !nodump)) continue; - dp = getino(ino); - di = *dp; /* inode buf may change in searchdir(). */ - filesize = di.di_size; + dp = getino(ino, &i); + /* + * inode buf may change in searchdir(). + */ + if (sblock->fs_magic == FS_UFS1_MAGIC) + di.dp1 = dp->dp1; + else + di.dp2 = dp->dp2; + filesize = DIP(&di, di_size); for (ret = 0, i = 0; filesize > 0 && i < NDADDR; i++) { - if (di.di_db[i] != 0) - ret |= searchdir(ino, di.di_db[i], - (long)dblksize(sblock, dp, i), - filesize, tapesize, nodump); + if (DIP(&di, di_db[i]) != 0) + ret |= searchdir(ino, DIP(&di, di_db[i]), + (long)sblksize(sblock, DIP(dp, di_size), i), + filesize, tapesize, nodump); if (ret & HASDUMPEDFILE) filesize = 0; else filesize -= sblock->fs_bsize; } for (i = 0; filesize > 0 && i < NIADDR; i++) { - if (di.di_ib[i] == 0) + if (DIP(&di, di_ib[i]) == 0) continue; - ret |= dirindir(ino, di.di_ib[i], i, &filesize, + ret |= dirindir(ino, DIP(&di, di_ib[i]), i, &filesize, tapesize, nodump); } if (ret & HASDUMPEDFILE) { @@ -256,17 +265,27 @@ mapdirs(ino_t maxino, long *tapesize) * require the directory to be dumped. */ static int -dirindir(ino_t ino, ufs_daddr_t blkno, int ind_level, long *filesize, - long *tapesize, int nodump) +dirindir( + ino_t ino, + ufs2_daddr_t blkno, + int ind_level, + long *filesize, + long *tapesize, + int nodump) { int ret = 0; int i; - ufs_daddr_t idblk[MAXNINDIR]; + static caddr_t idblk; - bread(fsbtodb(sblock, blkno), (char *)idblk, (int)sblock->fs_bsize); + if (idblk == NULL && (idblk = malloc(sblock->fs_bsize)) == NULL) + quit("dirindir: cannot allocate indirect memory.\n"); + bread(fsbtodb(sblock, blkno), idblk, (int)sblock->fs_bsize); if (ind_level <= 0) { for (i = 0; *filesize > 0 && i < NINDIR(sblock); i++) { - blkno = idblk[i]; + if (sblock->fs_magic == FS_UFS1_MAGIC) + blkno = ((ufs1_daddr_t *)idblk)[i]; + else + blkno = ((ufs2_daddr_t *)idblk)[i]; if (blkno != 0) ret |= searchdir(ino, blkno, sblock->fs_bsize, *filesize, tapesize, nodump); @@ -279,7 +298,10 @@ dirindir(ino_t ino, ufs_daddr_t blkno, int ind_level, long *filesize, } ind_level--; for (i = 0; *filesize > 0 && i < NINDIR(sblock); i++) { - blkno = idblk[i]; + if (sblock->fs_magic == FS_UFS1_MAGIC) + blkno = ((ufs1_daddr_t *)idblk)[i]; + else + blkno = ((ufs2_daddr_t *)idblk)[i]; if (blkno != 0) ret |= dirindir(ino, blkno, ind_level, filesize, tapesize, nodump); @@ -293,14 +315,22 @@ dirindir(ino_t ino, ufs_daddr_t blkno, int ind_level, long *filesize, * contains any subdirectories. */ static int -searchdir(ino_t ino, ufs_daddr_t blkno, long size, long filesize, - long *tapesize, int nodump) +searchdir( + ino_t ino, + ufs2_daddr_t blkno, + long size, + long filesize, + long *tapesize, + int nodump) { + int mode; struct direct *dp; - struct dinode *ip; + union dinode *ip; long loc, ret = 0; - char dblk[MAXBSIZE]; + static caddr_t dblk; + if (dblk == NULL && (dblk = malloc(sblock->fs_bsize)) == NULL) + quit("searchdir: cannot allocate indirect memory.\n"); bread(fsbtodb(sblock, blkno), dblk, (int)size); if (filesize < size) size = filesize; @@ -320,7 +350,7 @@ searchdir(ino_t ino, ufs_daddr_t blkno, long size, long filesize, continue; } if (nodump) { - ip = getino(dp->d_ino); + ip = getino(dp->d_ino, &mode); if (TSTINO(dp->d_ino, dumpinomap)) { CLRINO(dp->d_ino, dumpinomap); *tapesize -= blockest(ip); @@ -329,7 +359,7 @@ searchdir(ino_t ino, ufs_daddr_t blkno, long size, long filesize, * Add back to dumpdirmap and remove from usedinomap * to propagate nodump. */ - if ((ip->di_mode & IFMT) == IFDIR) { + if (mode == IFDIR) { SETINO(dp->d_ino, dumpdirmap); CLRINO(dp->d_ino, usedinomap); ret |= HASSUBDIRS; @@ -356,10 +386,12 @@ searchdir(ino_t ino, ufs_daddr_t blkno, long size, long filesize, * Dump the contents of an inode to tape. */ void -dumpino(struct dinode *dp, ino_t ino) +dumpino(union dinode *dp, ino_t ino) { + struct ufs1_dinode *dp1; + struct ufs2_dinode *dp2; int ind_level, cnt; - fsizeT size; + off_t size; char buf[TP_BSIZE]; if (newtape) { @@ -367,10 +399,36 @@ dumpino(struct dinode *dp, ino_t ino) dumpmap(dumpinomap, TS_BITS, ino); } CLRINO(ino, dumpinomap); - spcl.c_dinode = *dp; + if (sblock->fs_magic == FS_UFS1_MAGIC) { + spcl.c_mode = dp->dp1.di_mode; + spcl.c_size = dp->dp1.di_size; + spcl.c_atime = _time32_to_time(dp->dp1.di_atime); + spcl.c_atimensec = dp->dp1.di_atimensec; + spcl.c_mtime = _time32_to_time(dp->dp1.di_mtime); + spcl.c_mtimensec = dp->dp1.di_mtimensec; + spcl.c_createtime = 0; + spcl.c_createtimensec = 0; + spcl.c_rdev = dp->dp1.di_rdev; + spcl.c_file_flags = dp->dp1.di_flags; + spcl.c_uid = dp->dp1.di_uid; + spcl.c_gid = dp->dp1.di_gid; + } else { + spcl.c_mode = dp->dp2.di_mode; + spcl.c_size = dp->dp2.di_size; + spcl.c_atime = _time64_to_time(dp->dp2.di_atime); + spcl.c_atimensec = dp->dp2.di_atimensec; + spcl.c_mtime = _time64_to_time(dp->dp2.di_mtime); + spcl.c_mtimensec = dp->dp2.di_mtimensec; + spcl.c_createtime = _time64_to_time(dp->dp2.di_createtime); + spcl.c_createtimensec = dp->dp2.di_creatensec; + spcl.c_rdev = dp->dp2.di_rdev; + spcl.c_file_flags = dp->dp2.di_flags; + spcl.c_uid = dp->dp2.di_uid; + spcl.c_gid = dp->dp2.di_gid; + } spcl.c_type = TS_INODE; spcl.c_count = 0; - switch (dp->di_mode & S_IFMT) { + switch (DIP(dp, di_mode) & S_IFMT) { case 0: /* @@ -383,13 +441,18 @@ dumpino(struct dinode *dp, ino_t ino) * Check for short symbolic link. */ #ifdef FS_44INODEFMT - if (dp->di_size > 0 && - dp->di_size < sblock->fs_maxsymlinklen) { + if (DIP(dp, di_size) > 0 && + DIP(dp, di_size) < sblock->fs_maxsymlinklen) { spcl.c_addr[0] = 1; spcl.c_count = 1; writeheader(ino); - memmove(buf, dp->di_shortlink, (u_long)dp->di_size); - buf[dp->di_size] = '\0'; + if (sblock->fs_magic == FS_UFS1_MAGIC) + memmove(buf, (caddr_t)dp->dp1.di_db, + (u_long)DIP(dp, di_size)); + else + memmove(buf, (caddr_t)dp->dp2.di_db, + (u_long)DIP(dp, di_size)); + buf[DIP(dp, di_size)] = '\0'; writerec(buf, 0); return; } @@ -398,7 +461,7 @@ dumpino(struct dinode *dp, ino_t ino) case S_IFDIR: case S_IFREG: - if (dp->di_size > 0) + if (DIP(dp, di_size) > 0) break; /* fall through */ @@ -410,18 +473,22 @@ dumpino(struct dinode *dp, ino_t ino) return; default: - msg("Warning: undefined file type 0%o\n", dp->di_mode & IFMT); + msg("Warning: undefined file type 0%o\n", + DIP(dp, di_mode) & IFMT); return; } - if (dp->di_size > NDADDR * sblock->fs_bsize) + if (DIP(dp, di_size) > NDADDR * sblock->fs_bsize) cnt = NDADDR * sblock->fs_frag; else - cnt = howmany(dp->di_size, sblock->fs_fsize); - blksout(&dp->di_db[0], cnt, ino); - if ((size = dp->di_size - NDADDR * sblock->fs_bsize) <= 0) + cnt = howmany(DIP(dp, di_size), sblock->fs_fsize); + if (sblock->fs_magic == FS_UFS1_MAGIC) + ufs1_blksout(&dp->dp1.di_db[0], cnt, ino); + else + ufs2_blksout(&dp->dp2.di_db[0], cnt, ino); + if ((size = DIP(dp, di_size) - NDADDR * sblock->fs_bsize) <= 0) return; for (ind_level = 0; ind_level < NIADDR; ind_level++) { - dmpindir(ino, dp->di_ib[ind_level], ind_level, &size); + dmpindir(ino, DIP(dp, di_ib[ind_level]), ind_level, &size); if (size <= 0) return; } @@ -431,13 +498,15 @@ dumpino(struct dinode *dp, ino_t ino) * Read indirect blocks, and pass the data blocks to be dumped. */ static void -dmpindir(ino_t ino, ufs_daddr_t blk, int ind_level, fsizeT *size) +dmpindir(ino_t ino, ufs2_daddr_t blk, int ind_level, off_t *size) { int i, cnt; - ufs_daddr_t idblk[MAXNINDIR]; + static caddr_t idblk; + if (idblk == NULL && (idblk = malloc(sblock->fs_bsize)) == NULL) + quit("dmpindir: cannot allocate indirect memory.\n"); if (blk != 0) - bread(fsbtodb(sblock, blk), (char *)idblk, (int) sblock->fs_bsize); + bread(fsbtodb(sblock, blk), idblk, (int) sblock->fs_bsize); else memset(idblk, 0, (int)sblock->fs_bsize); if (ind_level <= 0) { @@ -446,12 +515,20 @@ dmpindir(ino_t ino, ufs_daddr_t blk, int ind_level, fsizeT *size) else cnt = NINDIR(sblock) * sblock->fs_frag; *size -= NINDIR(sblock) * sblock->fs_bsize; - blksout(&idblk[0], cnt, ino); + if (sblock->fs_magic == FS_UFS1_MAGIC) + ufs1_blksout((ufs1_daddr_t *)idblk, cnt, ino); + else + ufs2_blksout((ufs2_daddr_t *)idblk, cnt, ino); return; } ind_level--; for (i = 0; i < NINDIR(sblock); i++) { - dmpindir(ino, idblk[i], ind_level, size); + if (sblock->fs_magic == FS_UFS1_MAGIC) + dmpindir(ino, ((ufs1_daddr_t *)idblk)[i], ind_level, + size); + else + dmpindir(ino, ((ufs2_daddr_t *)idblk)[i], ind_level, + size); if (*size <= 0) return; } @@ -461,9 +538,44 @@ dmpindir(ino_t ino, ufs_daddr_t blk, int ind_level, fsizeT *size) * Collect up the data into tape record sized buffers and output them. */ void -blksout(ufs_daddr_t *blkp, int frags, ino_t ino) +ufs1_blksout(ufs1_daddr_t *blkp, int frags, ino_t ino) { - ufs_daddr_t *bp; + ufs1_daddr_t *bp; + int i, j, count, blks, tbperdb; + + blks = howmany(frags * sblock->fs_fsize, TP_BSIZE); + tbperdb = sblock->fs_bsize >> tp_bshift; + for (i = 0; i < blks; i += TP_NINDIR) { + if (i + TP_NINDIR > blks) + count = blks; + else + count = i + TP_NINDIR; + for (j = i; j < count; j++) + if (blkp[j / tbperdb] != 0) + spcl.c_addr[j - i] = 1; + else + spcl.c_addr[j - i] = 0; + spcl.c_count = count - i; + writeheader(ino); + bp = &blkp[i / tbperdb]; + for (j = i; j < count; j += tbperdb, bp++) + if (*bp != 0) { + if (j + tbperdb <= count) + dumpblock(*bp, (int)sblock->fs_bsize); + else + dumpblock(*bp, (count - j) * TP_BSIZE); + } + spcl.c_type = TS_ADDR; + } +} + +/* + * Collect up the data into tape record sized buffers and output them. + */ +void +ufs2_blksout(ufs2_daddr_t *blkp, int frags, ino_t ino) +{ + ufs2_daddr_t *bp; int i, j, count, blks, tbperdb; blks = howmany(frags * sblock->fs_fsize, TP_BSIZE); @@ -517,7 +629,7 @@ writeheader(ino_t ino) int32_t sum, cnt, *lp; spcl.c_inumber = ino; - spcl.c_magic = NFS_MAGIC; + spcl.c_magic = FS_UFS2_MAGIC; spcl.c_checksum = 0; lp = (int32_t *)&spcl; sum = 0; @@ -532,20 +644,32 @@ writeheader(ino_t ino) writerec((char *)&spcl, 1); } -struct dinode * -getino(ino_t inum) +union dinode * +getino(ino_t inum, int *modep) { - static ufs_daddr_t minino, maxino; - static struct dinode inoblock[MAXINOPB]; + static ino_t minino, maxino; + static caddr_t inoblock; + struct ufs1_dinode *dp1; + struct ufs2_dinode *dp2; + if (inoblock == NULL && (inoblock = malloc(sblock->fs_bsize)) == NULL) + quit("cannot allocate inode memory.\n"); curino = inum; if (inum >= minino && inum < maxino) - return (&inoblock[inum - minino]); - bread(fsbtodb(sblock, ino_to_fsba(sblock, inum)), (char *)inoblock, + goto gotit; + bread(fsbtodb(sblock, ino_to_fsba(sblock, inum)), inoblock, (int)sblock->fs_bsize); minino = inum - (inum % INOPB(sblock)); maxino = minino + INOPB(sblock); - return (&inoblock[inum - minino]); +gotit: + if (sblock->fs_magic == FS_UFS1_MAGIC) { + dp1 = &((struct ufs1_dinode *)inoblock)[inum - minino]; + *modep = (dp1->di_mode & IFMT); + return ((union dinode *)dp1); + } + dp2 = &((struct ufs2_dinode *)inoblock)[inum - minino]; + *modep = (dp2->di_mode & IFMT); + return ((union dinode *)dp2); } /* @@ -558,7 +682,7 @@ int breaderrors = 0; #define BREADEMAX 32 void -bread(ufs_daddr_t blkno, char *buf, int size) +bread(ufs2_daddr_t blkno, char *buf, int size) { int cnt, i; |