add-volupdate-counter-20051015
authorErvin Fenyak <efenyak@gamax.hu>
Sun, 23 Oct 2005 20:05:40 +0000 (20:05 +0000)
committerDerrick Brashear <shadow@dementia.org>
Sun, 23 Oct 2005 20:05:40 +0000 (20:05 +0000)
FIXES 18349

add a volume update counter. danger will robinson. see ticket for details.

====================
This delta was composed from multiple commits as part of the CVS->Git migration.
The checkin message with each commit was inconsistent.
The following are the additional commit messages.
====================

add configure gunk

====================

add configure gunk

====================

make this happy in libadmin on e.g. solaris

====================

make this work on Windows

16 files changed:
acinclude.m4
src/libadmin/test/vos.c
src/libadmin/vos/afs_vosAdmin.c
src/libadmin/vos/afs_vosAdmin.h
src/libadmin/vos/vosadmin.def
src/libadmin/vos/vsprocs.c
src/libadmin/vos/vsprocs.h
src/vol/vnode.c
src/vol/vol-info.c
src/vol/volume.h
src/volser/dumpstuff.c
src/volser/restorevol.c
src/volser/vol-dump.c
src/volser/volint.xg
src/volser/volprocs.c
src/volser/vos.c

index ebaa0b5..662cb6b 100644 (file)
@@ -979,7 +979,7 @@ AC_CHECK_HEADERS(netinet/in.h netdb.h sys/fcntl.h sys/mnttab.h sys/mntent.h)
 AC_CHECK_HEADERS(mntent.h sys/vfs.h sys/param.h sys/fs_types.h sys/fstyp.h)
 AC_CHECK_HEADERS(sys/mount.h strings.h termios.h signal.h)
 AC_CHECK_HEADERS(windows.h malloc.h winsock2.h direct.h io.h sys/user.h)
-AC_CHECK_HEADERS(security/pam_modules.h siad.h usersec.h ucontext.h regex.h)
+AC_CHECK_HEADERS(security/pam_modules.h siad.h usersec.h ucontext.h regex.h values.h)
 
 if test "$ac_cv_header_security_pam_modules_h" = yes -a "$enable_pam" = yes; then
        HAVE_PAM="yes"
index 2882fad..d68867a 100644 (file)
@@ -13,6 +13,9 @@
 
 #include <afsconfig.h>
 #include <afs/param.h>
+#ifndef AFS_NT40_ENV
+#include <netdb.h>
+#endif
 
 RCSID
     ("$Header$");
@@ -1613,6 +1616,190 @@ DoVosVolumeQuotaChange(struct cmd_syndesc *as, char *arock)
     return 0;
 }
 
