volser: preserve stats over reclones and restores
[openafs.git] / src / vol / vutil.c
index 396832d..007b1ec 100644 (file)
@@ -27,8 +27,6 @@
 #include <sys/lockf.h>
 #endif
 
-#include <afs/afs_assert.h>
-
 #include <rx/xdr.h>
 #include <afs/afsint.h>
 #include "nfs.h"
@@ -69,7 +67,8 @@
 
 #ifdef FSSYNC_BUILD_CLIENT
 static void
-RemoveInodes(struct afs_inode_info *stuff, Device dev, VolumeId vid)
+RemoveInodes(struct afs_inode_info *stuff, Device dev, VolumeId parent,
+             VolumeId vid)
 {
     int i;
     IHandle_t *handle;
@@ -77,11 +76,16 @@ RemoveInodes(struct afs_inode_info *stuff, Device dev, VolumeId vid)
     /* This relies on the fact that IDEC only needs the device and NT only
      * needs the dev and vid to decrement volume special files.
      */
-    IH_INIT(handle, dev, vid, -1);
+    IH_INIT(handle, dev, parent, -1);
     for (i = 0; i < MAXINODETYPE; i++) {
        Inode inode = *stuff[i].inode;
-       if (VALID_INO(inode))
-           IH_DEC(handle, inode, vid);
+       if (VALID_INO(inode)) {
+           if (stuff[i].inodeType == VI_LINKTABLE) {
+               IH_DEC(handle, inode, parent);
+           } else {
+               IH_DEC(handle, inode, vid);
+           }
+       }
     }
     IH_RELEASE(handle);
 }
@@ -109,7 +113,7 @@ VCreateVolume_r(Error * ec, char *partname, VolId volumeId, VolId parentId)
     struct VolumeDiskHeader diskHeader;
     IHandle_t *handle;
     FdHandle_t *fdP;
-    Inode nearInode = 0;
+    Inode nearInode AFS_UNUSED = 0;
     char *part, *name;
     struct stat st;
     struct VolumeHeader tempHeader;
@@ -239,7 +243,7 @@ VCreateVolume_r(Error * ec, char *partname, VolId volumeId, VolId parentId)
          bad:
            if (handle)
                IH_RELEASE(handle);
-           RemoveInodes(stuff, device, vol.id);
+           RemoveInodes(stuff, device, vol.parentId, vol.id);
            if (!*ec) {
                *ec = VNOVOL;
            }
@@ -382,6 +386,34 @@ ClearVolumeStats_r(VolumeDiskData * vol)
     vol->dayUseDate = 0;
 }
 
+void
+CopyVolumeStats_r(VolumeDiskData * from, VolumeDiskData * to)
+{
+    memcpy(to->weekUse, from->weekUse, sizeof(to->weekUse));
+    to->dayUse = from->dayUse;
+    to->dayUseDate = from->dayUseDate;
+    if (from->stat_initialized) {
+       memcpy(to->stat_reads, from->stat_reads, sizeof(to->stat_reads));
+       memcpy(to->stat_writes, from->stat_writes, sizeof(to->stat_writes));
+       memcpy(to->stat_fileSameAuthor, from->stat_fileSameAuthor,
+              sizeof(to->stat_fileSameAuthor));
+       memcpy(to->stat_fileDiffAuthor, from->stat_fileDiffAuthor,
+              sizeof(to->stat_fileDiffAuthor));
+       memcpy(to->stat_dirSameAuthor, from->stat_dirSameAuthor,
+              sizeof(to->stat_dirSameAuthor));
+       memcpy(to->stat_dirDiffAuthor, from->stat_dirDiffAuthor,
+              sizeof(to->stat_dirDiffAuthor));
+    }
+}
+
+void
+CopyVolumeStats(VolumeDiskData * from, VolumeDiskData * to)
+{
+    VOL_LOCK;
+    CopyVolumeStats_r(from, to);
+    VOL_UNLOCK;
+}
+
 /**
  * read an existing volume disk header.
  *