volser: preserve stats over reclones and restores
[openafs.git] / src / volser / dumpstuff.c
index 1d48936..91f725c 100644 (file)
@@ -14,7 +14,6 @@
 
 #include <ctype.h>
 
-#include <afs/afs_assert.h>
 #include <rx/xdr.h>
 #include <rx/rx.h>
 #include <afs/afsint.h>
@@ -50,6 +49,7 @@
 /*@printflike@*/ extern void Log(const char *format, ...);
 
 extern int DoLogging;
+extern int DoPreserveVolumeStats;
 
 
 /* Forward Declarations */
@@ -704,8 +704,9 @@ DumpFile(struct iod *iodp, int vnode, FdHandle_t * handleP)
     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)
@@ -717,7 +718,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
@@ -744,8 +749,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 {
@@ -761,7 +765,7 @@ 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;
 
@@ -801,7 +805,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.
             */
-           howFar = (size_t)((size - nbytes) + howMany);
+           howFar = (size_t)((howBig - nbytes) + howMany);
        }
 
        /* Now write the data out */
@@ -1149,10 +1153,6 @@ ProcessIndex(Volume * vp, VnodeClass class, afs_foff_t ** Bufp, int *sizep,
            (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 = malloc(nVnodes * sizeof(afs_foff_t));
            if (Buf == NULL) {
                STREAM_CLOSE(afile);
@@ -1172,9 +1172,6 @@ ProcessIndex(Volume * vp, VnodeClass class, afs_foff_t ** Bufp, int *sizep,
                }
                offset += vcp->diskSize;
            }
-           if (DoLogging) {
-               Log("RestoreVolume ProcessIndex: found %d inodes\n", cnt);
-           }
            *Bufp = Buf;
            *sizep = nVnodes;
        }
@@ -1199,11 +1196,16 @@ RestoreVolume(struct rx_call *call, Volume * avp, int incremental,
     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;
@@ -1230,6 +1232,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)) {
@@ -1270,7 +1274,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,7 +1316,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);
@@ -1318,9 +1331,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)