+/*
+ * Parse a server name/address and return the address in HOST BYTE order
+ */
+static afs_uint32
+GetServer(char *aname)
+{
+    register struct hostent *th;
+    afs_uint32 addr;
+    int b1, b2, b3, b4;
+    register afs_int32 code;
+    char hostname[MAXHOSTCHARS];
+
+    code = sscanf(aname, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
+    if (code == 4) {
+       addr = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
+       addr = ntohl(addr);     /* convert to host order */
+    } else {
+       th = gethostbyname(aname);
+       if (!th)
+           return 0;
+       memcpy(&addr, th->h_addr, sizeof(addr));
+    }
+
+    if (addr == htonl(0x7f000001)) {   /* local host */
+       code = gethostname(hostname, MAXHOSTCHARS);
+       if (code)
+           return 0;
+       th = gethostbyname(hostname);   /* returns host byte order */
+       if (!th)
+           return 0;
+       memcpy(&addr, th->h_addr, sizeof(addr));
+    }
+
+    return (addr);
+}
+
+static void
+Print_vos_volintInfo(afs_uint32 server, afs_uint32 partition, volintInfo* pinfo, const char *prefix)
+{
+    static afs_uint32 server_cache;
+    static int cache_valid = 0;
+    static char hostname[256], address[32];
+
+    if (!cache_valid || server != server_cache) {
+       struct in_addr s;
+
+       s.s_addr = server;
+       strcpy(hostname, hostutil_GetNameByINet(server));
+       strcpy(address, inet_ntoa(s));
+       server_cache = server;
+       cache_valid = 1;
+    }
+    
+    
+    printf("%sname\t\t%s\n",prefix, pinfo->name);
+    printf("%sid\t\t%lu\n",prefix, pinfo->volid);
+    printf("%sserv\t\t%s\t%s\n",prefix, address,hostname);
+    printf("%spart\t\t%u\n", prefix,partition);
+    
+    switch (pinfo->status) {
+    case 2: /* VOK */
+       printf("%sstatus\t\tOK\n",prefix);
+       break;
+    case 101: /* VBUSY */
+       printf("%sstatus\t\tBUSY\n",prefix);
+       return;
+    default:
+       printf("%sstatus\t\tUNATTACHABLE\n",prefix);
+       return;
+    }
+    printf("%sbackupID\t%lu\n",prefix, pinfo->backupID);
+    printf("%sparentID\t%lu\n",prefix, pinfo->parentID);
+    printf("%scloneID\t%lu\n",prefix, pinfo->cloneID);
+    printf("%sinUse\t\t%s\n",prefix, pinfo->inUse ? "Y" : "N");
+    printf("%sneedsSalvaged\t%s\n",prefix, pinfo->needsSalvaged ? "Y" : "N");
+    /* 0xD3 is from afs/volume.h since I had trouble including the file */
+    printf("%sdestroyMe\t%s\n",prefix, pinfo->destroyMe == 0xD3 ? "Y" : "N");
+    switch (pinfo->type) {
+    case 0:
+       printf("%stype\t\tRW\n",prefix);
+       break;
+    case 1:
+       printf("%stype\t\tRO\n",prefix);
+       break;
+    case 2:
+       printf("%stype\t\tBK\n",prefix);
+       break;
+    default:
+       printf("%stype\t\t?\n",prefix);
+       break;
+    }
+    printf("%screationDate\t%-9lu\n", prefix,pinfo->creationDate);
+    printf("%saccessDate\t%-9lu\n", prefix,pinfo->accessDate);
+    printf("%supdateDate\t%-9lu\n", prefix,pinfo->updateDate);
+    printf("%sbackupDate\t%-9lu\n", prefix,pinfo->backupDate);
+    printf("%scopyDate\t%-9lu\n", prefix,pinfo->copyDate);
+           
+    printf("%sflags\t\t%#lx\t(Optional)\n",prefix, pinfo->flags);
+    printf("%sdiskused\t%u\n",prefix, pinfo->size);
+    printf("%smaxquota\t%u\n",prefix, pinfo->maxquota);
+    printf("%sminquota\t%lu\t(Optional)\n",prefix, pinfo->spare0);
+    printf("%sfilecount\t%u\n",prefix, pinfo->filecount);
+    printf("%sdayUse\t\t%u\n",prefix, pinfo->dayUse);
+    printf("%sweekUse\t%lu\t(Optional)\n",prefix, pinfo->spare1);
+    printf("%svolUpdateCounter\t\t%lu\t(Optional)\n",prefix, pinfo->spare2);
+    printf("%sspare3\t\t%lu\t(Optional)\n",prefix, pinfo->spare3);
+}
+
+int
+DoVosVolumeGet2(struct cmd_syndesc *as, char *arock)
+{
+    typedef enum { SERVER, PARTITION, VOLUME } DoVosVolumeGet_parm_t;
+    afs_status_t st = 0;
+    void *vos_server = NULL;
+    afs_uint32 partition_id;
+    afs_uint32 volume_id;
+
+       volintInfo info;
+       memset(&info, 0, sizeof(struct volintInfo));
+
+    if (as->parms[SERVER].items) {
+       if (!vos_ServerOpen
+           (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
+           ERR_ST_EXT("vos_ServerOpen", st);
+       }
+    }
+
+    if (as->parms[PARTITION].items) {
+       partition_id =
+           GetPartitionIdFromString(as->parms[PARTITION].items->data);
+    }
+
+    if (as->parms[VOLUME].items) {
+       const char *volume = as->parms[VOLUME].items->data;
+       volume_id = GetVolumeIdFromString(volume);
+    }
+    
+
+       if (!vos_VolumeGet2
+       (cellHandle, vos_server, 0, partition_id, volume_id, &info, &st)) {
+       ERR_ST_EXT("vos_VolumeGet2", st);
+    }
+
+
+    Print_vos_volintInfo(GetServer(as->parms[SERVER].items->data),partition_id,&info," ");
+
+    return 0;
+}
+
+
+int
+DoVos_ClearVolUpdateCounter(struct cmd_syndesc *as, char *arock)
+{
+    typedef enum { SERVER, PARTITION, VOLUME } DoVosVolumeGet_parm_t;
+    afs_status_t st = 0;
+    void *vos_server = NULL;
+    unsigned int partition_id;
+    unsigned int volume_id;
+
+    if (as->parms[SERVER].items) {
+       if (!vos_ServerOpen
+           (cellHandle, as->parms[SERVER].items->data, &vos_server, &st)) {
+           ERR_ST_EXT("vos_ServerOpen", st);
+       }
+    }
+
+    if (as->parms[PARTITION].items) {
+       partition_id =
+           GetPartitionIdFromString(as->parms[PARTITION].items->data);
+    }
+
+    if (as->parms[VOLUME].items) {
+       const char *volume = as->parms[VOLUME].items->data;
+       volume_id = GetVolumeIdFromString(volume);
+    }
+
+    if (!vos_ClearVolUpdateCounter
+       (cellHandle, vos_server,partition_id, volume_id, &st)) {
+       ERR_ST_EXT("vos_ClearVolUpdateCounter", st);
+    }
+
+    return 0;
+}
+
 void
 SetupVosAdminCmd(void)
 {
@@ -1898,4 +2085,25 @@ SetupVosAdminCmd(void)
                "new quota in 1kb units");
     SetupCommonCmdArgs(ts);
 
+    ts = cmd_CreateSyntax("VosVolumeGet2", DoVosVolumeGet2, 0,
+                         "get a volume entry");
+    cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
+               "server that houses volume");
+    cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
+               "partition that houses volume");
+    cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED,
+               "volume to retrieve");
+    SetupCommonCmdArgs(ts);
+    
+    ts = cmd_CreateSyntax("ClearVolUpdateCounter", DoVos_ClearVolUpdateCounter, 0,
+                         "clear volUpdateCounter");
+    cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
+               "server that houses volume");
+    cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_REQUIRED,
+               "partition that houses volume");
+    cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED,
+               "volume");
+    SetupCommonCmdArgs(ts);
+
 }
