#include "rx/rx_globals.h"
#include "token.h"
+extern int afs_rmtsys_enable;
struct VenusFid afs_rootFid;
afs_int32 afs_waitForever = 0;
short afs_waitForeverCount = 0;
DECL_PIOCTL(PGetCellStatus);
DECL_PIOCTL(PSetCellStatus);
DECL_PIOCTL(PFlushVolumeData);
+DECL_PIOCTL(PFlushAllVolumeData);
DECL_PIOCTL(PGetVnodeXStatus);
DECL_PIOCTL(PGetVnodeXStatus2);
DECL_PIOCTL(PSetSysName);
PBogus, /* 11 */
PPrecache, /* 12 */
PGetPAG, /* 13 */
+ PFlushAllVolumeData, /* 14 */
};
static pioctlFunction OpioctlSw[] = {
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
*/
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);
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);
AFS_FAST_RELE(tvc);
}
}
+ }
ReleaseReadLock(&afs_xvcache);
}
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
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;
}
/* 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
return EINVAL;
num = count;
}
- if (afs_cr_gid(*acred) == RMTUSER_REQ ||
- afs_cr_gid(*acred) == RMTUSER_REQ_PRIV) { /* Handles all exporters */
+ if (afs_rmtsys_enable && (afs_cr_gid(*acred) == RMTUSER_REQ ||
+ afs_cr_gid(*acred) == RMTUSER_REQ_PRIV)) { /* Handles all exporters */
if (allpags && afs_cr_gid(*acred) != RMTUSER_REQ_PRIV) {
return EPERM;
}
cache_bypass_threshold = threshold;
afs_warn("Cache Bypass Threshold set to: %d\n", threshold);
/* TODO: move to separate pioctl, or enhance pioctl */
- cache_bypass_strategy = LARGE_FILES_BYPASS_CACHE;
+ if (threshold == AFS_CACHE_BYPASS_DISABLED)
+ cache_bypass_strategy = NEVER_BYPASS_CACHE;
+ else if (!threshold)
+ cache_bypass_strategy = ALWAYS_BYPASS_CACHE;
+ else
+ cache_bypass_strategy = LARGE_FILES_BYPASS_CACHE;
}
/* Return the current size threshold */
}
if (tokenSet.flags & AFSTOKEN_EX_SETPAG) {
+#if defined(AFS_LINUX26_ENV)
+ afs_ucred_t *old_cred = *acred;
+#endif
if (_settok_setParentPag(acred) == 0) {
+#if defined(AFS_LINUX26_ENV)
+ /* setpag() may have changed our credentials */
+ *acred = crref();
+ crfree(old_cred);
+#endif
afs_InitReq(&treq, *acred);
areq = &treq;
}