Handle backupDate of zero
[openafs.git] / src / volser / dumpstuff.c
index 732a3f6..21ed803 100644 (file)
 #include <afsconfig.h>
 #include <afs/param.h>
 
+#include <roken.h>
 
-#include <sys/types.h>
 #include <ctype.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#ifdef AFS_NT40_ENV
-#include <fcntl.h>
-#else
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/uio.h>
-#include <netinet/in.h>
-#include <unistd.h>
-#endif
-#include <sys/stat.h>
-#ifdef AFS_PTHREAD_ENV
-#include <assert.h>
-#else /* AFS_PTHREAD_ENV */
-#include <afs/assert.h>
-#endif /* AFS_PTHREAD_ENV */
-#include <rx/xdr.h>
+
+#include <afs/opr.h>
 #include <rx/rx.h>
+#include <rx/rx_queue.h>
 #include <afs/afsint.h>
 #include <afs/nfs.h>
 #include <afs/errors.h>
 #include <afs/vnode.h>
 #include <afs/volume.h>
 #include <afs/partition.h>
-#include "dump.h"
 #include <afs/daemon_com.h>
 #include <afs/fssync.h>
 #include <afs/acl.h>
 #include <afs/com_err.h>
 #include <afs/vol_prototypes.h>
+
+#include "dump.h"
 #include "volser.h"
 #include "volint.h"
 #include "dumpstuff.h"
@@ -65,6 +50,7 @@
 /*@printflike@*/ extern void Log(const char *format, ...);
 
 extern int DoLogging;
+extern int DoPreserveVolumeStats;
 
 
 /* Forward Declarations */