+
index c29eb13..fd6e882 100644 (file)
@@ -4404,8 +4404,10 @@ vos_VolumeQuotaChange(const void *cellHandle, const void *serverHandle,
 
     memset((void *)&tstatus, 0, sizeof(tstatus));
     tstatus.dayUse = -1;
+    tstatus.spare2 = -1;
     tstatus.maxquota = volumeQuota;
 
+
     tst =
        AFSVolTransCreate(f_server->serv, volumeId, partition, ITBusy, &ttid);
     if (tst) {
@@ -4443,3 +4445,187 @@ vos_VolumeQuotaChange(const void *cellHandle, const void *serverHandle,
     }
     return rc;
 }
+/*
+ * vos_VolumeGet2 - get information about a particular volume.
+ *
+ * PARAMETERS
+ *
+ * IN cellHandle - a previously opened cellHandle that corresponds
+ * to the cell where the volume exists.
+ *
+ * IN serverHandle - a previously opened serverHandle that corresponds
+ * to the server where the volume exists.
+ *
+ * IN callBack - a call back function pointer that may be called to report
+ * status information.  Can be null.
+ *
+ * IN partition - the partition where the volume exists.
+ *
+ * IN volumeId - the volume id of the volume to be retrieved.
+ *
+ * OUT pinfo - upon successful completion, contains the information about the 
+ * specified volume.
+ *
+ * LOCKS
+ * 
+ * No locks are obtained or released by this function
+ *
+ * RETURN CODES
+ *
+ * Returns != 0 upon successful completion.
+ */
+
+int ADMINAPI
+vos_VolumeGet2(const void *cellHandle, const void *serverHandle,
+             vos_MessageCallBack_t callBack, unsigned int partition,
+             unsigned int volumeId, volintInfo* pinfo,
+             afs_status_p st)
+{
+    int rc = 0;
+    afs_status_t tst = 0;
+    file_server_p f_server = (file_server_p) serverHandle;
+    volintInfo *pinfo_=0;
+
+    /*
+     * Validate arguments
+     */
+
+    if (!IsValidServerHandle(f_server, &tst)) {
+       goto fail_vos_VolumeGet2;
+    }
+
+    if (partition > VOLMAXPARTS) {
+       tst = ADMVOSPARTITIONIDTOOLARGE;
+       goto fail_vos_VolumeGet2;
+    }
+
+    if (pinfo == NULL) {
+       tst = ADMVOSVOLUMEPNULL;
+       goto fail_vos_VolumeGet2;
+    }
+
+    /*
+     * Retrieve the information for the volume
+     */
+
+    if (!UV_ListOneVolume(f_server->serv, partition, volumeId, &pinfo_,&tst)) {
+       goto fail_vos_VolumeGet2;
+    }
+
+
+    rc = 1;
+
+  fail_vos_VolumeGet2:
+
+    if (pinfo_ != NULL) {
+     memcpy(pinfo,pinfo_,sizeof(volintInfo));
+       free(pinfo_);
+    }
+
+    if (st != NULL) {
+       *st = tst;
+    }
+    return rc;
+}
+
+/*
+ * vos_ClearVolUpdateCounter - reset volUpdateCounter of a volume to zero
+ *
+ * PARAMETERS
+ *
+ * IN cellHandle - a previously opened cellHandle that corresponds
+ * to the cell where the volume exists.
+ *
+ * IN serverHandle - a previously opened serverHandle that corresponds
+ * to the server where the volume exists.
+ *
+ * IN partition - the partition where the volume exists.
+ *
+ * IN volumeId - the volume id of the volume to be retrieved.
+ *
+ * LOCKS
+ * 
+ * No locks are obtained or released by this function
+ *
+ * RETURN CODES
+ *
+ * Returns != 0 upon successful completion.
+ */
+
+int ADMINAPI
+vos_ClearVolUpdateCounter(const void *cellHandle,
+                                 const void *serverHandle,
+                                 unsigned int partition,
+                                 unsigned int volumeId,
+                                 afs_status_p st)
+{
+    int rc = 0;
+    afs_status_t tst = 0;
+    afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
+    file_server_p f_server = (file_server_p) serverHandle;
+    int ttid = 0;
+    int rcode = 0;
+    struct volintInfo tstatus;
+    int active_trans = 0;
+
+    /*
+     * Verify that the cellHandle is capable of making vos rpc's
+     */
+
+    if (!IsValidCellHandle(c_handle, &tst)) {
+       goto fail_vos_ClearVolUpdateCounter;
+    }
+
+    if (!IsValidServerHandle(f_server, &tst)) {
+       goto fail_vos_ClearVolUpdateCounter;
+    }
+
+    memset((void *)&tstatus, 0, sizeof(tstatus));
+    tstatus.maxquota = -1;
+    tstatus.dayUse = -1;
+    tstatus.creationDate = -1;
+    tstatus.updateDate = -1;
+    tstatus.flags = -1;
+    tstatus.spare0 = -1;
+    tstatus.spare1 = -1;
+    tstatus.spare2 = 0;
+    tstatus.spare3 = -1;
+    
+    tst =
+       AFSVolTransCreate(f_server->serv, volumeId, partition, ITBusy, &ttid);
+    if (tst) {
+       goto fail_vos_ClearVolUpdateCounter;
+    }
+    active_trans = 1;
+
+    tst = AFSVolSetInfo(f_server->serv, ttid, &tstatus);
+    if (tst) {
+       goto fail_vos_ClearVolUpdateCounter;
+    }
+    rc = 1;
+
+  fail_vos_ClearVolUpdateCounter:
+
+    if (active_trans) {
+       afs_status_t tst2 = 0;
+       tst2 = AFSVolEndTrans(f_server->serv, ttid, &rcode);
+       if (tst2) {
+           if (tst == 0) {
+               tst = tst2;
+               rc = 0;
+           }
+       }
+       if (rcode) {
+           if (tst == 0) {
+               tst = rcode;
+               rc = 0;
+           }
+       }
+    }
+
+    if (st != NULL) {
+       *st = tst;
+    }
+    return rc;
+}
+
index fe0a5c2..be051ef 100644 (file)
@@ -13,6 +13,7 @@
 #include <afs/param.h>
 #include <afs/afs_Admin.h>
 #include <sys/types.h>
+#include <afs/volint.h>
 #ifdef AFS_NT40_ENV
 #ifndef _MFC_VER
 #include <winsock2.h>
@@ -466,4 +467,17 @@ extern int ADMINAPI vos_VolumeQuotaChange(const void *cellHandle,
                                          unsigned int volumeQuota,
                                          afs_status_p st);
 
+extern int ADMINAPI vos_VolumeGet2(const void *cellHandle,
+                                 const void *serverHandle,
+                                 vos_MessageCallBack_t callBack,
+                                 unsigned int partition,
+                                 unsigned int volumeId,
+                                 volintInfo* pinfo, afs_status_p st);
+
+extern int ADMINAPI vos_ClearVolUpdateCounter(const void *cellHandle,
+                                 const void *serverHandle,
+                                 unsigned int partition,
+                                 unsigned int volumeId,
+                                 afs_status_p st);                               
+
 #endif /* OPENAFS_VOS_ADMIN_H */
index b9ff2d5..3e107b8 100644 (file)
@@ -45,7 +45,8 @@ EXPORTS
        vos_PartitionIdToName                                   @43
        vos_VolumeQuotaChange                                   @44
        vos_VLDBUnlock                                          @45
-
+       vos_VolumeGet2                                          @46
+       vos_ClearVolUpdateCounter                       @47
 
 
 
index 76378c7..acba733 100644 (file)
@@ -2938,6 +2938,66 @@ UV_XListOneVolume(struct rx_connection *server, afs_int32 a_partID,
 
 }                              /*UV_XListOneVolume */
 
+/*------------------------------------------------------------------------
+ * EXPORTED UV_ListOneVolume
+ *
+ * Description:
+ *     List the volume information for a volume on a particular File
+ *     Server and partition.
+ *
+ * Arguments:
+ *     server     : a handle to the server where the volume resides.
+ *     a_partID           : Partition for which we want the extended
+ *                             volume info.
+ *     a_volID            : Volume ID for which we want the info.
+ *     a_resultPP         : Ptr to the address of the area containing
+ *                             the returned volume info.
+ *
+ * Returns:
+ *     0 on success,
+ *     Otherise, the return value of AFSVolXListOneVolume.
+ *
+ * Side Effects:
+ *     As advertised.
+ *------------------------------------------------------------------------*/
+
+int UV_ListOneVolume(struct rx_connection *server, afs_int32 a_partID,
+                 afs_int32 a_volID, struct volintInfo **a_resultPP,
+                 afs_status_p st)
+{
+       int rc = 0;
+    afs_status_t tst = 0;
+    volEntries volumeInfo;     /*Area for returned info */
+
+    /*
+     * Set the area we're in which we are returning
+     * the info.  Setting the val field to a null pointer tells the stub
+     * to allocate space for us.
+     */
+    *a_resultPP = (volintInfo *) 0;
+    volumeInfo.volEntries_val = (volintInfo *) 0;
+    volumeInfo.volEntries_len = 0;
+
+    tst = AFSVolListOneVolume(server, a_partID, a_volID, &volumeInfo);
+
+    if (tst) {
+       goto fail_UV_ListOneVolume;
+    } else {
+       /*
+        * We got the info; pull out the pointer to where the results lie.
+        */
+       *a_resultPP = volumeInfo.volEntries_val;
+    }
+    rc = 1;
+
+  fail_UV_ListOneVolume:
+
+    if (st != NULL) {
+       *st = tst;
+    }
+    return rc;
+}/*UV_ListOneVolume*/
+
 /*sync vldb with all the entries on <myQueue> on <aserver> and <apart>*/
 static afs_int32
 ProcessEntries(afs_cell_handle_p cellHandle, struct qHead *myQueue,
index 416bfab..1781e51 100644 (file)
@@ -106,6 +106,10 @@ extern int UV_XListOneVolume(struct rx_connection *server, afs_int32 a_partID,
                             struct volintXInfo **a_resultPP,
                             afs_status_p st);
 
+extern int UV_ListOneVolume(struct rx_connection *server, afs_int32 a_partID,
+                 afs_int32 a_volID, struct volintInfo **a_resultPP,
+                 afs_status_p st);
+                           
 extern int UV_SyncVldb(afs_cell_handle_p cellHandle,
                       struct rx_connection *server, afs_int32 apart,
                       int flags, int force, afs_status_p st);
index 3e4b45d..c9a6c0c 100644 (file)
@@ -15,6 +15,7 @@
  */
 #include <afsconfig.h>
 #include <afs/param.h>
+#define MAXINT     (~(1<<((sizeof(int)*8)-1)))
 
 RCSID
     ("$Header$");
@@ -719,7 +720,11 @@ VPutVnode_r(Error * ec, register Vnode * vnp)
                vnp->disk.serverModifyTime = now;
            }
            if (vnp->changed_newTime)
+           {
                V_updateDate(vp) = vp->updateTime = now;
+               if(V_volUpCounter(vp)<MAXINT)
+                       V_volUpCounter(vp)++;
+           }
 
            /* The vnode has been changed. Write it out to disk */
            if (!V_inUse(vp)) {
index 836f50b..ae58d5f 100644 (file)
@@ -692,6 +692,7 @@ PrintHeader(register Volume * vp)
         V_dayUse(vp), V_weekUse(vp)[0], V_weekUse(vp)[1], V_weekUse(vp)[2],
         V_weekUse(vp)[3], V_weekUse(vp)[4], V_weekUse(vp)[5],
         V_weekUse(vp)[6], date(V_dayUseDate(vp)));
+    printf("volUpdateCounter = %u\n", V_volUpCounter(vp));
 }
 
 /* GetFileInfo
index 68fc0f9..c66a09b 100644 (file)
@@ -248,7 +248,8 @@ typedef struct VolumeDiskData {
                                 * of measurement; week[6] is 7 days ago */
     Date dayUseDate;           /* Date the dayUse statistics refer to; the week use stats
                                 * are the preceding 7 days */
