Unix Technical Forum

Re: ffs2 support for dump/restore

This is a discussion on Re: ffs2 support for dump/restore within the mailing.openbsd.tech forums, part of the OpenBSD category; --> so spake "Todd C. Miller" (millert): > I've merged ffs2 support for dump/restore from FreeBSD/NetBSD. > It needs testing ...


Go Back   Unix Technical Forum > Unix Operating Systems > OpenBSD > mailing.openbsd.tech

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-18-2008, 09:25 AM
Todd C. Miller
 
Posts: n/a
Default Re: ffs2 support for dump/restore

so spake "Todd C. Miller" (millert):

> I've merged ffs2 support for dump/restore from FreeBSD/NetBSD.
> It needs testing on normal ffs partitions as well.
>
> I've verified that the new restore can read old archives
> and vice versa but some real world testing would be appreciated.


Here's an updated version that fixes an ffs2 issue (thanks Otto).

- todd

Index: include/protocols/dumprestore.h
================================================== =================
RCS file: /home/cvs/openbsd/src/include/protocols/dumprestore.h,v
retrieving revision 1.7
diff -u -r1.7 dumprestore.h
--- include/protocols/dumprestore.h 31 Mar 2004 22:08:32 -0000 1.7
+++ include/protocols/dumprestore.h 8 May 2007 13:08:27 -0000
@@ -1,5 +1,5 @@
/* $OpenBSD: dumprestore.h,v 1.7 2004/03/31 22:08:32 henning Exp $ */
-/* $NetBSD: dumprestore.h,v 1.6 1994/10/26 00:56:49 cgd Exp $ */
+/* $NetBSD: dumprestore.h,v 1.14 2005/12/26 19:01:47 perry Exp $ */

/*
* Copyright (c) 1980, 1993
@@ -37,8 +37,8 @@
* @(#)dumprestore.h 8.2 (Berkeley) 1/21/94
*/

-#ifndef _DUMPRESTORE_H_
-#define _DUMPRESTORE_H_
+#ifndef _PROTOCOLS_DUMPRESTORE_H_
+#define _PROTOCOLS_DUMPRESTORE_H_

/*
* TP_BSIZE is the size of file blocks on the dump tapes.
@@ -61,35 +61,81 @@

#define OFS_MAGIC (int)60011
#define NFS_MAGIC (int)60012
+#ifndef FS_UFS2_MAGIC
+#define FS_UFS2_MAGIC (int)0x19540119
+#endif
#define CHECKSUM (int)84446

union u_spcl {
char dummy[TP_BSIZE];
struct s_spcl {
int32_t c_type; /* record type (see below) */
- time_t c_date; /* date of this dump */
- time_t c_ddate; /* date of previous dump */
+ int32_t c_old_date; /* date of this dump */
+ int32_t c_old_ddate; /* date of previous dump */
int32_t c_volume; /* dump volume number */
- daddr_t c_tapea; /* logical block of this record */
- ino_t c_inumber; /* number of inode */
+ int32_t c_old_tapea; /* logical block of this record */
+ uint32_t c_inumber; /* number of inode */
int32_t c_magic; /* magic number (see above) */
int32_t c_checksum; /* record checksum */
- struct ufs1_dinode c_dinode; /* ownership and mode of inode */
- int32_t c_count; /* number of valid c_addr entries,
- unless c_type is TS_BITS or
- TS_CLRI. */
+ union {
+ struct ufs1_dinode __uc_dinode;
+ struct {
+ uint16_t __uc_mode;
+ int16_t __uc_spare1[3];
+ uint64_t __uc_size;
+ int32_t __uc_old_atime;
+ int32_t __uc_atimensec;
+ int32_t __uc_old_mtime;
+ int32_t __uc_mtimensec;
+ int32_t __uc_spare2[2];
+ int32_t __uc_rdev;
+ int32_t __uc_birthtimensec;
+ int64_t __uc_birthtime;
+ int64_t __uc_atime;
+ int64_t __uc_mtime;
+ int32_t __uc_spare4[7];
+ uint32_t __uc_file_flags;
+ int32_t __uc_spare5[2];
+ uint32_t __uc_uid;
+ uint32_t __uc_gid;
+ int32_t __uc_spare6[2];
+ } __uc_ino;
+ } __c_ino;
+ int32_t c_count; /* number of valid c_addr entries */
char c_addr[TP_NINDIR]; /* 1 => data; 0 => hole in inode */
char c_label[LBLSIZE]; /* dump label */
int32_t c_level; /* level of this dump */
- char c_filesys[NAMELEN]; /* name of dumped file system */
- char c_dev[NAMELEN]; /* name of dumped device */
- char c_host[NAMELEN]; /* name of dumped host */
+ char c_filesys[NAMELEN]; /* name of dumpped file system */
+ char c_dev[NAMELEN]; /* name of dumpped device */
+ char c_host[NAMELEN]; /* name of dumpped host */
int32_t c_flags; /* additional information */
- int32_t c_firstrec; /* first record on volume */
- int32_t c_spare[32]; /* reserved for future uses */
+ int32_t c_old_firstrec; /* first record on volume */
+ int64_t c_date; /* date of this dump */
+ int64_t c_ddate; /* date of previous dump */
+ int64_t c_tapea; /* logical block of this record */
+ int64_t c_firstrec; /* first record on volume */
+ int32_t c_spare[24]; /* reserved for future uses */
} s_spcl;
} u_spcl;
#define spcl u_spcl.s_spcl
+
+#define c_dinode __c_ino.__uc_dinode
+#define c_mode __c_ino.__uc_ino.__uc_mode
+#define c_spare1 __c_ino.__uc_ino.__uc_spare1
+#define c_size __c_ino.__uc_ino.__uc_size
+#define c_old_atime __c_ino.__uc_ino.__uc_old_atime
+#define c_atime __c_ino.__uc_ino.__uc_atime
+#define c_atimensec __c_ino.__uc_ino.__uc_atimensec
+#define c_mtime __c_ino.__uc_ino.__uc_mtime
+#define c_mtimensec __c_ino.__uc_ino.__uc_mtimensec
+#define c_birthtime __c_ino.__uc_ino.__uc_birthtime
+#define c_birthtimensec __c_ino.__uc_ino.__uc_birthtimensec
+#define c_old_mtime __c_ino.__uc_ino.__uc_old_mtime
+#define c_rdev __c_ino.__uc_ino.__uc_rdev
+#define c_file_flags __c_ino.__uc_ino.__uc_file_flags
+#define c_uid __c_ino.__uc_ino.__uc_uid
+#define c_gid __c_ino.__uc_ino.__uc_gid
+
/*
* special record types
*/
@@ -110,4 +156,4 @@
/* name, level, ctime(date) */
#define DUMPINFMT "%16s %c %[^\n]\n" /* inverse for scanf */