@@ -79,7 +65,7 @@ static int DumpVnode(struct iod *iodp, struct VnodeDiskObject *v,
                     int volid, int vnodeNumber, int dumpEverything);
 static int ReadDumpHeader(struct iod *iodp, struct DumpHeader *hp);
 static int ReadVnodes(struct iod *iodp, Volume * vp, int incremental,
-                     afs_int32 * Lbuf, afs_int32 s1, afs_int32 * Sbuf,
+                     afs_foff_t * Lbuf, afs_int32 s1, afs_foff_t * Sbuf,
                      afs_int32 s2, afs_int32 delo);
 static afs_fsize_t volser_WriteFile(int vn, struct iod *iodp,
                                    FdHandle_t * handleP, int tag,
@@ -100,7 +86,9 @@ static int SizeDumpVnode(struct iod *iodp, struct VnodeDiskObject *v,
                         struct volintSize *size);
 
 #define MAX_SECTIONS    3
-#define MIN_TLV_TAG     5
+
+/* The TLV range must start above D_MAX */
+#define MIN_TLV_TAG     21
 #define MAX_TLV_TAG     0x60
 #define MAX_STANDARD_TAG 0x7a
 static afs_uint32 oldtags[MAX_SECTIONS][16];
@@ -177,7 +165,7 @@ iod_Write(struct iod *iodp, char *buf, int nbytes)
     int code, i;
     int one_success = 0;
 
-    assert((iodp->call && iodp->ncalls == 1 && !iodp->calls)
+    opr_Assert((iodp->call && iodp->ncalls == 1 && !iodp->calls)
           || (!iodp->call && iodp->ncalls >= 1 && iodp->calls));
 
     if (iodp->call) {
@@ -295,7 +283,8 @@ ReadStandardTagLen(struct iod *iodp, unsigned char tag, afs_int32 section,
     afs_int32 code, i;
     afs_uint32 off = tag >> 5;
     afs_uint32 mask = 1 << (tag & 0x1f);
-    unsigned char len, buf[8], *p;
+    int len;
+    unsigned char buf[8], *p;
 
     if (!oldtagsInited)
         initNonStandardTags();
@@ -309,7 +298,9 @@ ReadStandardTagLen(struct iod *iodp, unsigned char tag, afs_int32 section,
     }
     if (tag <= MAX_TLV_TAG) {
         len = iod_getc(iodp);
-        if (len < 128)
+       if (len == EOF)
+           return VOLSERDUMPERROR;
+       else if (len < 128)
             *length = len;
         else {
             len &= 0x7f;
@@ -545,8 +536,8 @@ DumpByte(struct iod *iodp, char tag, byte value)
     return ((iod_Write(iodp, tbuffer, 2) == 2) ? 0 : VOLSERDUMPERROR);
 }
 
-#define putint32(p, v)  *p++ = v>>24, *p++ = v>>16, *p++ = v>>8, *p++ = v
-#define putshort(p, v) *p++ = v>>8, *p++ = v
+#define afs_putint32(p, v)  *p++ = v>>24, *p++ = v>>16, *p++ = v>>8, *p++ = v
+#define afs_putshort(p, v) *p++ = v>>8, *p++ = v
 
 static int
 DumpDouble(struct iod *iodp, char tag, afs_uint32 value1,
@@ -555,8 +546,8 @@ DumpDouble(struct iod *iodp, char tag, afs_uint32 value1,
     char tbuffer[9];
     byte *p = (unsigned char *)tbuffer;
     *p++ = tag;
-    putint32(p, value1);
-    putint32(p, value2);
+    afs_putint32(p, value1);
+    afs_putint32(p, value2);
     return ((iod_Write(iodp, tbuffer, 9) == 9) ? 0 : VOLSERDUMPERROR);
 }
 
@@ -566,7 +557,7 @@ DumpInt32(struct iod *iodp, char tag, afs_uint32 value)
     char tbuffer[5];
     byte *p = (unsigned char *)tbuffer;
     *p++ = tag;
-    putint32(p, value);
+    afs_putint32(p, value);
     return ((iod_Write(iodp, tbuffer, 5) == 5) ? 0 : VOLSERDUMPERROR);
 }
 
@@ -579,7 +570,7 @@ DumpArrayInt32(struct iod *iodp, char tag,
     int code = 0;
     byte *p = (unsigned char *)tbuffer;
     *p++ = tag;
-    putshort(p, nelem);
+    afs_putshort(p, nelem);
     code = iod_Write(iodp, tbuffer, 3);
     if (code != 3)
        return VOLSERDUMPERROR;
@@ -587,7 +578,7 @@ DumpArrayInt32(struct iod *iodp, char tag,
        p = (unsigned char *)tbuffer;
        v = *array++;           /*this was register */
 
-       putint32(p, v);
+       afs_putint32(p, v);
        code = iod_Write(iodp, tbuffer, 4);
        if (code != 4)
            return VOLSERDUMPERROR;
@@ -664,6 +655,8 @@ DumpStandardTag(struct iod *iodp, char tag, afs_uint32 section)
         return VOLSERDUMPERROR;
     }
     code = iod_Write(iodp, &tag, 1);
+    if (code != 1)
+       return VOLSERDUMPERROR;
     return 0;
 }
 
@@ -707,18 +700,19 @@ DumpFile(struct iod *iodp, int vnode, FdHandle_t * handleP)
 {
     int code = 0, error = 0;
     afs_int32 pad = 0;
-    afs_int32 offset = 0;
+    afs_foff_t offset = 0;
     afs_sfsize_t nbytes, howBig;
     ssize_t n;
     size_t howMany;
-    afs_foff_t lcode = 0;
+    afs_foff_t howFar = 0;
     byte *p;
     afs_uint32 hi, lo;
     afs_ino_str_t stmp;
 #ifndef AFS_NT40_ENV
     struct afs_stat status;
+#else
+    LARGE_INTEGER fileSize;
 #endif
-    afs_sfsize_t size;
 #ifdef AFS_AIX_ENV
 #include <sys/statfs.h>
 #if defined(AFS_AIX52_ENV)
@@ -730,7 +724,11 @@ DumpFile(struct iod *iodp, int vnode, FdHandle_t * handleP)
 #endif
 
 #ifdef AFS_NT40_ENV
-    howBig = _filelength(handleP->fd_fd);
+    if (!GetFileSizeEx(handleP->fd_fd, &fileSize)) {
+        Log("DumpFile: GetFileSizeEx returned error code %d on descriptor %d\n", GetLastError(), handleP->fd_fd);
+           return VOLSERDUMPERROR;
+    }
+    howBig = fileSize.QuadPart;
     howMany = 4096;
 
 #else
@@ -757,8 +755,7 @@ DumpFile(struct iod *iodp, int vnode, FdHandle_t * handleP)
 #endif /* AFS_NT40_ENV */
 
 
-    size = FDH_SIZE(handleP);
-    SplitInt64(size, hi, lo);
+    SplitInt64(howBig, hi, lo);
     if (hi == 0L) {
        code = DumpInt32(iodp, 'f', lo);
     } else {
@@ -774,18 +771,19 @@ DumpFile(struct iod *iodp, int vnode, FdHandle_t * handleP)
        return VOLSERDUMPERROR;
     }
 
-    for (nbytes = size; (nbytes && !error); nbytes -= howMany) {
+    for (nbytes = howBig; (nbytes && !error); nbytes -= howMany) {
        if (nbytes < howMany)
            howMany = nbytes;
 
-       /* Read the data - unless we know we can't */
-       n = (lcode ? 0 : FDH_READ(handleP, p, howMany));
+       /* Read the data */
+       n = FDH_PREAD(handleP, p, howMany, howFar);
+       howFar += n;
 
        /* If read any good data and we null padded previously, log the
         * amount that we had null padded.
         */
        if ((n > 0) && pad) {
-           Log("1 Volser: DumpFile: Null padding file %d bytes at offset %u\n", pad, offset);
+           Log("1 Volser: DumpFile: Null padding file %d bytes at offset %lld\n", pad, (long long)offset);
            pad = 0;
        }
 
@@ -813,17 +811,7 @@ DumpFile(struct iod *iodp, int vnode, FdHandle_t * handleP)
            /* Now seek over the data we could not get. An error here means we
             * can't do the next read.
             */
-           lcode = FDH_SEEK(handleP, (size_t)((size - nbytes) + howMany), SEEK_SET);
-           if (lcode != ((size - nbytes) + howMany)) {
-               if (lcode < 0) {
-                   Log("1 Volser: DumpFile: Error seeking in inode %s for vnode %d: %s\n", PrintInode(NULL, handleP->fd_ih->ih_ino), vnode, afs_error_message(errno));
-               } else {
-                   Log("1 Volser: DumpFile: Error seeking in inode %s for vnode %d\n", PrintInode(NULL, handleP->fd_ih->ih_ino), vnode);
-                   lcode = -1;
-               }
-           } else {
-               lcode = 0;
-           }
+           howFar = (size_t)((howBig - nbytes) + howMany);
        }
 
        /* Now write the data out */
@@ -835,8 +823,8 @@ DumpFile(struct iod *iodp, int vnode, FdHandle_t * handleP)
     }
 
     if (pad) {                 /* Any padding we hadn't reported yet */
-       Log("1 Volser: DumpFile: Null padding file: %d bytes at offset %u\n",
-           pad, offset);
+       Log("1 Volser: DumpFile: Null padding file: %d bytes at offset %lld\n",
+           pad, (long long)offset);
     }
 
     free(p);
@@ -998,15 +986,15 @@ DumpVnodeIndex(struct iod *iodp, Volume * vp, VnodeClass class,
     int vnodeIndex;
 
     fdP = IH_OPEN(vp->vnodeIndex[class].handle);
-    assert(fdP != NULL);
+    opr_Assert(fdP != NULL);
     file = FDH_FDOPEN(fdP, "r+");
-    assert(file != NULL);
+    opr_Assert(file != NULL);
     size = OS_SIZE(fdP->fd_fd);
-    assert(size != -1);
+    opr_Assert(size != -1);
     nVnodes = (size / vcp->diskSize) - 1;
     if (nVnodes > 0) {
-       assert((nVnodes + 1) * vcp->diskSize == size);
-       assert(STREAM_SEEK(file, vcp->diskSize, 0) == 0);
+       opr_Assert((nVnodes + 1) * vcp->diskSize == size);
+       opr_Assert(STREAM_ASEEK(file, vcp->diskSize) == 0);
     } else
        nVnodes = 0;
     for (vnodeIndex = 0;
@@ -1049,7 +1037,21 @@ DumpDumpHeader(struct iod *iodp, Volume * vp,
     if (!code)
        code = DumpString(iodp, 'n', V_name(vp));
     dumpTimes[0] = fromtime;
-    dumpTimes[1] = V_backupDate(vp);   /* Until the time the clone was made */
+    switch (V_type(vp)) {
+    case readwriteVolume:
+       dumpTimes[1] = V_updateDate(vp);        /* until last update */
+       break;
+    case readonlyVolume:
+       dumpTimes[1] = V_creationDate(vp);      /* until clone was updated */
+       break;
+    case backupVolume:
+       /* until backup was made */
+       dumpTimes[1] = V_backupDate(vp) != 0 ? V_backupDate(vp) :
+                                              V_creationDate(vp);
+       break;
+    default:
+       code = EINVAL;
+    }
     if (!code)
        code = DumpArrayInt32(iodp, 't', (afs_uint32 *) dumpTimes, 2);
     return code;
@@ -1097,6 +1099,7 @@ DumpVnode(struct iod *iodp, struct VnodeDiskObject *v, int volid,
                               VAclDiskSize(v));
     }
     if (VNDISK_GET_INO(v)) {
+       afs_sfsize_t indexlen, disklen;
        IH_INIT(ihP, iodp->device, iodp->parentId, VNDISK_GET_INO(v));
        fdP = IH_OPEN(ihP);
        if (fdP == NULL) {
@@ -1104,6 +1107,17 @@ DumpVnode(struct iod *iodp, struct VnodeDiskObject *v, int volid,
            IH_RELEASE(ihP);
            return VOLSERREAD_DUMPERROR;
        }
+       VNDISK_GET_LEN(indexlen, v);
+       disklen = FDH_SIZE(fdP);
+       if (indexlen != disklen) {
+           FDH_REALLYCLOSE(fdP);
+           IH_RELEASE(ihP);
+           Log("DumpVnode: volume %lu vnode %lu has inconsistent length "
+               "(index %lu disk %lu); aborting dump\n",
+               (unsigned long)volid, (unsigned long)vnodeNumber,
+               (unsigned long)indexlen, (unsigned long)disklen);
+           return VOLSERREAD_DUMPERROR;
+       }
        code = DumpFile(iodp, vnodeNumber, fdP);
        FDH_CLOSE(fdP);
        IH_RELEASE(ihP);
@@ -1113,11 +1127,12 @@ DumpVnode(struct iod *iodp, struct VnodeDiskObject *v, int volid,
 
 
 int
-ProcessIndex(Volume * vp, VnodeClass class, afs_int32 ** Bufp, int *sizep,
+ProcessIndex(Volume * vp, VnodeClass class, afs_foff_t ** Bufp, int *sizep,
             int del)
 {
-    int i, nVnodes, offset, code;
-    afs_int32 *Buf;
+    int i, nVnodes, code;
+    afs_foff_t offset;
+    afs_foff_t *Buf;
     int cnt = 0;
     afs_sfsize_t size;
     StreamHandle_t *afile;
@@ -1137,7 +1152,7 @@ ProcessIndex(Volume * vp, VnodeClass class, afs_int32 ** Bufp, int *sizep,
        for (i = 0; i < *sizep; i++) {
            if (Buf[i]) {
                cnt++;
-               STREAM_SEEK(afile, Buf[i], 0);
+               STREAM_ASEEK(afile, Buf[i]);
                code = STREAM_READ(vnode, vcp->diskSize, 1, afile);
                if (code == 1) {
                    if (vnode->type != vNull && VNDISK_GET_INO(vnode)) {
@@ -1151,7 +1166,7 @@ ProcessIndex(Volume * vp, VnodeClass class, afs_int32 ** Bufp, int *sizep,
                               V_parentId(vp));
                        DOPOLL;
                    }
-                   STREAM_SEEK(afile, Buf[i], 0);
+                   STREAM_ASEEK(afile, Buf[i]);
                    (void)STREAM_WRITE(zero, vcp->diskSize, 1, afile);  /* Zero it out */
                }
                Buf[i] = 0;
@@ -1165,23 +1180,18 @@ ProcessIndex(Volume * vp, VnodeClass class, afs_int32 ** Bufp, int *sizep,
        OS_SYNC(afile->str_fd);
     } else {
        size = OS_SIZE(fdP->fd_fd);
-       assert(size != -1);
+       opr_Assert(size != -1);
        nVnodes =
            (size <=
             vcp->diskSize ? 0 : size - vcp->diskSize) >> vcp->logSize;
        if (nVnodes > 0) {
-           if (DoLogging) {
-               Log("RestoreVolume ProcessIndex: Set up %d inodes for volume %d\n",
-                   nVnodes, V_id(vp));
-           }
-           Buf = (afs_int32 *) malloc(nVnodes * sizeof(afs_int32));
+           Buf = calloc(nVnodes,  sizeof(afs_foff_t));
            if (Buf == NULL) {
                STREAM_CLOSE(afile);
                FDH_CLOSE(fdP);
                return -1;
            }
-           memset(Buf, 0, nVnodes * sizeof(afs_int32));
-           STREAM_SEEK(afile, offset = vcp->diskSize, 0);
+           STREAM_ASEEK(afile, offset = vcp->diskSize);
            while (1) {
                code = STREAM_READ(vnode, vcp->diskSize, 1, afile);
                if (code != 1) {
@@ -1193,9 +1203,6 @@ ProcessIndex(Volume * vp, VnodeClass class, afs_int32 ** Bufp, int *sizep,
                }
                offset += vcp->diskSize;
            }
-           if (DoLogging) {
-               Log("RestoreVolume ProcessIndex: found %d inodes\n", cnt);
-           }
            *Bufp = Buf;
            *sizep = nVnodes;
        }
@@ -1217,14 +1224,19 @@ RestoreVolume(struct rx_call *call, Volume * avp, int incremental,
     Volume *vp;
     struct iod iod;
     struct iod *iodp = &iod;
-    afs_int32 *b1 = NULL, *b2 = NULL;
+    afs_foff_t *b1 = NULL, *b2 = NULL;
     int s1 = 0, s2 = 0, delo = 0, tdelo;
     int tag;
+    VolumeDiskData saved_header;
 
     iod_Init(iodp, call);
 
     vp = avp;
 
+    if (DoPreserveVolumeStats) {
+       CopyVolumeStats(&V_disk(vp), &saved_header);
+    }
+
     if (!ReadDumpHeader(iodp, &header)) {
        Log("1 Volser: RestoreVolume: Error reading header file for dump; aborted\n");
        return VOLSERREAD_DUMPERROR;
@@ -1251,6 +1263,8 @@ RestoreVolume(struct rx_call *call, Volume * avp, int incremental,
     vol.cloneId = cookie->clone;
     vol.parentId = cookie->parent;
 
+    V_needsSalvaged(vp) = 0;
+
     tdelo = delo;
     while (1) {
        if (ReadVnodes(iodp, vp, 0, b1, s1, b2, s2, tdelo)) {
@@ -1291,7 +1305,16 @@ RestoreVolume(struct rx_call *call, Volume * avp, int incremental,
     }
 
   clean:
-    ClearVolumeStats(&vol);
+    if (DoPreserveVolumeStats) {
+       CopyVolumeStats(&saved_header, &vol);
+    } else {
+       ClearVolumeStats(&vol);
+    }
+    if (V_needsSalvaged(vp)) {
+       /* needsSalvaged may have been set while we tried to write volume data.
+        * prevent it from getting overwritten. */
+       vol.needsSalvaged = V_needsSalvaged(vp);
+    }
     CopyVolumeHeader(&vol, &V_disk(vp));
     V_destroyMe(vp) = 0;
     VUpdateVolume(&vupdate, vp);
@@ -1303,15 +1326,15 @@ RestoreVolume(struct rx_call *call, Volume * avp, int incremental,
   out:
     /* Free the malloced space above */
     if (b1)
-       free((char *)b1);
+       free(b1);
     if (b2)
-       free((char *)b2);
+       free(b2);
     return error;
 }
 
 static int
 ReadVnodes(struct iod *iodp, Volume * vp, int incremental,
-          afs_int32 * Lbuf, afs_int32 s1, afs_int32 * Sbuf, afs_int32 s2,
+          afs_foff_t * Lbuf, afs_int32 s1, afs_foff_t * Sbuf, afs_int32 s2,
           afs_int32 delo)
 {
     afs_int32 vnodeNumber;
@@ -1324,7 +1347,7 @@ ReadVnodes(struct iod *iodp, Volume * vp, int incremental,
     struct VnodeClassInfo *vcp;
     IHandle_t *tmpH;
     FdHandle_t *fdP;
-    Inode nearInode;
+    Inode nearInode AFS_UNUSED;
     afs_int32 critical = 0;
 
     tag = iod_getc(iodp);
@@ -1339,9 +1362,6 @@ ReadVnodes(struct iod *iodp, Volume * vp, int incremental,
        if (!ReadInt32(iodp, &vnode->uniquifier))
            return VOLSERREAD_DUMPERROR;
 
-       if (DoLogging) {
-           Log("ReadVnodes: setup %d/%d\n", vnodeNumber, vnode->uniquifier);
-       }
        while ((tag = iod_getc(iodp)) > D_MAX && tag != EOF) {
            haveStuff = 1;
             if (critical)
@@ -1413,24 +1433,26 @@ ReadVnodes(struct iod *iodp, Volume * vp, int incremental,
                    }
                    saw_f = 1;
 
-                   ino =
-                       IH_CREATE(V_linkHandle(vp), V_device(vp),
+                   tmpH =
+                       IH_CREATE_INIT(V_linkHandle(vp), V_device(vp),
                                  VPartitionPath(V_partition(vp)), nearInode,
                                  V_parentId(vp), vnodeNumber,
                                  vnode->uniquifier, vnode->dataVersion);
-                   if (!VALID_INO(ino)) {
+                   if (!tmpH) {
                        Log("1 Volser: ReadVnodes: IH_CREATE: %s - restore aborted\n",
                             afs_error_message(errno));
+                       V_needsSalvaged(vp) = 1;
                        return VOLSERREAD_DUMPERROR;
                    }
+                   ino = tmpH->ih_ino;
                    nearInode = ino;
                    VNDISK_SET_INO(vnode, ino);
-                   IH_INIT(tmpH, vp->device, V_parentId(vp), ino);
                    fdP = IH_OPEN(tmpH);
                    if (fdP == NULL) {
                        Log("1 Volser: ReadVnodes: IH_OPEN: %s - restore aborted\n",
                             afs_error_message(errno));
                        IH_RELEASE(tmpH);
+                       V_needsSalvaged(vp) = 1;
                        return VOLSERREAD_DUMPERROR;
                    }
                    vnodeLength =
@@ -1442,6 +1464,7 @@ ReadVnodes(struct iod *iodp, Volume * vp, int incremental,
                        Log("1 Volser: ReadVnodes: IDEC inode %llu\n",
                            (afs_uintmax_t) ino);
                        IH_DEC(V_linkHandle(vp), ino, V_parentId(vp));
+                       V_needsSalvaged(vp) = 1;
                        return VOLSERREAD_DUMPERROR;
                    }
                    break;
@@ -1475,16 +1498,10 @@ ReadVnodes(struct iod *iodp, Volume * vp, int incremental,
            if (fdP == NULL) {
                Log("1 Volser: ReadVnodes: Error opening vnode index: %s; restore aborted\n",
                    afs_error_message(errno));
+               V_needsSalvaged(vp) = 1;
                return VOLSERREAD_DUMPERROR;
            }
-           if (FDH_SEEK(fdP, vnodeIndexOffset(vcp, vnodeNumber), SEEK_SET) <
-               0) {
-               Log("1 Volser: ReadVnodes: Error seeking into vnode index: %s; restore aborted\n",
-                   afs_error_message(errno));
-               FDH_REALLYCLOSE(fdP);
-               return VOLSERREAD_DUMPERROR;
-           }
-           if (FDH_READ(fdP, &oldvnode, sizeof(oldvnode)) ==
+           if (FDH_PREAD(fdP, &oldvnode, sizeof(oldvnode), vnodeIndexOffset(vcp, vnodeNumber)) ==
                sizeof(oldvnode)) {
                if (oldvnode.type != vNull && VNDISK_GET_INO(&oldvnode)) {
                    IH_DEC(V_linkHandle(vp), VNDISK_GET_INO(&oldvnode),
@@ -1492,17 +1509,11 @@ ReadVnodes(struct iod *iodp, Volume * vp, int incremental,
                }
            }
            vnode->vnodeMagic = vcp->magic;
-           if (FDH_SEEK(fdP, vnodeIndexOffset(vcp, vnodeNumber), SEEK_SET) <
-               0) {
-               Log("1 Volser: ReadVnodes: Error seeking into vnode index: %s; restore aborted\n",
-                   afs_error_message(errno));
-               FDH_REALLYCLOSE(fdP);
-               return VOLSERREAD_DUMPERROR;
-           }
-           if (FDH_WRITE(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
+           if (FDH_PWRITE(fdP, vnode, vcp->diskSize, vnodeIndexOffset(vcp, vnodeNumber)) != vcp->diskSize) {
                Log("1 Volser: ReadVnodes: Error writing vnode index: %s; restore aborted\n",
                    afs_error_message(errno));
                FDH_REALLYCLOSE(fdP);
+               V_needsSalvaged(vp) = 1;
                return VOLSERREAD_DUMPERROR;
            }
            FDH_CLOSE(fdP);
@@ -1535,7 +1546,6 @@ volser_WriteFile(int vn, struct iod *iodp, FdHandle_t * handleP, int tag,
 
 
     *status = 0;
-#ifdef AFS_64BIT_ENV
     {
        afs_uint32 filesize_high = 0L, filesize_low = 0L;
        if (tag == 'h') {
@@ -1550,13 +1560,7 @@ volser_WriteFile(int vn, struct iod *iodp, FdHandle_t * handleP, int tag,
        }
        FillInt64(filesize, filesize_high, filesize_low);
     }
-#else /* !AFS_64BIT_ENV */
-    if (!ReadInt32(iodp, &filesize)) {
-       *status = 1;
-       return (0);
-    }
-#endif /* !AFS_64BIT_ENV */
-    p = (unsigned char *)malloc(size);
+    p = malloc(size);
     if (p == NULL) {
        *status = 2;
        return (0);
@@ -1571,7 +1575,7 @@ volser_WriteFile(int vn, struct iod *iodp, FdHandle_t * handleP, int tag,
            break;
        }
        if (handleP) {
-           nBytes = FDH_WRITE(handleP, p, size);
+           nBytes = FDH_PWRITE(handleP, p, size, written);
            if (nBytes > 0)
                written += nBytes;
            if (nBytes != size) {
@@ -1846,7 +1850,11 @@ SizeDumpVnode(struct iod *iodp, struct VnodeDiskObject *v, int volid,
     }
 
     if (VNDISK_GET_INO(v)) {
-       FillInt64(addvar,0, (v->length + 5));
+       VNDISK_GET_LEN(addvar, v);
+       if (v->vn_length_hi)
+           addvar += 9;
+       else
+           addvar += 5;
        AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
     }
     return code;
@@ -1886,15 +1894,15 @@ SizeDumpVnodeIndex(struct iod *iodp, Volume * vp, VnodeClass class,
     int vnodeIndex;
 
     fdP = IH_OPEN(vp->vnodeIndex[class].handle);
-    assert(fdP != NULL);
+    opr_Assert(fdP != NULL);
     file = FDH_FDOPEN(fdP, "r+");
-    assert(file != NULL);
+    opr_Assert(file != NULL);
     size = OS_SIZE(fdP->fd_fd);
-    assert(size != -1);
+    opr_Assert(size != -1);
     nVnodes = (size / vcp->diskSize) - 1;
     if (nVnodes > 0) {
-       assert((nVnodes + 1) * vcp->diskSize == size);
-       assert(STREAM_SEEK(file, vcp->diskSize, 0) == 0);
+       opr_Assert((nVnodes + 1) * vcp->diskSize == size);
+       opr_Assert(STREAM_ASEEK(file, vcp->diskSize) == 0);
     } else
        nVnodes = 0;
     for (vnodeIndex = 0;