diff --git a/doc/man-pages/pod1/fs_flushall.pod b/doc/man-pages/pod1/fs_flushall.pod index 92a621ebc1..38a9144611 100644 --- a/doc/man-pages/pod1/fs_flushall.pod +++ b/doc/man-pages/pod1/fs_flushall.pod @@ -18,10 +18,6 @@ B [B<-h>] The B command flushes all data from the AFS cache. -=head1 CAUTIONS - -This command is only available on Windows. - =head1 OPTIONS =over 4 diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index b6b2009347..df194b56a9 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -277,6 +277,7 @@ DECL_PIOCTL(PRemoveMount); DECL_PIOCTL(PGetCellStatus); DECL_PIOCTL(PSetCellStatus); DECL_PIOCTL(PFlushVolumeData); +DECL_PIOCTL(PFlushAllVolumeData); DECL_PIOCTL(PGetVnodeXStatus); DECL_PIOCTL(PGetVnodeXStatus2); DECL_PIOCTL(PSetSysName); @@ -420,6 +421,7 @@ static pioctlFunction CpioctlSw[] = { PBogus, /* 11 */ PPrecache, /* 12 */ PGetPAG, /* 13 */ + PFlushAllVolumeData, /* 14 */ }; static pioctlFunction OpioctlSw[] = { @@ -3442,46 +3444,27 @@ DECL_PIOCTL(PSetCellStatus) return 0; } -/*! - * VIOC_FLUSHVOLUME (37) - Flush whole volume's data - * - * \ingroup pioctl - * - * \param[in] ain not in use (args in avc) - * \param[out] aout not in use - * - * \retval EINVAL Error if some of the standard args aren't set - * \retval EIO Error if the afs daemon hasn't started yet - * - * \post - * Flush all cached contents of a volume. Exactly what stays and what - * goes depends on the platform. - * - * \notes - * Does not flush a file that a user has open and is using, because - * it will be re-created on next write. Also purges the dnlc, - * because things are screwed up. - */ -DECL_PIOCTL(PFlushVolumeData) +static void +FlushVolumeData(struct VenusFid *afid, afs_ucred_t * acred) { afs_int32 i; struct dcache *tdc; struct vcache *tvc; struct volume *tv; - afs_int32 cell, volume; + afs_int32 all = 0; + afs_int32 cell = 0; + afs_int32 volume = 0; struct afs_q *tq, *uq; #ifdef AFS_DARWIN80_ENV vnode_t vp; #endif - AFS_STATCNT(PFlushVolumeData); - if (!avc) - return EINVAL; - if (!afs_resourceinit_flag) /* afs daemons haven't started yet */ - return EIO; /* Inappropriate ioctl for device */ - - volume = avc->f.fid.Fid.Volume; /* who to zap */ - cell = avc->f.fid.Cell; + if (!afid) { + all = 1; + } else { + volume = afid->Fid.Volume; /* who to zap */ + cell = afid->Cell; + } /* * Clear stat'd flag from all vnodes from this volume; this will @@ -3489,11 +3472,11 @@ DECL_PIOCTL(PFlushVolumeData) */ loop: ObtainReadLock(&afs_xvcache); - i = VCHashV(&avc->f.fid); - for (tq = afs_vhashTV[i].prev; tq != &afs_vhashTV[i]; tq = uq) { + for (i = (afid ? VCHashV(afid) : 0); i < VCSIZE; i = (afid ? VCSIZE : i+1)) { + for (tq = afs_vhashTV[i].prev; tq != &afs_vhashTV[i]; tq = uq) { uq = QPrev(tq); tvc = QTOVH(tq); - if (tvc->f.fid.Fid.Volume == volume && tvc->f.fid.Cell == cell) { + if (all || (tvc->f.fid.Fid.Volume == volume && tvc->f.fid.Cell == cell)) { if (tvc->f.states & CVInit) { ReleaseReadLock(&afs_xvcache); afs_osi_Sleep(&tvc->f.states); @@ -3522,7 +3505,7 @@ DECL_PIOCTL(PFlushVolumeData) afs_BozonLock(&tvc->pvnLock, tvc); /* Since afs_TryToSmush will do a pvn_vptrunc */ #endif ObtainWriteLock(&tvc->lock, 232); - afs_ResetVCache(tvc, *acred, 1); + afs_ResetVCache(tvc, acred, 1); ReleaseWriteLock(&tvc->lock); #ifdef AFS_BOZONLOCK_ENV afs_BozonUnlock(&tvc->pvnLock, tvc); @@ -3536,6 +3519,7 @@ DECL_PIOCTL(PFlushVolumeData) AFS_FAST_RELE(tvc); } } + } ReleaseReadLock(&afs_xvcache); @@ -3549,7 +3533,7 @@ DECL_PIOCTL(PFlushVolumeData) } if (tdc->refCount <= 1) { /* too high, in use by running sys call */ ReleaseReadLock(&tdc->tlock); - if (tdc->f.fid.Fid.Volume == volume && tdc->f.fid.Cell == cell) { + if (all || (tdc->f.fid.Fid.Volume == volume && tdc->f.fid.Cell == cell)) { if (!(afs_indexFlags[i] & (IFDataMod | IFFree | IFDiscarded))) { /* if the file is modified, but has a ref cnt of only 1, * then someone probably has the file open and is writing @@ -3573,7 +3557,7 @@ DECL_PIOCTL(PFlushVolumeData) ObtainReadLock(&afs_xvolume); for (i = 0; i < NVOLS; i++) { for (tv = afs_volumes[i]; tv; tv = tv->next) { - if (tv->volume == volume) { + if (all || tv->volume == volume) { afs_ResetVolumeInfo(tv); break; } @@ -3584,9 +3568,70 @@ DECL_PIOCTL(PFlushVolumeData) /* probably, a user is doing this, probably, because things are screwed up. * maybe it's the dnlc's fault? */ osi_dnlc_purge(); +} + +/*! + * VIOC_FLUSHVOLUME (37) - Flush whole volume's data + * + * \ingroup pioctl + * + * \param[in] ain not in use (args in avc) + * \param[out] aout not in use + * + * \retval EINVAL Error if some of the standard args aren't set + * \retval EIO Error if the afs daemon hasn't started yet + * + * \post + * Flush all cached contents of a volume. Exactly what stays and what + * goes depends on the platform. + * + * \notes + * Does not flush a file that a user has open and is using, because + * it will be re-created on next write. Also purges the dnlc, + * because things are screwed up. + */ +DECL_PIOCTL(PFlushVolumeData) +{ + AFS_STATCNT(PFlushVolumeData); + if (!avc) + return EINVAL; + if (!afs_resourceinit_flag) /* afs daemons haven't started yet */ + return EIO; /* Inappropriate ioctl for device */ + + FlushVolumeData(&avc->f.fid, *acred); return 0; } +/*! + * VIOC_FLUSHALL (14) - Flush whole volume's data for all volumes + * + * \ingroup pioctl + * + * \param[in] ain not in use + * \param[out] aout not in use + * + * \retval EINVAL Error if some of the standard args aren't set + * \retval EIO Error if the afs daemon hasn't started yet + * + * \post + * Flush all cached contents. Exactly what stays and what + * goes depends on the platform. + * + * \notes + * Does not flush a file that a user has open and is using, because + * it will be re-created on next write. Also purges the dnlc, + * because things are screwed up. + */ +DECL_PIOCTL(PFlushAllVolumeData) +{ + AFS_STATCNT(PFlushAllVolumeData); + + if (!afs_resourceinit_flag) /* afs daemons haven't started yet */ + return EIO; /* Inappropriate ioctl for device */ + + FlushVolumeData(NULL, *acred); + return 0; +} /*! * VIOCGETVCXSTATUS (41) - gets vnode x status diff --git a/src/afs/afs_stats.h b/src/afs/afs_stats.h index 11e242a92d..1c0feb37b3 100644 --- a/src/afs/afs_stats.h +++ b/src/afs/afs_stats.h @@ -656,7 +656,8 @@ struct afs_MeanStats { AFS_CS(BPrefetchNoCache) /* afs_daemons.c */ \ AFS_CS(afs_ReadNoCache) /* osi_vnodeops.c */ \ AFS_CS(PSetTokens2) /* afs_pioctl.c */ \ - AFS_CS(PPrefetchFromTape) /* afs_pioctl.c */ + AFS_CS(PPrefetchFromTape) /* afs_pioctl.c */ \ + AFS_CS(PFlushAllVolumeData) /* afs_pioctl.c */ struct afs_CMCallStats { #define AFS_CS(call) afs_int32 C_ ## call; diff --git a/src/config/vioc.h b/src/config/vioc.h index caf140fb38..f6a40a3b31 100644 --- a/src/config/vioc.h +++ b/src/config/vioc.h @@ -104,6 +104,7 @@ #define VIOC_NEWUUID _CVICEIOCTL(9) /* new uuid */ #define VIOCPRECACHE _CVICEIOCTL(12) /* precache size */ #define VIOC_GETPAG _CVICEIOCTL(13) /* get pag value */ +#define VIOC_FLUSHALL _CVICEIOCTL(14) /* flush all volume data */ /* OpenAFS-specific 'O' pioctl's */ #define VIOC_NFS_NUKE_CREDS _OVICEIOCTL(1) /* nuke creds for all PAG's */ diff --git a/src/venus/fs.c b/src/venus/fs.c index 9dc26badd1..c05bfe50ca 100644 --- a/src/venus/fs.c +++ b/src/venus/fs.c @@ -1314,6 +1314,25 @@ FlushVolumeCmd(struct cmd_syndesc *as, void *arock) return error; } +static int +FlushAllVolumesCmd(struct cmd_syndesc *as, void *arock) +{ + afs_int32 code; + struct ViceIoctl blob; + int error = 0; + + blob.in_size = 0; + blob.out_size = AFS_PIOCTL_MAXSIZE; + blob.out = space; + + code = pioctl(NULL, VIOC_FLUSHALL, &blob, 0); + if (code) { + fprintf(stderr, "Error flushing all volumes\n"); + error = 1; + } + return error; +} + /* * The Windows version of UuidCmd displays the UUID. * When the UNIX version is updated to do the same @@ -3869,6 +3888,8 @@ defect 3069 "flush all data in volume"); cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path"); + cmd_CreateSyntax("flushall", FlushAllVolumesCmd, NULL, "flush all data from the cache"); + ts = cmd_CreateSyntax("sysname", SysNameCmd, NULL, "get/set sysname (i.e. @sys) value"); cmd_AddParm(ts, "-newsys", CMD_LIST, CMD_OPTIONAL, "new sysname");