summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/restore/dirs.c10
-rw-r--r--sbin/restore/restore.h3
-rw-r--r--sbin/restore/tape.c11
3 files changed, 24 insertions, 0 deletions
diff --git a/sbin/restore/dirs.c b/sbin/restore/dirs.c
index ee37113..f0ed7f8 100644
--- a/sbin/restore/dirs.c
+++ b/sbin/restore/dirs.c
@@ -331,6 +331,16 @@ putdir(char *buf, long 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 == 0)
+ 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 ||
diff --git a/sbin/restore/restore.h b/sbin/restore/restore.h
index 05ca620..2221b20 100644
--- a/sbin/restore/restore.h
+++ b/sbin/restore/restore.h
@@ -60,6 +60,7 @@ 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 Bcvt; /* need byte swapping on inodes and dirs */
+extern int oldinofmt; /* reading tape with FreeBSD 1 format inodes */
/*
* Each file in the file system is described by one of these entries
@@ -146,3 +147,5 @@ typedef struct rstdirdesc RST_DIR;
#define GOOD 1
#define FAIL 0
+
+#define NFS_DR_NEWINODEFMT 0x2 /* Tape uses 4.4 BSD inode format */
diff --git a/sbin/restore/tape.c b/sbin/restore/tape.c
index 1c8907b..ea5d37f 100644
--- a/sbin/restore/tape.c
+++ b/sbin/restore/tape.c
@@ -87,6 +87,7 @@ static char lnkbuf[MAXPATHLEN + 1];
static int pathlen;
int Bcvt; /* Swap Bytes */
+int oldinofmt; /* FreeBSD 1 inode format needs cvt */
#define FLUSHTAPEBUF() blkcnt = ntrec + 1
@@ -1086,6 +1087,8 @@ gethead(struct s_spcl *buf)
case TS_TAPE:
if (buf->c_magic == NFS_MAGIC) {
+ if ((buf->c_flags & NFS_DR_NEWINODEFMT) == 0)
+ oldinofmt = 1;
buf->c_date = _time32_to_time(buf->c_old_date);
buf->c_ddate = _time32_to_time(buf->c_old_ddate);
buf->c_tapea = buf->c_old_tapea;
@@ -1117,6 +1120,14 @@ gethead(struct s_spcl *buf)
panic("gethead: unknown inode type %d\n", buf->c_type);
break;
}
+ /*
+ * If we're restoring a filesystem with the old (FreeBSD 1)
+ * format inodes, copy the uid/gid to the new location
+ */
+ if (oldinofmt) {
+ buf->c_uid = buf->c_spare1[1];
+ buf->c_gid = buf->c_spare1[2];
+ }
buf->c_magic = FS_UFS2_MAGIC;
tapeaddr = buf->c_tapea;
if (dflag)
OpenPOWER on IntegriCloud