volser: use also vn_length_hi in dump size calculation
[openafs.git] / src / volser / dumpstuff.c
index e062100..0323922 100644 (file)
@@ -14,8 +14,9 @@
 
 #include <ctype.h>
 
-#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>
@@ -85,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];
@@ -162,7 +165,7 @@ iod_Write(struct iod *iodp, char *buf, int nbytes)
     int code, i;
     int one_success = 0;
 
-    osi_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) {
@@ -280,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();
@@ -294,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;
@@ -980,15 +986,15 @@ DumpVnodeIndex(struct iod *iodp, Volume * vp, VnodeClass class,
     int vnodeIndex;
 
     fdP = IH_OPEN(vp->vnodeIndex[class].handle);
-    osi_Assert(fdP != NULL);
+    opr_Assert(fdP != NULL);
     file = FDH_FDOPEN(fdP, "r+");
-    osi_Assert(file != NULL);
+    opr_Assert(file != NULL);
     size = OS_SIZE(fdP->fd_fd);
-    osi_Assert(size != -1);
+    opr_Assert(size != -1);
     nVnodes = (size / vcp->diskSize) - 1;
     if (nVnodes > 0) {
-       osi_Assert((nVnodes + 1) * vcp->diskSize == size);
-       osi_Assert(STREAM_ASEEK(file, vcp->diskSize) == 0);
+       opr_Assert((nVnodes + 1) * vcp->diskSize == size);
+       opr_Assert(STREAM_ASEEK(file, vcp->diskSize) == 0);
     } else
        nVnodes = 0;
     for (vnodeIndex = 0;
@@ -1079,6 +1085,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) {
@@ -1086,6 +1093,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);
@@ -1148,7 +1166,7 @@ ProcessIndex(Volume * vp, VnodeClass class, afs_foff_t ** Bufp, int *sizep,
        OS_SYNC(afile->str_fd);
     } else {
        size = OS_SIZE(fdP->fd_fd);
-       osi_Assert(size != -1);
+       opr_Assert(size != -1);
        nVnodes =
            (size <=
             vcp->diskSize ? 0 : size - vcp->diskSize) >> vcp->logSize;
@@ -1401,20 +1419,20 @@ 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",
@@ -1528,7 +1546,7 @@ volser_WriteFile(int vn, struct iod *iodp, FdHandle_t * handleP, int tag,
        }
        FillInt64(filesize, filesize_high, filesize_low);
     }
-    p = (unsigned char *)malloc(size);
+    p = malloc(size);
     if (p == NULL) {
        *status = 2;
        return (0);
@@ -1818,7 +1836,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;
@@ -1858,15 +1880,15 @@ SizeDumpVnodeIndex(struct iod *iodp, Volume * vp, VnodeClass class,
     int vnodeIndex;
 
     fdP = IH_OPEN(vp->vnodeIndex[class].handle);
-    osi_Assert(fdP != NULL);
+    opr_Assert(fdP != NULL);
     file = FDH_FDOPEN(fdP, "r+");
-    osi_Assert(file != NULL);
+    opr_Assert(file != NULL);
     size = OS_SIZE(fdP->fd_fd);
-    osi_Assert(size != -1);
+    opr_Assert(size != -1);
     nVnodes = (size / vcp->diskSize) - 1;
     if (nVnodes > 0) {
-       osi_Assert((nVnodes + 1) * vcp->diskSize == size);
-       osi_Assert(STREAM_ASEEK(file, vcp->diskSize) == 0);
+       opr_Assert((nVnodes + 1) * vcp->diskSize == size);
+       opr_Assert(STREAM_ASEEK(file, vcp->diskSize) == 0);
     } else
        nVnodes = 0;
     for (vnodeIndex = 0;