summaryrefslogtreecommitdiffstats
path: root/sbin/restore
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2002-06-21 06:18:05 +0000
committermckusick <mckusick@FreeBSD.org>2002-06-21 06:18:05 +0000
commit88d85c15ef183c06524d6ca695f62c0c0672b00c (patch)
treef1364dbfb9835934a3879b5904f7ff9a1495744c /sbin/restore
parenteacb69b0197a8553d5004aa99532cabad8778e36 (diff)
downloadFreeBSD-src-88d85c15ef183c06524d6ca695f62c0c0672b00c.zip
FreeBSD-src-88d85c15ef183c06524d6ca695f62c0c0672b00c.tar.gz
This commit adds basic support for the UFS2 filesystem. The UFS2
filesystem expands the inode to 256 bytes to make space for 64-bit block pointers. It also adds a file-creation time field, an ability to use jumbo blocks per inode to allow extent like pointer density, and space for extended attributes (up to twice the filesystem block size worth of attributes, e.g., on a 16K filesystem, there is space for 32K of attributes). UFS2 fully supports and runs existing UFS1 filesystems. New filesystems built using newfs can be built in either UFS1 or UFS2 format using the -O option. In this commit UFS1 is the default format, so if you want to build UFS2 format filesystems, you must specify -O 2. This default will be changed to UFS2 when UFS2 proves itself to be stable. In this commit the boot code for reading UFS2 filesystems is not compiled (see /sys/boot/common/ufsread.c) as there is insufficient space in the boot block. Once the size of the boot block is increased, this code can be defined. Things to note: the definition of SBSIZE has changed to SBLOCKSIZE. The header file <ufs/ufs/dinode.h> must be included before <ufs/ffs/fs.h> so as to get the definitions of ufs2_daddr_t and ufs_lbn_t. Still TODO: Verify that the first level bootstraps work for all the architectures. Convert the utility ffsinfo to understand UFS2 and test growfs. Add support for the extended attribute storage. Update soft updates to ensure integrity of extended attribute storage. Switch the current extended attribute interfaces to use the extended attribute storage. Add the extent like functionality (framework is there, but is currently never used). Sponsored by: DARPA & NAI Labs. Reviewed by: Poul-Henning Kamp <phk@freebsd.org>
Diffstat (limited to 'sbin/restore')
-rw-r--r--sbin/restore/dirs.c114
-rw-r--r--sbin/restore/main.c7
-rw-r--r--sbin/restore/restore.c4
-rw-r--r--sbin/restore/restore.h17
-rw-r--r--sbin/restore/tape.c277
5 files changed, 179 insertions, 240 deletions
diff --git a/sbin/restore/dirs.c b/sbin/restore/dirs.c
index 32da860..323e9ff 100644
--- a/sbin/restore/dirs.c
+++ b/sbin/restore/dirs.c
@@ -120,7 +120,7 @@ struct odirect {
char d_name[ODIRSIZ];
};
-static struct inotab *allocinotab(ino_t, struct dinode *, long);
+static struct inotab *allocinotab(struct context *, long);
static void dcvt(struct odirect *, struct direct *);
static void flushent(void);
static struct inotab *inotablookup(ino_t);
@@ -140,11 +140,9 @@ static struct direct *searchdir(ino_t, char *);
void
extractdirs(int genmode)
{
- int i;
- struct dinode *ip;
struct inotab *itp;
struct direct nulldir;
- int fd;
+ int i, fd;
const char *tmpdir;
vprintf(stdout, "Extract directories from tape\n");
@@ -184,8 +182,7 @@ extractdirs(int genmode)
for (;;) {
curfile.name = "<directory file - name unknown>";
curfile.action = USING;
- ip = curfile.dip;
- if (ip == NULL || (ip->di_mode & IFMT) != IFDIR) {
+ if (curfile.mode == 0 || (curfile.mode & IFMT) != IFDIR) {
(void) fclose(df);
dirp = opendirfile(dirfile);
if (dirp == NULL)
@@ -198,7 +195,7 @@ extractdirs(int genmode)
panic("Root directory is not on tape\n");
return;
}
- itp = allocinotab(curfile.ino, ip, seekpt);
+ itp = allocinotab(&curfile, seekpt);
getfile(putdir, xtrnull);
putent(&nulldir);
flushent();
@@ -213,7 +210,7 @@ void
skipdirs(void)
{
- while (curfile.dip && (curfile.dip->di_mode & IFMT) == IFDIR) {
+ while (curfile.ino && (curfile.mode & IFMT) == IFDIR) {
skipfile();
}
}
@@ -343,53 +340,34 @@ putdir(char *buf, long size)
struct direct *dp;
long loc, i;
- if (cvtflag) {
- eodp = (struct odirect *)&buf[size];
- for (odp = (struct odirect *)buf; odp < eodp; odp++)
- if (odp->d_ino != 0) {
- dcvt(odp, &cvtbuf);
- putent(&cvtbuf);
- }
- } else {
- for (loc = 0; loc < size; ) {
- dp = (struct direct *)(buf + loc);
- if (Bcvt)
- swabst((u_char *)"ls", (u_char *) dp);
- if (oldinofmt && dp->d_ino != 0) {
-# if BYTE_ORDER == BIG_ENDIAN
- if (Bcvt)
- dp->d_namlen = dp->d_type;
-# else
- if (!Bcvt)
- dp->d_namlen = dp->d_type;
-# endif
- dp->d_type = DT_UNKNOWN;
- }
- i = DIRBLKSIZ - (loc & (DIRBLKSIZ - 1));
- if ((dp->d_reclen & 0x3) != 0 ||
- dp->d_reclen > i ||
- dp->d_reclen < DIRSIZ(0, dp) ||
- dp->d_namlen > NAME_MAX) {
- vprintf(stdout, "Mangled directory: ");
- if ((dp->d_reclen & 0x3) != 0)
- vprintf(stdout,
- "reclen not multiple of 4 ");
- if (dp->d_reclen < DIRSIZ(0, dp))
- vprintf(stdout,
- "reclen less than DIRSIZ (%d < %d) ",
- dp->d_reclen, DIRSIZ(0, dp));
- if (dp->d_namlen > NAME_MAX)
- vprintf(stdout,
- "reclen name too big (%d > %d) ",
- dp->d_namlen, NAME_MAX);
- vprintf(stdout, "\n");
- loc += i;
- continue;
- }
- loc += dp->d_reclen;
- if (dp->d_ino != 0) {
- putent(dp);
- }
+ for (loc = 0; loc < size; ) {
+ dp = (struct direct *)(buf + loc);
+ if (Bcvt)
+ swabst((u_char *)"ls", (u_char *) dp);
+ i = DIRBLKSIZ - (loc & (DIRBLKSIZ - 1));
+ if ((dp->d_reclen & 0x3) != 0 ||
+ dp->d_reclen > i ||
+ dp->d_reclen < DIRSIZ(0, dp) ||
+ dp->d_namlen > NAME_MAX) {
+ vprintf(stdout, "Mangled directory: ");
+ if ((dp->d_reclen & 0x3) != 0)
+ vprintf(stdout,
+ "reclen not multiple of 4 ");
+ if (dp->d_reclen < DIRSIZ(0, dp))
+ vprintf(stdout,
+ "reclen less than DIRSIZ (%d < %d) ",
+ dp->d_reclen, DIRSIZ(0, dp));
+ if (dp->d_namlen > NAME_MAX)
+ vprintf(stdout,
+ "reclen name too big (%d > %d) ",
+ dp->d_namlen, NAME_MAX);
+ vprintf(stdout, "\n");
+ loc += i;
+ continue;
+ }
+ loc += dp->d_reclen;
+ if (dp->d_ino != 0) {
+ putent(dp);
}
}
}
@@ -692,7 +670,7 @@ inodetype(ino_t ino)
* If requested, save its pertinent mode, owner, and time info.
*/
static struct inotab *
-allocinotab(ino_t ino, struct dinode *dip, long seekpt)
+allocinotab(struct context *ctxp, long seekpt)
{
struct inotab *itp;
struct modeinfo node;
@@ -700,21 +678,21 @@ allocinotab(ino_t ino, struct dinode *dip, long seekpt)
itp = calloc(1, sizeof(struct inotab));
if (itp == NULL)
panic("no memory directory table\n");
- itp->t_next = inotab[INOHASH(ino)];
- inotab[INOHASH(ino)] = itp;
- itp->t_ino = ino;
+ itp->t_next = inotab[INOHASH(ctxp->ino)];
+ inotab[INOHASH(ctxp->ino)] = itp;
+ itp->t_ino = ctxp->ino;
itp->t_seekpt = seekpt;
if (mf == NULL)
return (itp);
- node.ino = ino;
- node.timep[0].tv_sec = dip->di_atime;
- node.timep[0].tv_usec = dip->di_atimensec / 1000;
- node.timep[1].tv_sec = dip->di_mtime;
- node.timep[1].tv_usec = dip->di_mtimensec / 1000;
- node.mode = dip->di_mode;
- node.flags = dip->di_flags;
- node.uid = dip->di_uid;
- node.gid = dip->di_gid;
+ node.ino = ctxp->ino;
+ node.timep[0].tv_sec = ctxp->atime_sec;
+ node.timep[0].tv_usec = ctxp->atime_nsec / 1000;
+ node.timep[1].tv_sec = ctxp->mtime_sec;
+ node.timep[1].tv_usec = ctxp->mtime_nsec / 1000;
+ node.mode = ctxp->mode;
+ node.flags = ctxp->file_flags;
+ node.uid = ctxp->uid;
+ node.gid = ctxp->gid;
(void) fwrite((char *)&node, 1, sizeof(struct modeinfo), mf);
return (itp);
}
diff --git a/sbin/restore/main.c b/sbin/restore/main.c
index 0c7b363..ef3df7a 100644
--- a/sbin/restore/main.c
+++ b/sbin/restore/main.c
@@ -98,9 +98,9 @@ main(int argc, char *argv[])
inputdev = _PATH_DEFTAPE;
obsolete(&argc, &argv);
#ifdef KERBEROS
-#define optlist "b:cdf:hikmNRrs:tuvxy"
+#define optlist "b:df:hikmNRrs:tuvxy"
#else
-#define optlist "b:cdf:himNRrs:tuvxy"
+#define optlist "b:df:himNRrs:tuvxy"
#endif
while ((ch = getopt(argc, argv, optlist)) != -1)
switch(ch) {
@@ -113,9 +113,6 @@ main(int argc, char *argv[])
if (ntrec <= 0)
errx(1, "block size must be greater than 0");
break;
- case 'c':
- cvtflag = 1;
- break;
case 'd':
dflag = 1;
break;
diff --git a/sbin/restore/restore.c b/sbin/restore/restore.c
index 46e208b..0a3647d 100644
--- a/sbin/restore/restore.c
+++ b/sbin/restore/restore.c
@@ -41,11 +41,11 @@ static const char rcsid[] =
#include <sys/types.h>
-#include <ufs/ufs/dinode.h>
-
#include <stdio.h>
#include <string.h>
+#include <ufs/ufs/dinode.h>
+
#include "restore.h"
#include "extern.h"
diff --git a/sbin/restore/restore.h b/sbin/restore/restore.h
index 1e71330..cb10d81 100644
--- a/sbin/restore/restore.h
+++ b/sbin/restore/restore.h
@@ -42,7 +42,6 @@
/*
* Flags
*/
-extern int cvtflag; /* convert from old to new tape format */
extern int bflag; /* set input block size */
extern int dflag; /* print out debugging info */
extern int hflag; /* restore heirarchies */
@@ -64,7 +63,6 @@ extern time_t dumptime; /* time that this dump begins */
extern time_t dumpdate; /* time that this dump was made */
extern char command; /* opration being performed */
extern FILE *terminal; /* file descriptor for the terminal input */
-extern int oldinofmt; /* reading tape with old format inodes */
extern int Bcvt; /* need byte swapping on inodes and dirs */
/*
@@ -106,10 +104,19 @@ struct entry {
* The entry describes the next file available on the tape
*/
struct context {
- char *name; /* name of file */
+ short action; /* action being taken on this file */
+ mode_t mode; /* mode of file */
ino_t ino; /* inumber of file */
- struct dinode *dip; /* pointer to inode */
- char action; /* action being taken on this file */
+ uid_t uid; /* file owner */
+ gid_t gid; /* file group */
+ int file_flags; /* status flags (chflags) */
+ int rdev; /* device number of file */
+ time_t atime_sec; /* access time seconds */
+ time_t mtime_sec; /* modified time seconds */
+ int atime_nsec; /* access time nanoseconds */
+ int mtime_nsec; /* modified time nanoseconds */
+ off_t size; /* size of file */
+ char *name; /* name of file */
} curfile;
/* actions */
#define USING 1 /* extracting from the tape */
diff --git a/sbin/restore/tape.c b/sbin/restore/tape.c
index c40c7a9..2b2ab91 100644
--- a/sbin/restore/tape.c
+++ b/sbin/restore/tape.c
@@ -74,20 +74,19 @@ static int numtrec;
static char *tapebuf;
static union u_spcl endoftapemark;
static long blksread; /* blocks read since last header */
-static long tapeaddr = 0; /* current TP_BSIZE tape record */
+static int64_t tapeaddr = 0; /* current TP_BSIZE tape record */
static long tapesread;
static jmp_buf restart;
static int gettingfile = 0; /* restart has a valid frame */
static char *host = NULL;
+static int readmapflag;
static int ofile;
static char *map;
static char lnkbuf[MAXPATHLEN + 1];
static int pathlen;
-int oldinofmt; /* old inode format conversion required */
-int Bcvt; /* Swap Bytes (for CCI or sun) */
-static int Qcvt; /* Swap quads (for sun) */
+int Bcvt; /* Swap Bytes */
#define FLUSHTAPEBUF() blkcnt = ntrec + 1
@@ -109,8 +108,6 @@ static void xtrmap(char *, long);
static void xtrmapskip(char *, long);
static void xtrskip(char *, long);
-static int readmapflag;
-
/*
* Set up an input source
*/
@@ -207,17 +204,11 @@ setup(void)
if (!pipein && !bflag)
findtapeblksize();
if (gethead(&spcl) == FAIL) {
- blkcnt--; /* push back this block */
- blksread--;
- cvtflag++;
- if (gethead(&spcl) == FAIL) {
- fprintf(stderr, "Tape is not a dump tape\n");
- done(1);
- }
- fprintf(stderr, "Converting to new filesystem format.\n");
+ fprintf(stderr, "Tape is not a dump tape\n");
+ done(1);
}
if (pipein) {
- endoftapemark.s_spcl.c_magic = cvtflag ? OFS_MAGIC : NFS_MAGIC;
+ endoftapemark.s_spcl.c_magic = FS_UFS2_MAGIC;
endoftapemark.s_spcl.c_type = TS_END;
ip = (int *)&endoftapemark;
j = sizeof(union u_spcl) / sizeof(int);
@@ -229,8 +220,8 @@ setup(void)
}
if (vflag || command == 't')
printdumpinfo();
- dumptime = _time32_to_time(spcl.c_ddate);
- dumpdate = _time32_to_time(spcl.c_date);
+ dumptime = _time64_to_time(spcl.c_ddate);
+ dumpdate = _time64_to_time(spcl.c_date);
if (stat(".", &stbuf) < 0) {
fprintf(stderr, "cannot stat .: %s\n", strerror(errno));
done(1);
@@ -279,8 +270,7 @@ setup(void)
* whiteout inode exists, so that the whiteout entries can be
* extracted.
*/
- if (oldinofmt == 0)
- SETINO(WINO, dumpmap);
+ SETINO(WINO, dumpmap);
/* 'r' restores don't call getvol() for tape 1, so mark it as read. */
if (command == 'r')
tapesread = 1;
@@ -296,7 +286,8 @@ setup(void)
void
getvol(long nextvol)
{
- long newvol, prevtapea, savecnt, i;
+ int64_t prevtapea;
+ long i, newvol, savecnt;
union u_spcl tmpspcl;
# define tmpbuf tmpspcl.s_spcl
char buf[TP_BSIZE];
@@ -403,9 +394,9 @@ gethdr:
volno = 0;
goto again;
}
- if (_time32_to_time(tmpbuf.c_date) != dumpdate ||
- _time32_to_time(tmpbuf.c_ddate) != dumptime) {
- time_t t = _time32_to_time(tmpbuf.c_date);
+ if (_time64_to_time(tmpbuf.c_date) != dumpdate ||
+ _time64_to_time(tmpbuf.c_ddate) != dumptime) {
+ time_t t = _time64_to_time(tmpbuf.c_date);
fprintf(stderr, "Wrong dump date\n\tgot: %s", ctime(&t));
fprintf(stderr, "\twanted: %s", ctime(&dumpdate));
volno = 0;
@@ -420,9 +411,9 @@ gethdr:
* If coming to this volume at random, skip to the beginning
* of the next record.
*/
- dprintf(stdout, "last rec %ld, tape starts with %ld\n", prevtapea,
+ dprintf(stdout, "last rec %qd, tape starts with %qd\n", prevtapea,
tmpbuf.c_tapea);
- if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) {
+ if (tmpbuf.c_type == TS_TAPE) {
if (curfile.action != USING) {
/*
* XXX Dump incorrectly sets c_count to 1 in the
@@ -475,7 +466,7 @@ terminateinput(void)
}
curfile.name = "<name unknown>";
curfile.action = UNKNOWN;
- curfile.dip = NULL;
+ curfile.mode = 0;
curfile.ino = maxino;
if (gettingfile) {
gettingfile = 0;
@@ -513,9 +504,9 @@ void
printdumpinfo(void)
{
time_t t;
- t = _time32_to_time(spcl.c_date);
+ t = _time64_to_time(spcl.c_date);
fprintf(stdout, "Dump date: %s", ctime(&t));
- t = _time32_to_time(spcl.c_ddate);
+ t = _time64_to_time(spcl.c_ddate);
fprintf(stdout, "Dumped from: %s",
(spcl.c_ddate == 0) ? "the epoch\n" : ctime(&t));
if (spcl.c_host[0] == '\0')
@@ -529,22 +520,18 @@ int
extractfile(char *name)
{
int flags;
- uid_t uid;
- gid_t gid;
mode_t mode;
struct timeval timep[2];
struct entry *ep;
curfile.name = name;
curfile.action = USING;
- timep[0].tv_sec = curfile.dip->di_atime;
- timep[0].tv_usec = curfile.dip->di_atimensec / 1000;
- timep[1].tv_sec = curfile.dip->di_mtime;
- timep[1].tv_usec = curfile.dip->di_mtimensec / 1000;
- uid = curfile.dip->di_uid;
- gid = curfile.dip->di_gid;
- mode = curfile.dip->di_mode;
- flags = curfile.dip->di_flags;
+ timep[0].tv_sec = curfile.atime_sec;
+ timep[0].tv_usec = curfile.atime_nsec / 1000;
+ timep[1].tv_sec = curfile.mtime_sec;
+ timep[1].tv_usec = curfile.mtime_nsec / 1000;
+ mode = curfile.mode;
+ flags = curfile.file_flags;
switch (mode & IFMT) {
default:
@@ -578,7 +565,7 @@ extractfile(char *name)
return (GOOD);
}
if (linkit(lnkbuf, name, SYMLINK) == GOOD) {
- (void) lchown(name, uid, gid);
+ (void) lchown(name, curfile.uid, curfile.gid);
(void) lchmod(name, mode);
(void) lutimes(name, timep);
return (GOOD);
@@ -599,7 +586,7 @@ extractfile(char *name)
skipfile();
return (FAIL);
}
- (void) chown(name, uid, gid);
+ (void) chown(name, curfile.uid, curfile.gid);
(void) chmod(name, mode);
(void) utimes(name, timep);
(void) chflags(name, flags);
@@ -615,13 +602,13 @@ extractfile(char *name)
}
if (uflag)
(void)unlink(name);
- if (mknod(name, mode, (int)curfile.dip->di_rdev) < 0) {
+ if (mknod(name, mode, (int)curfile.rdev) < 0) {
fprintf(stderr, "%s: cannot create special file: %s\n",
name, strerror(errno));
skipfile();
return (FAIL);
}
- (void) chown(name, uid, gid);
+ (void) chown(name, curfile.uid, curfile.gid);
(void) chmod(name, mode);
(void) utimes(name, timep);
(void) chflags(name, flags);
@@ -643,7 +630,7 @@ extractfile(char *name)
skipfile();
return (FAIL);
}
- (void) fchown(ofile, uid, gid);
+ (void) fchown(ofile, curfile.uid, curfile.gid);
(void) fchmod(ofile, mode);
getfile(xtrfile, xtrskip);
(void) close(ofile);
@@ -687,14 +674,14 @@ getfile(void (*fill)(char *, long), void (*skip)(char *, long))
{
int i;
int curblk = 0;
- quad_t size = spcl.c_dinode.di_size;
+ quad_t size = spcl.c_size;
static char clearedbuf[MAXBSIZE];
char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE];
char junk[TP_BSIZE];
if (spcl.c_type == TS_END)
panic("ran off end of tape\n");
- if (spcl.c_magic != NFS_MAGIC)
+ if (spcl.c_magic != FS_UFS2_MAGIC)
panic("not at beginning of a file\n");
if (!gettingfile && setjmp(restart) != 0)
return;
@@ -1000,106 +987,43 @@ closemt(void)
/*
* Read the next block from the tape.
- * Check to see if it is one of several vintage headers.
- * If it is an old style header, convert it to a new style header.
* If it is not any valid header, return an error.
*/
static int
gethead(struct s_spcl *buf)
{
long i;
- union {
- quad_t qval;
- int32_t val[2];
- } qcvt;
- union u_ospcl {
- char dummy[TP_BSIZE];
- struct s_ospcl {
- int32_t c_type;
- int32_t c_date;
- int32_t c_ddate;
- int32_t c_volume;
- int32_t c_tapea;
- u_short c_inumber;
- int32_t c_magic;
- int32_t c_checksum;
- struct odinode {
- unsigned short odi_mode;
- u_short odi_nlink;
- u_short odi_uid;
- u_short odi_gid;
- int32_t odi_size;
- int32_t odi_rdev;
- char odi_addr[36];
- int32_t odi_atime;
- int32_t odi_mtime;
- int32_t odi_ctime;
- } c_dinode;
- int32_t c_count;
- char c_addr[256];
- } s_ospcl;
- } u_ospcl;
-
- if (!cvtflag) {
- readtape((char *)buf);
- if (buf->c_magic != NFS_MAGIC) {
- if (swabl(buf->c_magic) != NFS_MAGIC)
- return (FAIL);
- if (!Bcvt) {
- vprintf(stdout, "Note: Doing Byte swapping\n");
- Bcvt = 1;
- }
+
+ readtape((char *)buf);
+ if (buf->c_magic != FS_UFS2_MAGIC && buf->c_magic != NFS_MAGIC) {
+ if (buf->c_magic == OFS_MAGIC) {
+ fprintf(stderr,
+ "Format of dump tape is too old. Must use\n");
+ fprintf(stderr,
+ "a version of restore from before 2002.\n");
+ return (FAIL);
}
- if (checksum((int *)buf) == FAIL)
+ if (swabl(buf->c_magic) != FS_UFS2_MAGIC &&
+ buf->c_magic != NFS_MAGIC) {
+ if (buf->c_magic == OFS_MAGIC) {
+ fprintf(stderr,
+ "Format of dump tape is too old. Must use\n");
+ fprintf(stderr,
+ "a version of restore from before 2002.\n");
+ }
return (FAIL);
- if (Bcvt) {
- swabst((u_char *)"8l4s31l", (u_char *)buf);
- swabst((u_char *)"l",(u_char *) &buf->c_level);
- swabst((u_char *)"2l",(u_char *) &buf->c_flags);
}
- goto good;
- }
- readtape((char *)(&u_ospcl.s_ospcl));
- memset(buf, 0, (long)TP_BSIZE);
- buf->c_type = u_ospcl.s_ospcl.c_type;
- buf->c_date = u_ospcl.s_ospcl.c_date;
- buf->c_ddate = u_ospcl.s_ospcl.c_ddate;
- buf->c_volume = u_ospcl.s_ospcl.c_volume;
- buf->c_tapea = u_ospcl.s_ospcl.c_tapea;
- buf->c_inumber = u_ospcl.s_ospcl.c_inumber;
- buf->c_checksum = u_ospcl.s_ospcl.c_checksum;
- buf->c_magic = u_ospcl.s_ospcl.c_magic;
- buf->c_dinode.di_mode = u_ospcl.s_ospcl.c_dinode.odi_mode;
- buf->c_dinode.di_nlink = u_ospcl.s_ospcl.c_dinode.odi_nlink;
- buf->c_dinode.di_uid = u_ospcl.s_ospcl.c_dinode.odi_uid;
- buf->c_dinode.di_gid = u_ospcl.s_ospcl.c_dinode.odi_gid;
- buf->c_dinode.di_size = u_ospcl.s_ospcl.c_dinode.odi_size;
- buf->c_dinode.di_rdev = u_ospcl.s_ospcl.c_dinode.odi_rdev;
- buf->c_dinode.di_atime = u_ospcl.s_ospcl.c_dinode.odi_atime;
- buf->c_dinode.di_mtime = u_ospcl.s_ospcl.c_dinode.odi_mtime;
- buf->c_dinode.di_ctime = u_ospcl.s_ospcl.c_dinode.odi_ctime;
- buf->c_count = u_ospcl.s_ospcl.c_count;
- memmove(buf->c_addr, u_ospcl.s_ospcl.c_addr, (long)256);
- if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC ||
- checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
- return(FAIL);
- buf->c_magic = NFS_MAGIC;
-
-good:
- if ((buf->c_dinode.di_size == 0 || buf->c_dinode.di_size > 0xfffffff) &&
- (buf->c_dinode.di_mode & IFMT) == IFDIR && Qcvt == 0) {
- qcvt.qval = buf->c_dinode.di_size;
- if (qcvt.val[0] || qcvt.val[1]) {
- printf("Note: Doing Quad swapping\n");
- Qcvt = 1;
+ if (!Bcvt) {
+ vprintf(stdout, "Note: Doing Byte swapping\n");
+ Bcvt = 1;
}
}
- if (Qcvt) {
- qcvt.qval = buf->c_dinode.di_size;
- i = qcvt.val[1];
- qcvt.val[1] = qcvt.val[0];
- qcvt.val[0] = i;
- buf->c_dinode.di_size = qcvt.qval;
+ if (checksum((int *)buf) == FAIL)
+ return (FAIL);
+ if (Bcvt) {
+ swabst((u_char *)"8l4s1q8l2q17l", (u_char *)buf);
+ swabst((u_char *)"l",(u_char *) &buf->c_level);
+ swabst((u_char *)"2l4q",(u_char *) &buf->c_flags);
}
readmapflag = 0;
@@ -1111,7 +1035,7 @@ good:
* Have to patch up missing information in bit map headers
*/
buf->c_inumber = 0;
- buf->c_dinode.di_size = buf->c_count * TP_BSIZE;
+ buf->c_size = buf->c_count * TP_BSIZE;
if (buf->c_count > TP_NINDIR)
readmapflag = 1;
else
@@ -1120,14 +1044,25 @@ good:
break;
case TS_TAPE:
- if ((buf->c_flags & DR_NEWINODEFMT) == 0)
- oldinofmt = 1;
- /* fall through */
case TS_END:
buf->c_inumber = 0;
break;
case TS_INODE:
+ /*
+ * For old dump tapes, have to copy up old fields to
+ * new locations.
+ */
+ if (buf->c_magic == NFS_MAGIC) {
+ buf->c_tapea = buf->c_old_tapea;
+ buf->c_firstrec = buf->c_old_firstrec;
+ buf->c_date = _time32_to_time(buf->c_old_date);
+ buf->c_ddate = _time32_to_time(buf->c_old_ddate);
+ buf->c_atime = _time32_to_time(buf->c_old_atime);
+ buf->c_mtime = _time32_to_time(buf->c_old_mtime);
+ }
+ break;
+
case TS_ADDR:
break;
@@ -1135,14 +1070,7 @@ good:
panic("gethead: unknown inode type %d\n", buf->c_type);
break;
}
- /*
- * If we are restoring a filesystem with old format inodes,
- * copy the uid/gid to the new location.
- */
- if (oldinofmt) {
- buf->c_dinode.di_uid = buf->c_dinode.di_ouid;
- buf->c_dinode.di_gid = buf->c_dinode.di_ogid;
- }
+ buf->c_magic = FS_UFS2_MAGIC;
tapeaddr = buf->c_tapea;
if (dflag)
accthdr(buf);
@@ -1161,10 +1089,9 @@ accthdr(struct s_spcl *header)
long blks, i;
if (header->c_type == TS_TAPE) {
- fprintf(stderr, "Volume header (%s inode format) ",
- oldinofmt ? "old" : "new");
+ fprintf(stderr, "Volume header ");
if (header->c_firstrec)
- fprintf(stderr, "begins with record %ld",
+ fprintf(stderr, "begins with record %qd",
header->c_firstrec);
fprintf(stderr, "\n");
previno = 0x7fffffff;
@@ -1219,15 +1146,9 @@ findinode(struct s_spcl *header)
curfile.name = "<name unknown>";
curfile.action = UNKNOWN;
- curfile.dip = NULL;
+ curfile.mode = 0;
curfile.ino = 0;
do {
- if (header->c_magic != NFS_MAGIC) {
- skipcnt++;
- while (gethead(header) == FAIL ||
- _time32_to_time(header->c_date) != dumpdate)
- skipcnt++;
- }
htype = header->c_type;
switch (htype) {
@@ -1239,12 +1160,21 @@ findinode(struct s_spcl *header)
if (header->c_addr[i])
readtape(buf);
while (gethead(header) == FAIL ||
- _time32_to_time(header->c_date) != dumpdate)
+ _time64_to_time(header->c_date) != dumpdate)
skipcnt++;
break;
case TS_INODE:
- curfile.dip = &header->c_dinode;
+ curfile.mode = header->c_mode;
+ curfile.uid = header->c_uid;
+ curfile.gid = header->c_gid;
+ curfile.file_flags = header->c_file_flags;
+ curfile.rdev = header->c_rdev;
+ curfile.atime_sec = header->c_atime;
+ curfile.atime_nsec = header->c_atimensec;
+ curfile.mtime_sec = header->c_mtime;
+ curfile.mtime_nsec = header->c_mtimensec;
+ curfile.size = header->c_size;
curfile.ino = header->c_inumber;
break;
@@ -1288,7 +1218,7 @@ checksum(int *buf)
j = sizeof(union u_spcl) / sizeof(int);
i = 0;
- if(!Bcvt) {
+ if (!Bcvt) {
do
i += *buf++;
while (--j);
@@ -1346,6 +1276,21 @@ swablong(u_char *sp, int n)
return (sp);
}
+static u_char *
+swabquad(u_char *sp, int n)
+{
+ char c;
+
+ while (--n >= 0) {
+ c = sp[0]; sp[0] = sp[7]; sp[7] = c;
+ c = sp[1]; sp[1] = sp[6]; sp[6] = c;
+ c = sp[2]; sp[2] = sp[5]; sp[5] = c;
+ c = sp[3]; sp[3] = sp[4]; sp[4] = c;
+ sp += 8;
+ }
+ return (sp);
+}
+
void
swabst(u_char *cp, u_char *sp)
{
@@ -1370,11 +1315,23 @@ swabst(u_char *cp, u_char *sp)
sp = swablong(sp, n);
break;
- default: /* Any other character, like 'b' counts as byte. */
+ case 'q':
+ if (n == 0)
+ n = 1;
+ sp = swabquad(sp, n);
+ break;
+
+ case 'b':
if (n == 0)
n = 1;
sp += n;
break;
+
+ default:
+ fprintf(stderr, "Unknown conversion character: %c\n",
+ *cp);
+ done(0);
+ break;
}
cp++;
n = 0;
OpenPOWER on IntegriCloud