-#endif /* !_DUMPRESTORE_H_ */
+#endif /* !_PROTOCOLS_DUMPRESTORE_H_ */
Index: sbin/dump/dump.h
================================================== =================
RCS file: /home/cvs/openbsd/src/sbin/dump/dump.h,v
retrieving revision 1.15
diff -u -r1.15 dump.h
--- sbin/dump/dump.h 10 Apr 2007 04:45:37 -0000 1.15
+++ sbin/dump/dump.h 31 May 2007 19:46:56 -0000
@@ -32,9 +32,6 @@
* @(#)dump.h 8.1 (Berkeley) 6/5/93
*/

-#define MAXINOPB (MAXBSIZE / sizeof(struct ufs1_dinode))
-#define MAXNINDIR (MAXBSIZE / sizeof(daddr_t))
-
/*
* Dump maps used to describe what is to be dumped.
*/
@@ -90,31 +87,34 @@
void broadcast(char *message);
time_t do_stats(void);
void lastdump(int arg); /* int should be char */
-void msg(const char *fmt, ...);
-void msgtail(const char *fmt, ...);
+void msg(const char *fmt, ...)
+ __attribute__((__format__ (printf, 1, 2)));
+void msgtail(const char *fmt, ...)
+ __attribute__((__format__ (printf, 1, 2)));
int query(char *question);
void quit(const char *fmt, ...);
void statussig(int);
void timeest(void);

/* mapping routines */
-struct ufs1_dinode;
-off_t blockest(struct ufs1_dinode *dp);
+union dinode;
+off_t blockest(union dinode *dp);
void mapfileino(ino_t, off_t *, int *);
int mapfiles(ino_t maxino, off_t *tapesize, char *disk, char * const *dirv);
int mapdirs(ino_t maxino, off_t *tapesize);

/* file dumping routines */
-void blksout(daddr_t *blkp, int frags, ino_t ino);
-void bread(daddr_t blkno, char *buf, int size);
-void dumpino(struct ufs1_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(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);
@@ -124,7 +124,7 @@
void getfstab(void);

char *rawname(char *cp);
-struct ufs1_dinode *getino(ino_t inum);
+union dinode *getino(ino_t inum, int *mode);

/* rdump routines */
#ifdef RDUMP
Index: sbin/dump/itime.c
================================================== =================
RCS file: /home/cvs/openbsd/src/sbin/dump/itime.c,v
retrieving revision 1.14
diff -u -r1.14 itime.c
--- sbin/dump/itime.c 4 Mar 2007 22:37:18 -0000 1.14
+++ sbin/dump/itime.c 31 May 2007 19:46:56 -0000
@@ -150,9 +150,9 @@
continue;
if (ddp->dd_level >= level)
continue;
- if (ddp->dd_ddate <= spcl.c_ddate)
+ if (ddp->dd_ddate <= (time_t)spcl.c_ddate)
continue;
- spcl.c_ddate = ddp->dd_ddate;
+ spcl.c_ddate = (int64_t)ddp->dd_ddate;
lastlevel = ddp->dd_level;
}
}
@@ -162,9 +162,9 @@
{
FILE *df;
struct dumpdates *dtwalk;
- int i;
- int fd;
+ int fd, i;
char *fname;
+ time_t t;

if(uflag == 0)
return;
@@ -200,7 +200,7 @@
found:
(void) strlcpy(dtwalk->dd_name, fname, sizeof(dtwalk->dd_name));
dtwalk->dd_level = level;
- dtwalk->dd_ddate = spcl.c_date;
+ dtwalk->dd_ddate = (time_t)spcl.c_date;

ITITERATE(i, dtwalk) {
dumprecout(df, dtwalk);
@@ -210,8 +210,8 @@
if (ftruncate(fd, ftello(df)))
quit("ftruncate (%s): %s\n", dumpdates, strerror(errno));
(void) fclose(df);
- msg("level %c dump on %s", level,
- spcl.c_date == 0 ? "the epoch\n" : ctime(&spcl.c_date));
+ t = (time_t)spcl.c_date;
+ msg("level %c dump on %s", level, t == 0 ? "the epoch\n" : ctime(&t));
}

static void
Index: sbin/dump/main.c
================================================== =================
RCS file: /home/cvs/openbsd/src/sbin/dump/main.c,v
retrieving revision 1.40
diff -u -r1.40 main.c
--- sbin/dump/main.c 4 Mar 2007 22:36:54 -0000 1.40
+++ sbin/dump/main.c 31 May 2007 19:46:56 -0000
@@ -69,10 +69,6 @@
#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 */
@@ -84,6 +80,11 @@
char *host = NULL; /* remote host (if any) */
int maxbsize = 64*1024; /* XXX MAXBSIZE from sys/param.h */

+/*
+ * Possible superblock locations ordered from most to least likely.
+ */
+static int sblock_try[] = SBLOCKSEARCH;
+
static long numarg(char *, long, long);
static void obsolete(int *, char **[]);
static void usage(void);
@@ -93,20 +94,19 @@
{
ino_t ino;
int dirty;
- struct ufs1_dinode *dp;
+ union dinode *dp;
struct fstab *dt;
char *map;
- int ch;
+ int ch, mode;
struct tm then;
struct statfs fsbuf;
int i, anydirskipped, bflag = 0, Tflag = 0, honorlevel = 1;
ino_t maxino;
- time_t tnow;
+ time_t t;
int dirlist;
char *toplevel, *str, *mount_point = NULL;

- spcl.c_date = 0;
- (void)time((time_t *)&spcl.c_date);
+ spcl.c_date = (int64_t)time(NULL);

tsize = 0; /* Default later, based on 'c' option for cart tapes */
if ((tape = getenv("TAPE")) == NULL)
@@ -173,9 +173,9 @@
str = strptime(optarg, "%a %b %e %H:%M:%S %Y", &then);
then.tm_isdst = -1;
if (str == NULL || (*str != '\n' && *str != '\0'))
- spcl.c_ddate = (time_t) -1;
+ spcl.c_ddate = -1;
else
- spcl.c_ddate = mktime(&then);
+ spcl.c_ddate = (int64_t)mktime(&then);
if (spcl.c_ddate < 0) {
(void)fprintf(stderr, "bad time \"%s\"\n",
optarg);
@@ -378,10 +378,12 @@
if (!Tflag)
getdumptime(); /* /etc/dumpdates snarfed */

+ t = (time_t)spcl.c_date;
msg("Date of this level %c dump: %s", level,
- spcl.c_date == 0 ? "the epoch\n" : ctime(&spcl.c_date));
+ t == 0 ? "the epoch\n" : ctime(&t));
+ t = (time_t)spcl.c_ddate;
msg("Date of last level %c dump: %s", lastlevel,
- spcl.c_ddate == 0 ? "the epoch\n" : ctime(&spcl.c_ddate));
+ t == 0 ? "the epoch\n" : ctime(&t));
msg("Dumping %s ", disk);
if (mount_point != NULL)
msgtail("(%s) ", mount_point);
@@ -396,9 +398,18 @@
}
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++) {
+ ssize_t n = pread(diskfd, sblock, SBLOCKSIZE,
+ (off_t)sblock_try[i]);
+ if (n == SBLOCKSIZE && (sblock->fs_magic == FS_UFS1_MAGIC ||
+ (sblock->fs_magic == FS_UFS2_MAGIC &&
+ sblock->fs_sblockloc == 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))
@@ -407,7 +418,8 @@
if (TP_BSIZE != (1 << tp_bshift))
quit("TP_BSIZE (%d) is not a power of 2\n", TP_BSIZE);
#ifdef FS_44INODEFMT
- if (sblock->fs_inodefmt >= FS_44INODEFMT)
+ if (sblock->fs_magic == FS_UFS2_MAGIC ||
+ sblock->fs_inodefmt >= FS_44INODEFMT)
spcl.c_flags |= DR_NEWINODEFMT;
#endif
maxino = sblock->fs_ipg * sblock->fs_ncg;
@@ -432,7 +444,7 @@

if (pipeout || unlimited) {
tapesize += 10; /* 10 trailer blocks */
- msg("estimated %qd tape blocks.\n", tapesize);
+ msg("estimated %lld tape blocks.\n", tapesize);
} else {
double fetapes;

@@ -472,7 +484,7 @@
tapesize += (etapes - 1) *
(howmany(mapsize * sizeof(char), TP_BSIZE) + 1);
tapesize += etapes + 10; /* headers + 10 trailer blks */
- msg("estimated %qd tape blocks on %3.2f tape(s).\n",
+ msg("estimated %lld tape blocks on %3.2f tape(s).\n",
tapesize, fetapes);
}

@@ -499,16 +511,14 @@
/*
* 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);
}

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
@@ -518,8 +528,7 @@
/*
* 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);
@@ -529,15 +538,16 @@
for (i = 0; i < ntrec; i++)
writeheader(maxino - 1);
if (pipeout)
- msg("%ld tape blocks\n", spcl.c_tapea);
+ msg("%lld tape blocks\n", spcl.c_tapea);
else
- msg("%ld tape blocks on %d volume%s\n",
+ msg("%lld tape blocks on %d volume%s\n",
spcl.c_tapea, spcl.c_volume,
(spcl.c_volume == 1) ? "" : "s");
- tnow = do_stats();
+ t = (time_t)spcl.c_date;
msg("Date of this level %c dump: %s", level,
- spcl.c_date == 0 ? "the epoch\n" : ctime(&spcl.c_date));
- msg("Date this dump completed: %s", ctime(&tnow));
+ t == 0 ? "the epoch\n" : ctime(&t));
+ t = do_stats();
+ msg("Date this dump completed: %s", ctime(&t));
msg("Average transfer rate: %ld KB/s\n", xferrate / tapeno);
putdumptime();
trewind();
Index: sbin/dump/optr.c
================================================== =================
RCS file: /home/cvs/openbsd/src/sbin/dump/optr.c,v
retrieving revision 1.29
diff -u -r1.29 optr.c
--- sbin/dump/optr.c 20 Feb 2007 01:44:16 -0000 1.29
+++ sbin/dump/optr.c 31 May 2007 19:46:56 -0000
@@ -42,6 +42,8 @@
#include <sys/wait.h>
#include <sys/time.h>

+#include <ufs/ufs/dinode.h>
+
#include <errno.h>
#include <fstab.h>
#include <grp.h>
Index: sbin/dump/tape.c
================================================== =================
RCS file: /home/cvs/openbsd/src/sbin/dump/tape.c,v
retrieving revision 1.28
diff -u -r1.28 tape.c
--- sbin/dump/tape.c 4 Mar 2007 22:36:54 -0000 1.28
+++ sbin/dump/tape.c 31 May 2007 19:46:56 -0000
@@ -62,7 +62,7 @@
#include "pathnames.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 @@
* The following structure defines the instruction packets sent to slaves.
*/
struct req {
- 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 */
pid_t 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];
@@ -110,7 +110,7 @@
char (*nextblock)[TP_BSIZE];

static time_t tstart_volume; /* time of volume start */
-static int tapea_volume; /* value of spcl.c_tapea at volume start */
+static int64_t tapea_volume; /* value of spcl.c_tapea at volume start */

pid_t master; /* pid of master, for sending error signals */
int tenths; /* length of tape used per block written */
@@ -160,7 +160,7 @@
writerec(char *dp, int isspcl)
{

- slp->req[trecno].dblk = (daddr_t)0;
+ slp->req[trecno].dblk = (ufs2_daddr_t)0;
slp->req[trecno].count = 1;
*(union u_spcl *)(*(nextblock)++) = *(union u_spcl *)dp;
if (isspcl)
@@ -172,9 +172,10 @@
}

void
-dumpblock(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;
@@ -203,7 +204,7 @@
quit("Cannot recover\n");
/* NOTREACHED */
}
- msg("write error %d blocks into volume %d\n", blocksthisvol, tapeno);
+ msg("write error %ld blocks into volume %d\n", blocksthisvol, tapeno);
broadcast("DUMP WRITE ERROR!\n");
if (!query("Do you want to restart?"))
dumpabort(0);
@@ -240,7 +241,7 @@
if (ttaken > 0) {
msg("Volume %d took %d:%02d:%02d\n", tapeno,
ttaken / 3600, (ttaken % 3600) / 60, ttaken % 60);
- msg("Volume %d transfer rate: %ld KB/s\n", tapeno,
+ msg("Volume %d transfer rate: %d KB/s\n", tapeno,
blocks / ttaken);
xferrate += blocks / ttaken;
}
@@ -267,7 +268,7 @@
deltat = tstart_writing - tnow + (1.0 * (tnow - tstart_writing))
/ blockswritten * tapesize;
(void)snprintf(msgbuf, sizeof(msgbuf),
- "dump: %s %3.2f%% done at %d KB/s, finished in %d:%02d\n",
+ "dump: %s %3.2f%% done at %lld KB/s, finished in %d:%02d\n",
tape, (blockswritten * 100.0) / tapesize,
(spcl.c_tapea - tapea_volume) / (tnow - tstart_volume),
(int)(deltat / 3600), (int)((deltat % 3600) / 60));
@@ -279,7 +280,7 @@
flushtape(void)
{
int i, blks, got;
- long lastfirstrec;
+ int64_t lastfirstrec;

int siz = (char *)nextblock - (char *)slp->req;

@@ -445,7 +446,8 @@
{
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];
@@ -681,9 +683,11 @@
spcl.c_firstrec = slp->firstrec;
spcl.c_volume++;
spcl.c_type = TS_TAPE;
- spcl.c_flags |= DR_NEWHEADER;
+ if (sblock->fs_magic != FS_UFS2_MAGIC)
+ spcl.c_flags |= DR_NEWHEADER;
writeheader((ino_t)slp->inode);
- spcl.c_flags &=~ DR_NEWHEADER;
+ if (sblock->fs_magic != FS_UFS2_MAGIC)
+ spcl.c_flags &=~ DR_NEWHEADER;
msg("Volume %d started at: %s", tapeno, ctime(&tstart_volume));
if (tapeno > 1)
msg("Volume %d begins with blocks from inode %d\n",
@@ -795,7 +799,7 @@
static void
doslave(int cmd, int slave_number)
{
- int nread, nextslave, size, wrote, eot_count;
+ int nread, nextslave, size, wrote = 0, eot_count;
sigset_t nsigset, osigset;

/*
Index: sbin/dump/traverse.c
================================================== =================
RCS file: /home/cvs/openbsd/src/sbin/dump/traverse.c,v
retrieving revision 1.20
diff -u -r1.20 traverse.c
--- sbin/dump/traverse.c 19 Mar 2007 13:27:47 -0000 1.20
+++ sbin/dump/traverse.c 31 May 2007 19:48:50 -0000
@@ -51,17 +51,26 @@
#include <errno.h>
#include <fts.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.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

-static int dirindir(ino_t ino, daddr_t blkno, int level, off_t *size);
-static void dmpindir(ino_t ino, daddr_t blk, int level, off_t *size);
-static int searchdir(ino_t ino, daddr_t blkno, long size, off_t filesize);
+static int dirindir(ino_t ino, ufs2_daddr_t blkno, int level, off_t *size);
+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, off_t filesize);

/*
* This is an estimation of the number of TP_BSIZE blocks in the file.
@@ -71,7 +80,7 @@
* hence the estimate may be high.
*/
off_t
-blockest(struct ufs1_dinode *dp)
+blockest(union dinode *dp)
{
off_t blkest, sizeest;

@@ -89,11 +98,11 @@
* dump blocks (sizeest vs. blkest in the indirect block
* calculation).
*/
- blkest = howmany(dbtob((off_t)dp->di_blocks), TP_BSIZE);
- sizeest = howmany(dp->di_size, TP_BSIZE);
+ blkest = howmany(dbtob((off_t)DIP(dp, di_blocks)), TP_BSIZE);
+ sizeest = howmany((off_t)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,
@@ -104,13 +113,13 @@

/* 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
@@ -122,10 +131,10 @@
mapfileino(ino_t ino, off_t *tapesize, int *dirskipped)
{
int mode;
- struct ufs1_dinode *dp;
+ union dinode *dp;

- dp = getino(ino);
- if ((mode = (dp->di_mode & IFMT)) == 0)
+ dp = getino(ino, &mode);
+ if (mode == 0)
return;
SETINO(ino, usedinomap);
if (mode == IFDIR)
@@ -142,6 +151,59 @@
*dirskipped = 1;
}

+void
+fs_mapinodes(ino_t maxino, off_t *tapesize, int *anydirskipped)
+{
+ int i, cg, inosused;
+ struct cg *cgp;
+ ino_t ino;
+ char *cp;
+
+ if ((cgp = malloc(sblock->fs_cgsize)) == NULL)
+ quit("fs_mapinodes: cannot allocate memory.\n");
+
+ for (cg = 0; cg < sblock->fs_ncg; cg++) {
+ ino = cg * sblock->fs_ipg;
+ bread(fsbtodb(sblock, cgtod(sblock, cg)), (char *)cgp,
+ sblock->fs_cgsize);
+ if (sblock->fs_magic == FS_UFS2_MAGIC)
+ inosused = cgp->cg_initediblk;
+ else
+ inosused = sblock->fs_ipg;
+ /*
+ * If we are using soft updates, then we can trust the
+ * cylinder group inode allocation maps to tell us which
+ * inodes are allocated. We will scan the used inode map
+ * to find the inodes that are really in use, and then
+ * read only those inodes in from disk.
+ */
+ if (sblock->fs_flags & FS_DOSOFTDEP) {
+ if (!cg_chkmagic(cgp))
+ quit("mapfiles: cg %d: bad magic number\n", cg);
+ cp = &cg_inosused(cgp)[(inosused - 1) / CHAR_BIT];
+ for ( ; inosused > 0; inosused -= CHAR_BIT, cp--) {
+ if (*cp == 0)
+ continue;
+ for (i = 1 << (CHAR_BIT - 1); i > 0; i >>= 1) {
+ if (*cp & i)
+ break;
+ inosused--;
+ }
+ break;
+ }
+ if (inosused <= 0)
+ continue;
+ }
+ for (i = 0; i < inosused; i++, ino++) {
+ if (ino < ROOTINO)
+ continue;
+ mapfileino(ino, tapesize, anydirskipped);
+ }
+ }
+
+ free(cgp);
+}
+
/*
* Dump pass 1.
*
@@ -227,11 +289,7 @@
*/
mapfileino(ROOTINO, tapesize, &anydirskipped);
} else {
- ino_t ino;
-
- for (ino = ROOTINO; ino < maxino; ino++) {
- mapfileino(ino, tapesize, &anydirskipped);
- }
+ fs_mapinodes(maxino, tapesize, &anydirskipped);
}
/*
* Restore gets very upset if the root is not dumped,
@@ -256,10 +314,11 @@
int
mapdirs(ino_t maxino, off_t *tapesize)
{
- struct ufs1_dinode *dp;
+ union dinode *dp;
int i, isdir;
char *map;
ino_t ino;
+ union dinode di;
off_t filesize;
int ret, change = 0;

@@ -271,21 +330,29 @@
isdir >>= 1;
if ((isdir & 1) == 0 || TSTINO(ino, dumpinomap))
continue;
- dp = getino(ino);
- filesize = dp->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 = (off_t)DIP(dp, di_size);
for (ret = 0, i = 0; filesize > 0 && i < NDADDR; i++) {
- if (dp->di_db[i] != 0)
- ret |= searchdir(ino, dp->di_db[i],
- dblksize(sblock, dp, i), filesize);
+ if (DIP(&di, di_db[i]) != 0)
+ ret |= searchdir(ino, DIP(&di, di_db[i]),
+ sblksize(sblock, DIP(dp, di_size), i),
+ filesize);
if (ret & HASDUMPEDFILE)
filesize = 0;
else
filesize -= sblock->fs_bsize;
}
for (i = 0; filesize > 0 && i < NIADDR; i++) {
- if (dp->di_ib[i] == 0)
+ if (DIP(&di, di_ib[i]) == 0)
continue;
- ret |= dirindir(ino, dp->di_ib[i], i, &filesize);
+ ret |= dirindir(ino, DIP(&di, di_ib[i]), i, &filesize);
}
if (ret & HASDUMPEDFILE) {
SETINO(ino, dumpinomap);
@@ -309,16 +376,21 @@
* require the directory to be dumped.
*/
static int
-dirindir(ino_t ino, daddr_t blkno, int ind_level, off_t *filesize)
+dirindir(ino_t ino, ufs2_daddr_t blkno, int ind_level, off_t *filesize)
{
int ret = 0;
int i;
- daddr_t idblk[MAXNINDIR];
+ static void *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);
@@ -331,7 +403,10 @@
}
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);
}
@@ -344,13 +419,15 @@
* contains any subdirectories.
*/
static int
-searchdir(ino_t ino, daddr_t blkno, long size, off_t filesize)
+searchdir(ino_t ino, ufs2_daddr_t blkno, long size, off_t filesize)
{
struct direct *dp;
long loc;
- char dblk[MAXBSIZE];
+ static caddr_t dblk;
int ret = 0;

+ 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;
@@ -389,7 +466,7 @@
* Dump the contents of an inode to tape.
*/
void
-dumpino(struct ufs1_dinode *dp, ino_t ino)
+dumpino(union dinode *dp, ino_t ino)
{
int ind_level, cnt;
off_t size;
@@ -400,10 +477,36 @@
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 = (time_t)dp->dp1.di_atime;
+ spcl.c_atimensec = dp->dp1.di_atimensec;
+ spcl.c_mtime = (time_t)dp->dp1.di_mtime;
+ spcl.c_mtimensec = dp->dp1.di_mtimensec;
+ spcl.c_birthtime = 0;
+ spcl.c_birthtimensec = 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 = (time_t)dp->dp2.di_atime;
+ spcl.c_atimensec = dp->dp2.di_atimensec;
+ spcl.c_mtime = (time_t)dp->dp2.di_mtime;
+ spcl.c_mtimensec = dp->dp2.di_mtimensec;
+ spcl.c_birthtime = (time_t)dp->dp2.di_birthtime;
+ spcl.c_birthtimensec = dp->dp2.di_birthnsec;
+ 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 & IFMT) {
+ switch (DIP(dp, di_mode) & S_IFMT) {

case 0:
/*
@@ -415,18 +518,24 @@
/*
* Check for short symbolic link.
*/
- if (dp->di_size > 0 &&
+ if (DIP(dp, di_size) > 0 &&
#ifdef FS_44INODEFMT
- (dp->di_size < sblock->fs_maxsymlinklen ||
- (sblock->fs_maxsymlinklen == 0 && dp->di_blocks == 0))) {
+ (DIP(dp, di_size) < sblock->fs_maxsymlinklen ||
+ (sblock->fs_maxsymlinklen == 0 && DIP(dp, di_blocks) == 0))) {
#else
- dp->di_blocks == 0) {
+ DIP(dp, di_blocks) == 0) {
#endif
+ void *shortlink;
+
spcl.c_addr[0] = 1;
spcl.c_count = 1;
writeheader(ino);
- memcpy(buf, dp->di_shortlink, (u_long)dp->di_size);
- buf[dp->di_size] = '\0';
+ if (sblock->fs_magic == FS_UFS1_MAGIC)
+ shortlink = dp->dp1.di_shortlink;
+ else
+ shortlink = dp->dp2.di_shortlink;
+ memcpy(buf, shortlink, DIP(dp, di_size));
+ buf[DIP(dp, di_size)] = '\0';
writerec(buf, 0);
return;
}
@@ -434,7 +543,7 @@

case IFDIR:
case IFREG:
- if (dp->di_size > 0)
+ if (DIP(dp, di_size) > 0)
break;
/* FALLTHROUGH */

@@ -446,18 +555,22 @@
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;
}
@@ -467,13 +580,15 @@
* Read indirect blocks, and pass the data blocks to be dumped.
*/
static void
-dmpindir(ino_t ino, daddr_t blk, int ind_level, off_t *size)
+dmpindir(ino_t ino, ufs2_daddr_t blk, int ind_level, off_t *size)
{
int i, cnt;
- daddr_t idblk[MAXNINDIR];
+ static void *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) {
@@ -482,12 +597,20 @@
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;
}
@@ -497,9 +620,44 @@
* Collect up the data into tape record sized buffers and output them.
*/
void
-blksout(daddr_t *blkp, int frags, ino_t ino)
+ufs1_blksout(ufs1_daddr_t *blkp, int frags, ino_t ino)
{
- 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);
@@ -557,7 +715,15 @@
int32_t sum, cnt, *lp;

spcl.c_inumber = ino;
- spcl.c_magic = NFS_MAGIC;
+ if (sblock->fs_magic == FS_UFS2_MAGIC) {
+ spcl.c_magic = FS_UFS2_MAGIC;
+ } else {
+ spcl.c_magic = NFS_MAGIC;
+ spcl.c_old_date = (int32_t)spcl.c_date;
+ spcl.c_old_ddate = (int32_t)spcl.c_ddate;
+ spcl.c_old_tapea = (int32_t)spcl.c_tapea;
+ spcl.c_old_firstrec = (int32_t)spcl.c_firstrec;
+ }
spcl.c_checksum = 0;
lp = (int32_t *)&spcl;
sum = 0;
@@ -572,20 +738,32 @@
writerec((char *)&spcl, 1);
}

-struct ufs1_dinode *
-getino(ino_t inum)
+union dinode *
+getino(ino_t inum, int *modep)
{
- static daddr_t minino, maxino;
- static struct ufs1_dinode inoblock[MAXINOPB];
+ static ino_t minino, maxino;
+ static void *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);
}

/*
@@ -598,7 +776,7 @@
#define BREADEMAX 32

void
-bread(daddr_t blkno, char *buf, int size)
+bread(ufs2_daddr_t blkno, char *buf, int size)
{
int cnt, i;

@@ -622,10 +800,10 @@
goto loop;
}
if (cnt == -1)
- msg("read error from %s: %s: [block %d]: count=%d\n",
+ msg("read error from %s: %s: [block %lld]: count=%d\n",
disk, strerror(errno), blkno, size);
else
- msg("short read error from %s: [block %d]: count=%d, got=%d\n",
+ msg("short read error from %s: [block %lld]: count=%d, got=%d\n",
disk, blkno, size, cnt);
if (++breaderrors > BREADEMAX) {
msg("More than %d block read errors from %s\n",
@@ -648,11 +826,11 @@
if ((cnt = read(diskfd, buf, (int)dev_bsize)) == dev_bsize)
continue;
if (cnt == -1) {
- msg("read error from %s: %s: [sector %d]: count=%d\n",
+ msg("read error from %s: %s: [sector %lld]: count=%ld\n",
disk, strerror(errno), blkno, dev_bsize);
continue;
}
- msg("short read error from %s: [sector %d]: count=%d, got=%d\n",
+ msg("short read error from %s: [sector %lld]: count=%ld, got=%d\n",
disk, blkno, dev_bsize, cnt);
}
}
Index: sbin/restore/dirs.c
================================================== =================
RCS file: /home/cvs/openbsd/src/sbin/restore/dirs.c,v
retrieving revision 1.30
diff -u -r1.30 dirs.c
--- sbin/restore/dirs.c 28 Apr 2005 16:15:45 -0000 1.30
+++ sbin/restore/dirs.c 13 May 2007 19:22:28 -0000
@@ -83,7 +83,8 @@
*/
struct modeinfo {
ino_t ino;
- struct timeval timep[2];
+ struct timeval ctimep[2];
+ struct timeval mtimep[2];
mode_t mode;
uid_t uid;
gid_t gid;
@@ -121,7 +122,7 @@
char d_name[ODIRSIZ];
};

-static struct inotab *allocinotab(ino_t, struct ufs1_dinode *, long);
+static struct inotab *allocinotab(FILE *, struct context *, long);
static void dcvt(struct odirect *, struct direct *);
static void flushent(void);
static struct inotab *inotablookup(ino_t);
@@ -142,7 +143,6 @@
extractdirs(int genmode)
{
int i;
- struct ufs1_dinode *ip;
struct inotab *itp;
struct direct nulldir;
int fd;
@@ -183,8 +183,7 @@
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)
@@ -196,7 +195,7 @@
panic("Root directory is not on tape\n");
return;
}
- itp = allocinotab(curfile.ino, ip, seekpt);
+ itp = allocinotab(mf, &curfile, seekpt);
getfile(putdir, xtrnull);
putent(&nulldir);
flushent();
@@ -211,7 +210,7 @@
skipdirs(void)
{

- while (curfile.dip && (curfile.dip->di_mode & IFMT) == IFDIR) {
+ while (curfile.ino && (curfile.mode & IFMT) == IFDIR) {
skipfile();
}
}
@@ -270,7 +269,7 @@
while (dp != NULL) {
locname[namelen] = '\0';
if (namelen + dp->d_namlen >= sizeof(locname)) {
- fprintf(stderr, "%s%s: name exceeds %d char\n",
+ fprintf(stderr, "%s%s: name exceeds %zd char\n",
locname, dp->d_name, sizeof(locname) - 1);
} else {
(void)strlcat(locname, dp->d_name, sizeof(locname));
@@ -617,11 +616,14 @@
if (ep == NULL) {
panic("cannot find directory inode %d\n", node.ino);
} else {
- cp = myname(ep);
- (void)chown(cp, node.uid, node.gid);
- (void)chmod(cp, node.mode);
- (void)chflags(cp, node.flags);
- utimes(cp, node.timep);
+ if (!Nflag) {
+ cp = myname(ep);
+ (void)chown(cp, node.uid, node.gid);
+ (void)chmod(cp, node.mode);
+ (void)chflags(cp, node.flags);
+ (void)utimes(cp, node.ctimep);
+ (void)utimes(cp, node.mtimep);
+ }
ep->e_flags &= ~NEW;
}
}
@@ -687,7 +689,7 @@
* If requested, save its pertinent mode, owner, and time info.
*/
static struct inotab *
-allocinotab(ino_t ino, struct ufs1_dinode *dip, long seekpt)
+allocinotab(FILE *mf, struct context *ctxp, long seekpt)
{
struct inotab *itp;
struct modeinfo node;
@@ -695,21 +697,25 @@
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.mtimep[0].tv_sec = ctxp->atime_sec;
+ node.mtimep[0].tv_usec = ctxp->atime_nsec / 1000;
+ node.mtimep[1].tv_sec = ctxp->mtime_sec;
+ node.mtimep[1].tv_usec = ctxp->mtime_nsec / 1000;
+ node.ctimep[0].tv_sec = ctxp->atime_sec;
+ node.ctimep[0].tv_usec = ctxp->atime_nsec / 1000;
+ node.ctimep[1].tv_sec = ctxp->birthtime_sec;
+ node.ctimep[1].tv_usec = ctxp->birthtime_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);
}
Index: sbin/restore/restore.h
================================================== =================
RCS file: /home/cvs/openbsd/src/sbin/restore/restore.h,v
retrieving revision 1.6
diff -u -r1.6 restore.h
--- sbin/restore/restore.h 31 Mar 2004 22:08:32 -0000 1.6
+++ sbin/restore/restore.h 13 May 2007 18:54:32 -0000
@@ -105,10 +105,21 @@
* 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 ufs1_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 */
+ time_t birthtime_sec; /* creation time seconds */
+ int atime_nsec; /* access time nanoseconds */
+ int mtime_nsec; /* modified time nanoseconds */
+ int birthtime_nsec; /* creation time nanoseconds */
+ off_t size; /* size of file */
+ char *name; /* name of file */
} curfile;
/* actions */
#define USING 1 /* extracting from the tape */
Index: sbin/restore/tape.c
================================================== =================
RCS file: /home/cvs/openbsd/src/sbin/restore/tape.c,v
retrieving revision 1.31
diff -u -r1.31 tape.c
--- sbin/restore/tape.c 14 Jun 2005 19:46:05 -0000 1.31
+++ sbin/restore/tape.c 13 May 2007 19:24:36 -0000
@@ -86,10 +86,37 @@

int oldinofmt; /* old inode format conversion required */
int Bcvt; /* Swap Bytes (for CCI or sun) */
-static int Qcvt; /* Swap quads (for sun) */

#define FLUSHTAPEBUF() blkcnt = ntrec + 1

+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_int16_t c_inumber;
+ int32_t c_magic;
+ int32_t c_checksum;
+ struct odinode {
+ unsigned short odi_mode;
+ u_int16_t odi_nlink;
+ u_int16_t odi_uid;
+ u_int16_t 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_odinode;
+ int32_t c_count;
+ char c_addr[256];
+ } s_ospcl;
+};
+
static void accthdr(struct s_spcl *);
static int checksum(int *);
static void findinode(struct s_spcl *);
@@ -98,6 +125,7 @@
static void readtape(char *);
static void setdumpnum(void);
static void swap_header(struct s_spcl *);
+static void swap_old_header(struct s_ospcl *);
static void terminateinput(void);
static void xtrfile(char *, size_t);
static void xtrlnkfile(char *, size_t);
@@ -198,7 +226,8 @@
(void)fputs("Converting to new file system format.\n", stderr);
}
if (pipein) {
- endoftapemark.s_spcl.c_magic = cvtflag ? OFS_MAGIC : NFS_MAGIC;
+ endoftapemark.s_spcl.c_magic = cvtflag ? OFS_MAGIC :
+ FS_UFS2_MAGIC;
endoftapemark.s_spcl.c_type = TS_END;
ip = (int *)&endoftapemark;
j = sizeof(union u_spcl) / sizeof(int);
@@ -210,8 +239,8 @@
}
if (vflag || command == 't')
printdumpinfo();
- dumptime = spcl.c_ddate;
- dumpdate = spcl.c_date;
+ dumptime = (time_t)spcl.c_ddate;
+ dumpdate = (time_t)spcl.c_date;
if (stat(".", &stbuf) < 0)
err(1, "cannot stat .");
if (stbuf.st_blksize > 0 && stbuf.st_blksize < TP_BSIZE )
@@ -257,7 +286,7 @@
void
getvol(long nextvol)
{
- long newvol = 0, savecnt, wantnext, i;
+ long newvol = 0, savecnt = 0, wantnext = 0, i;
union u_spcl tmpspcl;
# define tmpbuf tmpspcl.s_spcl
char buf[TP_BSIZE];
@@ -364,8 +393,8 @@
goto again;
}
if (tmpbuf.c_date != dumpdate || tmpbuf.c_ddate != dumptime) {
- fprintf(stderr, "Wrong dump date\n\tgot: %s",
- ctime(&tmpbuf.c_date));
+ time_t t = (time_t)tmpbuf.c_date;
+ fprintf(stderr, "Wrong dump date\n\tgot: %s", ctime(&t));
fprintf(stderr, "\twanted: %s", ctime(&dumpdate));
volno = 0;
goto again;
@@ -379,7 +408,7 @@
* If coming to this volume at random, skip to the beginning
* of the next record.
*/
- Dprintf(stdout, "read %ld recs, tape starts with %d\n",
+ Dprintf(stdout, "read %ld recs, tape starts with %lld\n",
tpblksread, tmpbuf.c_firstrec);
if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) {
if (!wantnext) {
@@ -430,7 +459,7 @@
}
curfile.name = "<name unknown>";
curfile.action = UNKNOWN;
- curfile.dip = NULL;
+ curfile.mode = 0;
curfile.ino = maxino;
if (gettingfile) {
gettingfile = 0;
@@ -465,9 +494,13 @@
void
printdumpinfo(void)
{
- fprintf(stdout, "Dump date: %s", ctime(&spcl.c_date));
+ time_t t;
+
+ t = (time_t)spcl.c_date;
+ fprintf(stdout, "Dump date: %s", ctime(&t));
+ t = (time_t)spcl.c_ddate;
fprintf(stdout, "Dumped from: %s",
- (spcl.c_ddate == 0) ? "the epoch\n" : ctime(&spcl.c_ddate));
+ (spcl.c_ddate == 0) ? "the epoch\n" : ctime(&t));
if (spcl.c_host[0] == '\0')
return;
fprintf(stderr, "Level %d dump of %s on %s:%s\n",
@@ -479,18 +512,31 @@
extractfile(char *name)
{
u_int flags;
+ uid_t uid;
+ gid_t gid;
mode_t mode;
- struct timeval timep[2];
+ struct timeval mtimep[2], ctimep[2];
struct entry *ep;
+ int setbirth;

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;
- mode = curfile.dip->di_mode;
- flags = curfile.dip->di_flags;
+ mtimep[0].tv_sec = curfile.atime_sec;
+ mtimep[0].tv_usec = curfile.atime_nsec / 1000;
+ mtimep[1].tv_sec = curfile.mtime_sec;
+ mtimep[1].tv_usec = curfile.mtime_nsec / 1000;
+
+ setbirth = curfile.birthtime_sec != 0;
+ if (setbirth) {
+ ctimep[0].tv_sec = curfile.atime_sec;
+ ctimep[0].tv_usec = curfile.atime_nsec / 1000;
+ ctimep[1].tv_sec = curfile.birthtime_sec;
+ ctimep[1].tv_usec = curfile.birthtime_nsec / 1000;
+ }
+ uid = curfile.uid;
+ gid = curfile.gid;
+ mode = curfile.mode;
+ flags = curfile.file_flags;
switch (mode & IFMT) {

default:
@@ -515,10 +561,6 @@
return (genliteraldir(name, curfile.ino));

case IFLNK: {
- /* Gotta save these, linkit() changes curfile. */
- uid_t luid = curfile.dip->di_uid;
- gid_t lgid = curfile.dip->di_gid;
-
lnkbuf[0] = '\0';
pathlen = 0;
getfile(xtrlnkfile, xtrlnkskip);
@@ -530,7 +572,7 @@
}
if (linkit(lnkbuf, name, SYMLINK) == FAIL)
return (FAIL);
- (void)lchown(name, luid, lgid);
+ (void)lchown(name, uid, gid);
return (GOOD);
}

@@ -541,16 +583,18 @@
skipfile();
return (GOOD);
}
- if (mknod(name, mode, (int)curfile.dip->di_rdev) < 0) {
+ if (mknod(name, mode, (int)curfile.rdev) < 0) {
warn("%s: cannot create special file", name);
skipfile();
return (FAIL);
}
- (void)chown(name, curfile.dip->di_uid, curfile.dip->di_gid);
+ (void)chown(name, uid, gid);
(void)chmod(name, mode);
(void)chflags(name, flags);
skipfile();
- utimes(name, timep);
+ if (setbirth)
+ (void)utimes(name, ctimep);
+ (void)utimes(name, mtimep);
return (GOOD);

case IFIFO:
@@ -564,11 +608,13 @@
skipfile();
return (FAIL);
}
- (void)chown(name, curfile.dip->di_uid, curfile.dip->di_gid);
+ (void)chown(name, uid, gid);
(void)chmod(name, mode);
(void)chflags(name, flags);
skipfile();
- utimes(name, timep);
+ if (setbirth)
+ (void)utimes(name, ctimep);
+ (void)utimes(name, mtimep);
return (GOOD);

case IFREG:
@@ -583,12 +629,14 @@
skipfile();
return (FAIL);
}
- (void)fchown(ofile, curfile.dip->di_uid, curfile.dip->di_gid);
+ (void)fchown(ofile, curfile.uid, curfile.gid);
(void)fchmod(ofile, mode);
(void)fchflags(ofile, flags);
getfile(xtrfile, xtrskip);
(void)close(ofile);
- utimes(name, timep);
+ if (setbirth)
+ (void)utimes(name, ctimep);
+ (void)utimes(name, mtimep);
return (GOOD);
}
/* NOTREACHED */
@@ -630,7 +678,7 @@
{
int i;
volatile int curblk = 0;
- volatile off_t size = spcl.c_dinode.di_size;
+ volatile off_t size = spcl.c_size;
static char clearedbuf[MAXBSIZE];
char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE];
char junk[TP_BSIZE];
@@ -638,7 +686,7 @@

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;
@@ -938,43 +986,14 @@
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_int16_t c_inumber;
- int32_t c_magic;
- int32_t c_checksum;
- struct odinode {
- unsigned short odi_mode;
- u_int16_t odi_nlink;
- u_int16_t odi_uid;
- u_int16_t 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;
+ union u_ospcl u_ospcl;

if (!cvtflag) {
readtape((char *)buf);
- if (buf->c_magic != NFS_MAGIC) {
- if (swap32(buf->c_magic) != NFS_MAGIC)
+ if (buf->c_magic != NFS_MAGIC &&
+ buf->c_magic != FS_UFS2_MAGIC) {
+ if (swap32(buf->c_magic) != NFS_MAGIC &&
+ swap32(buf->c_magic) != FS_UFS2_MAGIC)
return (FAIL);
if (!Bcvt) {
Vprintf(stdout, "Note: Doing Byte swapping\n");
@@ -987,7 +1006,20 @@
swap_header(buf);
goto good;
}
+
readtape((char *)(&u_ospcl.s_ospcl));
+ if (checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
+ return (FAIL);
+ if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC) {
+ if (swap32(u_ospcl.s_ospcl.c_magic) != OFS_MAGIC)
+ return (FAIL);
+ if (!Bcvt) {
+ fprintf(stdout, "Note: Doing Byte swapping\n");
+ Bcvt = 1;
+ }
+ swap_old_header(&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;
@@ -996,40 +1028,17 @@
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_mode = u_ospcl.s_ospcl.c_odinode.odi_mode;
+ buf->c_uid = u_ospcl.s_ospcl.c_odinode.odi_uid;
+ buf->c_gid = u_ospcl.s_ospcl.c_odinode.odi_gid;
+ buf->c_size = u_ospcl.s_ospcl.c_odinode.odi_size;
+ buf->c_rdev = u_ospcl.s_ospcl.c_odinode.odi_rdev;
+ buf->c_atime = u_ospcl.s_ospcl.c_odinode.odi_atime;
+ buf->c_mtime = u_ospcl.s_ospcl.c_odinode.odi_mtime;
buf->c_count = u_ospcl.s_ospcl.c_count;
memcpy(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;
-
+ buf->c_magic = FS_UFS2_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 (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;
- }
-
switch (buf->c_type) {

case TS_CLRI:
@@ -1038,7 +1047,7 @@
* 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;
break;

case TS_TAPE:
@@ -1050,6 +1059,18 @@
break;

case TS_INODE:
+ if (buf->c_magic == NFS_MAGIC) {
+ buf->c_tapea = buf->c_old_tapea;
+ buf->c_firstrec = buf->c_old_firstrec;
+ buf->c_date = buf->c_old_date;
+ buf->c_ddate = buf->c_old_ddate;
+ buf->c_atime = buf->c_old_atime;
+ buf->c_mtime = buf->c_old_mtime;
+ buf->c_birthtime = 0;
+ buf->c_birthtimensec = 0;
+ buf->c_atimensec = buf->c_mtimensec = 0;
+ }
+
case TS_ADDR:
break;

@@ -1057,13 +1078,16 @@
panic("gethead: unknown inode type %d\n", buf->c_type);
break;
}
+
+ buf->c_magic = FS_UFS2_MAGIC;
+
/*
- * If we are restoring a filesystem with old format inodes,
+ * 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_uid = buf->c_spare1[1];
+ buf->c_gid = buf->c_spare1[2];
}
if (dflag)
accthdr(buf);
@@ -1085,8 +1109,8 @@
fprintf(stderr, "Volume header (%s inode format) ",
oldinofmt ? "old" : "new");
if (header->c_firstrec)
- fprintf(stderr, "begins with record %d",
- header->c_firstrec);
+ fprintf(stderr, "begins with record %lld",
+ (long long)header->c_firstrec);
fprintf(stderr, "\n");
previno = 0x7fffffff;
return;
@@ -1150,10 +1174,10 @@

curfile.name = "<name unknown>";
curfile.action = UNKNOWN;
- curfile.dip = NULL;
+ curfile.mode = 0;
curfile.ino = 0;
do {
- if (header->c_magic != NFS_MAGIC) {
+ if (header->c_magic != FS_UFS2_MAGIC) {
skipcnt++;
while (gethead(header) == FAIL ||
header->c_date != dumpdate)
@@ -1174,7 +1198,18 @@
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.birthtime_sec = header->c_birthtime;
+ curfile.birthtime_nsec = header->c_birthtimensec;
+ curfile.size = header->c_size;
curfile.ino = header->c_inumber;
break;

@@ -1217,8 +1252,6 @@
i += *buf++;
while (--j);
} else {
- /* What happens if we want to read restore tapes
- for a 16bit int machine??? */
do
i += swap32(*buf++);
while (--j);
@@ -1250,36 +1283,68 @@
swap_header(struct s_spcl *s)
{
s->c_type = swap32(s->c_type);
- s->c_date = swap32(s->c_date);
- s->c_ddate = swap32(s->c_ddate);
+ s->c_old_date = swap32(s->c_old_date);
+ s->c_old_ddate = swap32(s->c_old_ddate);
s->c_volume = swap32(s->c_volume);
- s->c_tapea = swap32(s->c_tapea);
+ s->c_old_tapea = swap32(s->c_old_tapea);
s->c_inumber = swap32(s->c_inumber);
s->c_magic = swap32(s->c_magic);
s->c_checksum = swap32(s->c_checksum);

- s->c_dinode.di_mode = swap16(s->c_dinode.di_mode);
- s->c_dinode.di_nlink = swap16(s->c_dinode.di_nlink);
- s->c_dinode.di_ouid = swap16(s->c_dinode.di_ouid);
- s->c_dinode.di_ogid = swap16(s->c_dinode.di_ogid);
-
- s->c_dinode.di_size = swap64(s->c_dinode.di_size);
-
- s->c_dinode.di_atime = swap32(s->c_dinode.di_atime);
- s->c_dinode.di_atimensec = swap32(s->c_dinode.di_atimensec);
- s->c_dinode.di_mtime = swap32(s->c_dinode.di_mtime);
- s->c_dinode.di_mtimensec = swap32(s->c_dinode.di_mtimensec);
- s->c_dinode.di_ctime = swap32(s->c_dinode.di_ctime);
- s->c_dinode.di_ctimensec = swap32(s->c_dinode.di_ctimensec);
-
- s->c_dinode.di_flags = swap32(s->c_dinode.di_flags);
- s->c_dinode.di_blocks = swap32(s->c_dinode.di_blocks);
- s->c_dinode.di_gen = swap32(s->c_dinode.di_gen);
- s->c_dinode.di_uid = swap32(s->c_dinode.di_uid);
- s->c_dinode.di_gid = swap32(s->c_dinode.di_gid);
+ s->c_mode = swap16(s->c_mode);
+ s->c_size = swap64(s->c_size);
+ s->c_old_atime = swap32(s->c_old_atime);
+ s->c_atimensec = swap32(s->c_atimensec);
+ s->c_old_mtime = swap32(s->c_old_mtime);
+ s->c_mtimensec = swap32(s->c_mtimensec);
+ s->c_rdev = swap32(s->c_rdev);
+ s->c_birthtimensec = swap32(s->c_birthtimensec);
+ s->c_birthtime = swap64(s->c_birthtime);
+ s->c_atime = swap64(s->c_atime);
+ s->c_mtime = swap64(s->c_mtime);
+ s->c_file_flags = swap32(s->c_file_flags);
+ s->c_uid = swap32(s->c_uid);
+ s->c_gid = swap32(s->c_gid);

s->c_count = swap32(s->c_count);
s->c_level = swap32(s->c_level);
s->c_flags = swap32(s->c_flags);
- s->c_firstrec = swap32(s->c_firstrec);
+ s->c_old_firstrec = swap32(s->c_old_firstrec);
+
+ s->c_date = swap64(s->c_date);
+ s->c_ddate = swap64(s->c_ddate);
+ s->c_tapea = swap64(s->c_tapea);
+ s->c_firstrec = swap64(s->c_firstrec);
+
+ /*
+ * These are ouid and ogid.
+ */
+ s->c_spare1[1] = swap16(s->c_spare1[1]);
+ s->c_spare1[2] = swap16(s->c_spare1[2]);
+}
+
+static void
+swap_old_header(struct s_ospcl *os)
+{
+ os->c_type = swap32(os->c_type);
+ os->c_date = swap32(os->c_date);
+ os->c_ddate = swap32(os->c_ddate);
+ os->c_volume = swap32(os->c_volume);
+ os->c_tapea = swap32(os->c_tapea);
+ os->c_inumber = swap16(os->c_inumber);
+ os->c_magic = swap32(os->c_magic);
+ os->c_checksum = swap32(os->c_checksum);
+
+ os->c_odinode.odi_mode = swap16(os->c_odinode.odi_mode);
+ os->c_odinode.odi_nlink = swap16(os->c_odinode.odi_nlink);
+ os->c_odinode.odi_uid = swap16(os->c_odinode.odi_uid);
+ os->c_odinode.odi_gid = swap16(os->c_odinode.odi_gid);
+
+ os->c_odinode.odi_size = swap32(os->c_odinode.odi_size);
+ os->c_odinode.odi_rdev = swap32(os->c_odinode.odi_rdev);
+ os->c_odinode.odi_atime = swap32(os->c_odinode.odi_atime);
+ os->c_odinode.odi_mtime = swap32(os->c_odinode.odi_mtime);
+ os->c_odinode.odi_ctime = swap32(os->c_odinode.odi_ctime);
+
+ os->c_count = swap32(os->c_count);
}

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 08:49 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com