-    int reserved3[11];         /* Other stats here */
+    unsigned int volUpdateCounter; /*incremented at every update of volume*/
+    int reserved3[10];         /* Other stats here */
 
     /* Server supplied dates */
     Date creationDate;         /* Creation date for a read/write
@@ -402,6 +403,7 @@ struct volHeader {
 #define V_stat_dirSameAuthor(vp, idx)  (((vp)->header->diskstuff.stat_dirSameAuthor)[idx])
 #define V_stat_dirDiffAuthor(vp, idx)  (((vp)->header->diskstuff.stat_dirDiffAuthor)[idx])
 #endif /* OPENAFS_VOL_STATS */
+#define V_volUpCounter(vp)             ((vp)->header->diskstuff.volUpdateCounter)
 
 /* File offset computations.  The offset values in the volume header are
    computed with these macros -- when the file is written only!! */
index 33099c1..911c35a 100644 (file)
@@ -371,6 +371,10 @@ ReadVolumeHeader(register struct iod *iodp, VolumeDiskData * vol)
            if (!ReadInt32(iodp, (afs_uint32 *) & vol->dayUse))
                return VOLSERREAD_DUMPERROR;
            break;
+       case 'V':
+           if (!ReadInt32(iodp, (afs_uint32 *) & vol->volUpdateCounter))
+               return VOLSERREAD_DUMPERROR;
+           break;
        }
     }
     iod_ungetc(iodp, tag);
