diff options
-rw-r--r-- | sbin/restore/dirs.c | 10 | ||||
-rw-r--r-- | sbin/restore/restore.h | 3 | ||||
-rw-r--r-- | sbin/restore/tape.c | 11 |
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) |