From cfa7b866c8deb876b06fd634d34ecdd30fb9b819 Mon Sep 17 00:00:00 2001 From: Ervin Fenyak Date: Sun, 23 Oct 2005 20:05:40 +0000 Subject: [PATCH] add-volupdate-counter-20051015 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 --- acinclude.m4 | 2 +- src/libadmin/test/vos.c | 208 ++++++++++++++++++++++++++++++++ src/libadmin/vos/afs_vosAdmin.c | 186 ++++++++++++++++++++++++++++ src/libadmin/vos/afs_vosAdmin.h | 14 +++ src/libadmin/vos/vosadmin.def | 3 +- src/libadmin/vos/vsprocs.c | 60 +++++++++ src/libadmin/vos/vsprocs.h | 4 + src/vol/vnode.c | 5 + src/vol/vol-info.c | 1 + src/vol/volume.h | 4 +- src/volser/dumpstuff.c | 9 ++ src/volser/restorevol.c | 4 + src/volser/vol-dump.c | 2 + src/volser/volint.xg | 2 +- src/volser/volprocs.c | 8 +- src/volser/vos.c | 5 + 16 files changed, 511 insertions(+), 6 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index ebaa0b546..662cb6b64 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -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" diff --git a/src/libadmin/test/vos.c b/src/libadmin/test/vos.c index 2882fad23..d68867a66 100644 --- a/src/libadmin/test/vos.c +++ b/src/libadmin/test/vos.c @@ -13,6 +13,9 @@ #include #include +#ifndef AFS_NT40_ENV +#include +#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); + } + diff --git a/src/libadmin/vos/afs_vosAdmin.c b/src/libadmin/vos/afs_vosAdmin.c index c29eb13f5..fd6e882af 100644 --- a/src/libadmin/vos/afs_vosAdmin.c +++ b/src/libadmin/vos/afs_vosAdmin.c @@ -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; +} + diff --git a/src/libadmin/vos/afs_vosAdmin.h b/src/libadmin/vos/afs_vosAdmin.h index fe0a5c200..be051ef98 100644 --- a/src/libadmin/vos/afs_vosAdmin.h +++ b/src/libadmin/vos/afs_vosAdmin.h @@ -13,6 +13,7 @@ #include #include #include +#include #ifdef AFS_NT40_ENV #ifndef _MFC_VER #include @@ -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 */ diff --git a/src/libadmin/vos/vosadmin.def b/src/libadmin/vos/vosadmin.def index b9ff2d50a..3e107b8b4 100644 --- a/src/libadmin/vos/vosadmin.def +++ b/src/libadmin/vos/vosadmin.def @@ -45,7 +45,8 @@ EXPORTS vos_PartitionIdToName @43 vos_VolumeQuotaChange @44 vos_VLDBUnlock @45 - + vos_VolumeGet2 @46 + vos_ClearVolUpdateCounter @47 diff --git a/src/libadmin/vos/vsprocs.c b/src/libadmin/vos/vsprocs.c index 76378c778..acba733b6 100644 --- a/src/libadmin/vos/vsprocs.c +++ b/src/libadmin/vos/vsprocs.c @@ -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 on and */ static afs_int32 ProcessEntries(afs_cell_handle_p cellHandle, struct qHead *myQueue, diff --git a/src/libadmin/vos/vsprocs.h b/src/libadmin/vos/vsprocs.h index 416bfabe6..1781e5150 100644 --- a/src/libadmin/vos/vsprocs.h +++ b/src/libadmin/vos/vsprocs.h @@ -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); diff --git a/src/vol/vnode.c b/src/vol/vnode.c index 3e4b45df4..c9a6c0c58 100644 --- a/src/vol/vnode.c +++ b/src/vol/vnode.c @@ -15,6 +15,7 @@ */ #include #include +#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)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!! */ diff --git a/src/volser/dumpstuff.c b/src/volser/dumpstuff.c index 33099c112..911c35ae4 100644 --- a/src/volser/dumpstuff.c +++ b/src/volser/dumpstuff.c @@ -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; } diff --git a/src/volser/restorevol.c b/src/volser/restorevol.c index 449e7d01b..341c0d978 100644 --- a/src/volser/restorevol.c +++ b/src/volser/restorevol.c @@ -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; diff --git a/src/volser/vol-dump.c b/src/volser/vol-dump.c index 39a1edd50..47ee1fa19 100644 --- a/src/volser/vol-dump.c +++ b/src/volser/vol-dump.c @@ -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; } diff --git a/src/volser/volint.xg b/src/volser/volint.xg index cfa515596..99d0180b1 100644 --- a/src/volser/volint.xg +++ b/src/volser/volint.xg @@ -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; }; diff --git a/src/volser/volprocs.c b/src/volser/volprocs.c index d0a1659b9..7795aa7ca 100644 --- a/src/volser/volprocs.c +++ b/src/volser/volprocs.c @@ -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) { diff --git a/src/volser/vos.c b/src/volser/vos.c index e7ed31a85..e62b73938 100644 --- a/src/volser/vos.c +++ b/src/volser/vos.c @@ -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); -- 2.39.5