@@ -695,6 +699,8 @@ DumpVolumeHeader(register struct iod *iodp, register Volume * vp)
        code = DumpInt32(iodp, 'D', V_dayUseDate(vp));
     if (!code)
        code = DumpInt32(iodp, 'Z', V_dayUse(vp));
+    if (!code)
+       code = DumpInt32(iodp, 'V', V_volUpCounter(vp));
     return code;
 }
 
@@ -1450,6 +1456,9 @@ SizeDumpVolumeHeader(register struct iod *iodp, register Volume * vp,
 /*     if (!code) code = DumpInt32(iodp, 'Z', V_dayUse(vp)); */
     FillInt64(addvar,0, 5);
     AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
+/*     if (!code) code = DumpInt32(iodp, 'V', V_volUpCounter(vp)); */
+    FillInt64(addvar,0, 5);
+    AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
     return code;
 }
 
index 449e7d0..341c0d9 100644 (file)
@@ -225,6 +225,7 @@ struct volumeHeader {
     int inService;
     int blessed;
     char message[1024];
+    afs_int32 volUpdateCounter;
 };
 
 afs_int32
@@ -351,6 +352,9 @@ ReadVolumeHeader(count)
        case 'Z':
            vh.dayUse = ntohl(readvalue(4));
            break;
