static_inline int
afs_pd_alloc(struct afs_pdata *apd, size_t size)
{
-
- if (size > AFS_LRALLOCSIZ)
+ /* Ensure that we give caller at least one trailing guard byte
+ * for the NUL terminator. */
+ if (size >= AFS_LRALLOCSIZ)
apd->ptr = osi_Alloc(size + 1);
else
apd->ptr = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
if (apd->ptr == NULL)
return ENOMEM;
- if (size > AFS_LRALLOCSIZ)
+ /* Clear it all now, including the guard byte. */
+ if (size >= AFS_LRALLOCSIZ)
memset(apd->ptr, 0, size + 1);
else
memset(apd->ptr, 0, AFS_LRALLOCSIZ);
+ /* Don't tell the caller about the guard byte. */
apd->remaining = size;
return 0;
if (apd->ptr == NULL)
return;
- if (apd->remaining > AFS_LRALLOCSIZ)
+ if (apd->remaining >= AFS_LRALLOCSIZ)
osi_Free(apd->ptr, apd->remaining + 1);
else
osi_FreeLargeSpace(apd->ptr);
#if defined(AFS_NBSD50_ENV)
if ((fd = fd_getfile(SCARG(uap, fd))) == NULL)
return (EBADF);
-#elif defined(AFS_FBSD100_ENV)
+#elif defined(AFS_FBSD_ENV)
if ((uap->fd >= fdp->fd_nfiles)
|| ((fd = fdp->fd_ofiles[uap->fd].fde_file) == NULL))
return EBADF;
if (!ioctlDone) {
# if defined(AFS_FBSD_ENV)
-# if (__FreeBSD_version >= 900044)
return sys_ioctl(td, uap);
-# else
- return ioctl(td, uap);
-# endif
# elif defined(AFS_OBSD_ENV)
code = sys_ioctl(p, uap, retval);
# elif defined(AFS_NBSD_ENV)
dput(dp);
AFS_GLOCK();
#else
-#if defined(AFS_FBSD80_ENV)
+#if defined(AFS_FBSD_ENV)
if (VOP_ISLOCKED(vp))
VOP_UNLOCK(vp, 0);
-#endif /* AFS_FBSD80_ENV */
+#endif /* AFS_FBSD_ENV */
AFS_RELE(vp); /* put vnode back */
#endif
}
SHARED_LOCK, NULL));
/* now we've forgotten all of the access info */
- ObtainWriteLock(&afs_xcbhash, 455);
- avc->callback = 0;
- afs_DequeueCallback(avc);
- avc->f.states &= ~(CStatd | CUnique);
- ReleaseWriteLock(&afs_xcbhash);
- if (avc->f.fid.Fid.Vnode & 1 || (vType(avc) == VDIR))
- osi_dnlc_purgedp(avc);
+ afs_StaleVCacheFlags(avc, AFS_STALEVC_CLEARCB, CUnique);
/* SXW - Should we flush metadata here? */
+
return code;
}
AFS_STATCNT(PSetVolumeStatus);
if (!avc)
return EINVAL;
+ memset(&storeStat, 0, sizeof(storeStat));
tvp = afs_GetVolume(&avc->f.fid, areq, READ_LOCK);
if (tvp) {
tfid.Cell = avc->f.fid.Cell;
tfid.Fid.Volume = avc->f.fid.Fid.Volume;
if (!tfid.Fid.Unique && (avc->f.states & CForeign)) {
- tvc = afs_LookupVCache(&tfid, areq, NULL, avc, bufp);
+ tvc = afs_LookupVCache(&tfid, areq, avc, bufp);
} else {
- tvc = afs_GetVCache(&tfid, areq, NULL, NULL);
+ tvc = afs_GetVCache(&tfid, areq);
}
if (!tvc) {
code = EIO;
int i;
struct unixuser *tu = NULL;
+ if (iterator > afs_cellindex)
+ return NULL; /* no point in looking */
+
i = UHash(uid);
ObtainReadLock(&afs_xuser);
for (tu = afs_users[i]; tu; tu = tu->next) {
afs_int32 results[MAXGCSTATS];
afs_int32 flags;
struct dcache * tdc;
- int i, size;
+ int i;
AFS_STATCNT(PGetCacheSize);
tdc = afs_indexTable[i];
if (tdc){
+ afs_size_t size = tdc->validPos;
+
results[9]++;
- size = tdc->validPos;
- if ( 0 < size && size < (1<<12) ) results[10]++;
+ if ( 0 <= size && size < (1<<12) ) results[10]++;
else if (size < (1<<14) ) results[11]++;
else if (size < (1<<16) ) results[12]++;
else if (size < (1<<18) ) results[13]++;
(tc, rxconn, code, &avc->f.fid, areq,
AFS_STATS_FS_RPCIDX_GIVEUPCALLBACKS, SHARED_LOCK, NULL));
- ObtainWriteLock(&afs_xcbhash, 457);
- afs_DequeueCallback(avc);
- avc->callback = 0;
- avc->f.states &= ~(CStatd | CUnique);
- ReleaseWriteLock(&afs_xcbhash);
- if (avc->f.fid.Fid.Vnode & 1 || (vType(avc) == VDIR))
- osi_dnlc_purgedp(avc);
+ afs_StaleVCacheFlags(avc, AFS_STALEVC_CLEARCB, CUnique);
}
ReleaseWriteLock(&avc->lock);
return 0;
* This whole logic is bogus, because it relies on the newer command
* sending its 12th address as 0.
*/
- if ((afs_pd_remaining(ain) < AFS_MAXCELLHOSTS +3) * sizeof(afs_int32))
+ if (afs_pd_remaining(ain) < (AFS_MAXCELLHOSTS + 3) * sizeof(afs_int32))
return EINVAL;
newcell = afs_pd_where(ain) + (AFS_MAXCELLHOSTS + 3) * sizeof(afs_int32);
tfid.Cell = avc->f.fid.Cell;
tfid.Fid.Volume = avc->f.fid.Fid.Volume;
if (!tfid.Fid.Unique && (avc->f.states & CForeign)) {
- tvc = afs_LookupVCache(&tfid, areq, NULL, avc, bufp);
+ tvc = afs_LookupVCache(&tfid, areq, avc, bufp);
} else {
- tvc = afs_GetVCache(&tfid, areq, NULL, NULL);
+ tvc = afs_GetVCache(&tfid, areq);
}
if (!tvc) {
code = EIO;
return 0;
}
-static void
+static int
FlushVolumeData(struct VenusFid *afid, afs_ucred_t * acred)
{
afs_int32 i;
afs_int32 cell = 0;
afs_int32 volume = 0;
struct afs_q *tq, *uq;
+ int code = 0;
#ifdef AFS_DARWIN80_ENV
vnode_t vp;
#endif
continue; /* never had any data */
tdc = afs_GetValidDSlot(i);
if (!tdc) {
- continue;
+ code = EIO;
+ break;
}
if (tdc->refCount <= 1) { /* too high, in use by running sys call */
ReleaseReadLock(&tdc->tlock);
/* probably, a user is doing this, probably, because things are screwed up.
* maybe it's the dnlc's fault? */
osi_dnlc_purge();
+ return code;
}
/*!
if (!afs_resourceinit_flag) /* afs daemons haven't started yet */
return EIO; /* Inappropriate ioctl for device */
- FlushVolumeData(&avc->f.fid, *acred);
- return 0;
+ return FlushVolumeData(&avc->f.fid, *acred);
}
/*!
if (!afs_resourceinit_flag) /* afs daemons haven't started yet */
return EIO; /* Inappropriate ioctl for device */
- FlushVolumeData(NULL, *acred);
- return 0;
+ return FlushVolumeData(NULL, *acred);
}
/*!
newcred->cr_groupset.gs_union.un_groups[0] = g0;
newcred->cr_groupset.gs_union.un_groups[1] = g1;
#elif defined(AFS_LINUX26_ENV)
-# ifdef AFS_LINUX26_ONEGROUP_ENV
+# ifdef AFS_PAG_ONEGROUP_ENV
afs_set_cr_group_info(newcred, groups_alloc(1)); /* nothing sets this */
l = (((g0-0x3f00) & 0x3fff) << 14) | ((g1-0x3f00) & 0x3fff);
h = ((g0-0x3f00) >> 14);
GROUP_AT(afs_cr_group_info(newcred), 1) = g1;
# endif
#elif defined(AFS_SUN510_ENV)
+# ifdef AFS_PAG_ONEGROUP_ENV
+ gids[0] = afs_get_pag_from_groups(g0, g1);
+ crsetgroups(newcred, 1, gids);
+# else
gids[0] = g0;
gids[1] = g1;
crsetgroups(newcred, 2, gids);
+# endif /* !AFS_PAG_ONEGROUP_ENV */
#else
newcred->cr_groups[0] = g0;
newcred->cr_groups[1] = g1;
#ifdef AFS_AIX_ENV
newcred->cr_ngrps = 2;
#elif !defined(AFS_LINUX26_ENV) && !defined(AFS_SUN510_ENV)
-# if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX22_ENV) || defined(AFS_FBSD80_ENV)
+# if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX22_ENV) || defined(AFS_FBSD_ENV)
newcred->cr_ngroups = 2;
# else
for (i = 2; i < NGROUPS; i++)
if (ainSize < sizeof(struct setspref))
return EINVAL;
-#if 0 /* num_servers is unsigned */
- if (sin->num_servers < 0)
- return EINVAL;
-#endif
if (sin->num_servers > AFS_MAX_INTERFACE_ADDR)
return ENOMEM;
tfid.Cell = avc->f.fid.Cell;
tfid.Fid.Volume = avc->f.fid.Fid.Volume;
if (!tfid.Fid.Unique && (avc->f.states & CForeign)) {
- tvc = afs_LookupVCache(&tfid, areq, NULL, avc, bufp);
+ tvc = afs_LookupVCache(&tfid, areq, avc, bufp);
} else {
- tvc = afs_GetVCache(&tfid, areq, NULL, NULL);
+ tvc = afs_GetVCache(&tfid, areq);
}
if (!tvc) {
code = EIO;
goto out;
}
ObtainWriteLock(&tvc->lock, 649);
- ObtainWriteLock(&afs_xcbhash, 650);
- afs_DequeueCallback(tvc);
- tvc->f.states &= ~(CStatd | CDirty); /* next reference will re-stat cache entry */
- ReleaseWriteLock(&afs_xcbhash);
+ /* next reference will re-stat cache entry */
+ afs_StaleVCacheFlags(tvc, 0, CDirty);
/* now find the disk cache entries */
afs_TryToSmush(tvc, *acred, 1);
- osi_dnlc_purgedp(tvc);
if (tvc->linkData && !(tvc->f.states & CCore)) {
afs_osi_Free(tvc->linkData, strlen(tvc->linkData) + 1);
tvc->linkData = NULL;
tfid.Fid.Vnode = Fid->Vnode;
tfid.Fid.Unique = Fid->Unique;
- tvc = afs_GetVCache(&tfid, areq, NULL, NULL);
+ tvc = afs_GetVCache(&tfid, areq);
if (!tvc) {
afs_Trace3(afs_iclSetp, CM_TRACE_PREFETCHCMD, ICL_TYPE_POINTER, tvc,
ICL_TYPE_FID, &tfid, ICL_TYPE_FID, &avc->f.fid);
tfid.Fid.Vnode = Fid->Vnode;
tfid.Fid.Unique = Fid->Unique;
- tvc = afs_GetVCache(&tfid, areq, NULL, NULL);
+ tvc = afs_GetVCache(&tfid, areq);
afs_Trace3(afs_iclSetp, CM_TRACE_RESIDCMD, ICL_TYPE_POINTER, tvc,
ICL_TYPE_INT32, Inputs->command, ICL_TYPE_FID, &tfid);
if (!tvc)
DECL_PIOCTL(PCallBackAddr)
{
#ifndef UKERNEL
- afs_uint32 addr, code;
+ afs_uint32 code;
int srvAddrCount;
struct server *ts;
struct srvAddr *sa;
struct afs_conn *tc;
- afs_int32 i, j;
+ afs_int32 i, j, addr;
struct unixuser *tu;
struct srvAddr **addrs;
struct rx_connection *rxconn;
if (!afs_resourceinit_flag) /* afs deamons havn't started yet */
return EIO; /* Inappropriate ioctl for device */
- if (!afs_osi_suser(acred))
+ if (!afs_osi_suser(*acred))
return EACCES;
if (afs_pd_getInt(ain, &addr) != 0)
}
afs_PutConn(tc, rxconn, SHARED_LOCK); /* done with it now */
} /* Outer loop over addrs */
+ afs_osi_Free(addrs, srvAddrCount * sizeof(*addrs));
#endif /* UKERNEL */
return 0;
}
return code;
}
+/*!
+ * VIOC_GETTOK2 (7) - Return a user's nth token, or token for a cell by
+ * name.
+ *
+ * \ingroup pioctl
+ *
+ * \param[in] ain EITHER a string cellname
+ * OR an integer 'iterator' to specify the nth
+ * token.
+ *
+ * \param[out] aout XDR-encoded tokens from the user's tokenJar
+ *
+ * \retval EINVAL invalid input (bad integer, or invalid string)
+ * unable to extract token(s)
+ * \retval ENOMEM insufficient memory (returned from called routines)
+ * \retval EDOM (integer) request was out of bounds or the user has no tokens
+ * \retval ENOTCONN user found but has no valid token(s)
+ * \retval E2BIG token(s) do not fit in the output buffer
+ *
+ */
DECL_PIOCTL(PGetTokens2)
{
struct cell *cell = NULL;
char *cellName = NULL;
afs_int32 cellNum;
int code = 0;
+ int integer_in = 1; /* assume integer input */
time_t now;
XDR xdrs;
struct ktc_setTokenData tokenSet;
memset(&tokenSet, 0, sizeof(tokenSet));
/* No input data - return tokens for primary cell */
- /* 4 octets of data is an iterator count */
+ /* 4 octets of data is PROBABLY an iterator count */
/* Otherwise, treat as string & return tokens for that cell name */
if (afs_pd_remaining(ain) == sizeof(afs_int32)) {
- /* Integer iterator - return tokens for the n'th cell found for user */
+ char *scratch = afs_pd_where(ain);
+
+ if (scratch[3] == '\0' && strlen(scratch) == 3)
+ integer_in = 0;
+ } else {
+ integer_in = 0;
+ }
+
+ if (integer_in) {
+ /* The misleadingly-named getNthCell actually return the nth valid
+ * token found for the specified user; there can never be a gap
+ * in the ordinals at this level.
+ */
if (afs_pd_getInt(ain, &iterator) != 0)
return EINVAL;
tu = getNthCell(areq->uid, iterator);
return EACCES;
}
afs_PutUser(tu, SHARED_LOCK);
- } else if (!afs_osi_suser(acred)) {
+ } else if (!afs_osi_suser(*acred)) {
return EACCES;
}