+       case 'V':
+            vh.volUpdateCounter = ntohl(readvalue(4));
+           break;
 
        default:
            done = 1;
index 39a1edd..47ee1fa 100644 (file)
@@ -508,6 +508,8 @@ DumpVolumeHeader(int dumpfd, register Volume * vp)
        code = DumpInt32(dumpfd, 'D', V_dayUseDate(vp));
     if (!code)
        code = DumpInt32(dumpfd, 'Z', V_dayUse(vp));
+    if (!code)
+       code = DumpInt32(dumpfd, 'V', V_volUpCounter(vp));
     return code;
 }
 
index cfa5155..99d0180 100644 (file)
@@ -108,7 +108,7 @@ struct volintInfo {
     afs_int32 flags;           /* used by the backup system */
     afs_int32 spare0;          /* Used to hold the minquota value */
     afs_int32 spare1;          /* Used to hold the weekuse value */
-    afs_int32 spare2;
+    afs_int32 spare2;          /* Used to hold volUpdateCounter */
     afs_int32 spare3;
 };
 
index d0a1659..7795aa7 100644 (file)
@@ -1544,6 +1544,8 @@ VolSetInfo(struct rx_call *acid, afs_int32 atrans,
        td->creationDate = astatus->creationDate;
     if (astatus->updateDate != -1)
        td->updateDate = astatus->updateDate;
+    if (astatus->spare2 != -1)
+       td->volUpdateCounter = (unsigned int)astatus->spare2;
     VUpdateVolume(&error, tv);
     tt->rxCallPtr = (struct rx_call *)0;
     if (TRELE(tt))
@@ -1849,7 +1851,8 @@ VolListOneVolume(struct rx_call *acid, afs_int32 partid, afs_int32
                (long)tv->header->diskstuff.weekUse[4] +
                (long)tv->header->diskstuff.weekUse[5] +
                (long)tv->header->diskstuff.weekUse[6];
-           pntr->flags = pntr->spare2 = pntr->spare3 = (long)0;
+           pntr->spare2 = V_volUpCounter(tv);
+           pntr->flags = pntr->spare3 = (long)0;
            VDetachVolume(&error, tv);  /*free the volume */
            tv = (Volume *) 0;
            if (error) {
@@ -2224,7 +2227,8 @@ VolListVolumes(struct rx_call *acid, afs_int32 partid, afs_int32 flags,
                (long)tv->header->diskstuff.weekUse[4] +
                (long)tv->header->diskstuff.weekUse[5] +
                (long)tv->header->diskstuff.weekUse[6];
-           pntr->flags = pntr->spare2 = pntr->spare3 = (long)0;
+           pntr->spare2 = V_volUpCounter(tv);
+           pntr->flags = pntr->spare3 = (long)0;
            VDetachVolume(&error, tv);  /*free the volume */
            tv = (Volume *) 0;
            if (error) {
index e7ed31a..e62b739 100644 (file)
@@ -1715,6 +1715,10 @@ SetFields(as)
        /* -clearuse */
        info.dayUse = 0;
     }
+    if (as->parms[3].items) {
+       /* -clearVolUpCounter */
+       info.spare2 = 0;
+    }
     code = UV_SetVolumeInfo(aserver, apart, volid, &info);
     if (code)
        fprintf(STDERR,
@@ -5895,6 +5899,7 @@ main(argc, argv)
     cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
     cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL, "quota (KB)");
     cmd_AddParm(ts, "-clearuse", CMD_FLAG, CMD_OPTIONAL, "clear dayUse");
+    cmd_AddParm(ts, "-clearVolUpCounter", CMD_FLAG, CMD_OPTIONAL, "clear volUpdateCounter");
     COMMONPARMS;
 
     ts = cmd_CreateSyntax("offline", volOffline, 0, (char *)CMD_HIDDEN);