#include "afs/vice.h"
#include "afs/afs_bypasscache.h"
#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;
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;
+ /* 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);
}
static_inline int
-afs_pd_getInt(struct afs_pdata *apd, afs_int32 *val)
+afs_pd_getBytes(struct afs_pdata *apd, void *dest, size_t bytes)
{
- if (apd == NULL || apd->remaining < sizeof(afs_int32))
+ if (apd == NULL || apd->remaining < bytes)
return EINVAL;
- apd->remaining -= sizeof(afs_int32);
- *val = *(afs_int32 *)apd->ptr;
- apd->ptr += sizeof(afs_int32);
+ apd->remaining -= bytes;
+ memcpy(dest, apd->ptr, bytes);
+ apd->ptr += bytes;
return 0;
}
static_inline int
-afs_pd_getUint(struct afs_pdata *apd, afs_uint32 *val)
+afs_pd_getInt(struct afs_pdata *apd, afs_int32 *val)
{
- return afs_pd_getInt(apd, (afs_int32 *)val);
+ return afs_pd_getBytes(apd, val, sizeof(*val));
}
static_inline int
-afs_pd_getBytes(struct afs_pdata *apd, void *dest, size_t bytes)
+afs_pd_getUint(struct afs_pdata *apd, afs_uint32 *val)
{
- if (apd == NULL || apd->remaining < bytes)
- return EINVAL;
- apd->remaining -= bytes;
- memcpy(dest, apd->ptr, bytes);
- apd->ptr += bytes;
- return 0;
+ return afs_pd_getBytes(apd, val, sizeof(*val));
}
static_inline void *
return ret;
}
+static_inline void
+afs_pd_xdrStart(struct afs_pdata *apd, XDR *xdrs, enum xdr_op op) {
+ xdrmem_create(xdrs, apd->ptr, apd->remaining, op);
+}
+
+static_inline void
+afs_pd_xdrEnd(struct afs_pdata *apd, XDR *xdrs) {
+ size_t pos;
+
+ pos = xdr_getpos(xdrs);
+ apd->ptr += pos;
+ apd->remaining -= pos;
+ xdr_destroy(xdrs);
+}
+
+
+
static_inline int
afs_pd_getString(struct afs_pdata *apd, char *str, size_t maxLen)
{
}
static_inline int
-afs_pd_putInt(struct afs_pdata *apd, afs_int32 val)
-{
- if (apd == NULL || apd->remaining < sizeof(afs_int32))
- return E2BIG;
- *(afs_int32 *)apd->ptr = val;
- apd->ptr += sizeof(afs_int32);
- apd->remaining -= sizeof(afs_int32);
-
- return 0;
-}
-
-static_inline int
afs_pd_putBytes(struct afs_pdata *apd, const void *bytes, size_t len)
{
if (apd == NULL || apd->remaining < len)
}
static_inline int
+afs_pd_putInt(struct afs_pdata *apd, afs_int32 val)
+{
+ return afs_pd_putBytes(apd, &val, sizeof(val));
+}
+
+static_inline int
afs_pd_putString(struct afs_pdata *apd, char *str) {
/* Add 1 so we copy the NULL too */
DECL_PIOCTL(PGetWSCell);
DECL_PIOCTL(PGetUserCell);
DECL_PIOCTL(PSetTokens);
+DECL_PIOCTL(PSetTokens2);
DECL_PIOCTL(PGetVolumeStatus);
DECL_PIOCTL(PSetVolumeStatus);
DECL_PIOCTL(PFlush);
DECL_PIOCTL(PNewStatMount);
DECL_PIOCTL(PGetTokens);
+DECL_PIOCTL(PGetTokens2);
DECL_PIOCTL(PUnlog);
DECL_PIOCTL(PMariner);
DECL_PIOCTL(PCheckServers);
DECL_PIOCTL(PGetCellStatus);
DECL_PIOCTL(PSetCellStatus);
DECL_PIOCTL(PFlushVolumeData);
+DECL_PIOCTL(PFlushAllVolumeData);
DECL_PIOCTL(PGetVnodeXStatus);
DECL_PIOCTL(PGetVnodeXStatus2);
DECL_PIOCTL(PSetSysName);
DECL_PIOCTL(PDiscon);
DECL_PIOCTL(PNFSNukeCreds);
DECL_PIOCTL(PNewUuid);
-DECL_PIOCTL(PPrecache);
+DECL_PIOCTL(PPrecache);
DECL_PIOCTL(PGetPAG);
-#if defined(AFS_CACHE_BYPASS)
+#if defined(AFS_CACHE_BYPASS) && defined(AFS_LINUX24_ENV)
DECL_PIOCTL(PSetCachingThreshold);
#endif
afs_ucred_t **acred,
afs_ucred_t *credp);
#endif
-int HandleIoctl(register struct vcache *avc, register afs_int32 acom,
+int HandleIoctl(struct vcache *avc, afs_int32 acom,
struct afs_ioctl *adata);
int afs_HandlePioctl(struct vnode *avp, afs_int32 acom,
- register struct afs_ioctl *ablob, int afollow,
+ struct afs_ioctl *ablob, int afollow,
afs_ucred_t **acred);
static int Prefetch(uparmtype apath, struct afs_ioctl *adata, int afollow,
afs_ucred_t *acred);
PBogus, /* 4 */
PDiscon, /* 5 -- get/set discon mode */
PBogus, /* 6 */
- PBogus, /* 7 */
- PBogus, /* 8 */
+ PGetTokens2, /* 7 */
+ PSetTokens2, /* 8 */
PNewUuid, /* 9 */
PBogus, /* 10 */
PBogus, /* 11 */
PPrecache, /* 12 */
PGetPAG, /* 13 */
+ PFlushAllVolumeData, /* 14 */
};
static pioctlFunction OpioctlSw[] = {
PBogus, /* 0 */
PNFSNukeCreds, /* 1 -- nuke all creds for NFS client */
-#if defined(AFS_CACHE_BYPASS)
+#if defined(AFS_CACHE_BYPASS) && defined(AFS_LINUX24_ENV)
PSetCachingThreshold /* 2 -- get/set cache-bypass size threshold */
#else
PNoop /* 2 -- get/set cache-bypass size threshold */
int afs_nobody = NFS_NOBODY;
int
-HandleIoctl(register struct vcache *avc, register afs_int32 acom,
+HandleIoctl(struct vcache *avc, afs_int32 acom,
struct afs_ioctl *adata)
{
- register afs_int32 code;
+ afs_int32 code;
code = 0;
AFS_STATCNT(HandleIoctl);
case 3:{
/* return the name of the cell this file is open on */
- register struct cell *tcell;
- register afs_int32 i;
+ struct cell *tcell;
+ afs_int32 i;
tcell = afs_GetCell(avc->f.fid.Cell, READ_LOCK);
if (tcell) {
# endif
} u_uap, *uap = &u_uap;
struct file *fd;
- register struct vcache *tvc;
- register int ioctlDone = 0, code = 0;
+ struct vcache *tvc;
+ int ioctlDone = 0, code = 0;
AFS_STATCNT(afs_xioctl);
uap->fd = fdes;
if (tvc && IsAfsVnode(AFSTOV(tvc))) {
/* This is an AFS vnode */
if (((uap->com >> 8) & 0xff) == 'V') {
- register struct afs_ioctl *datap;
+ struct afs_ioctl *datap;
AFS_GLOCK();
- datap =
- (struct afs_ioctl *)osi_AllocSmallSpace(AFS_SMALLOCSIZ);
+ datap = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
code=copyin_afs_ioctl((char *)uap->arg, datap);
if (code) {
osi_FreeSmallSpace(datap);
int arg;
};
-int
+int
afs_xioctl(struct afs_ioctl_sys *uap, rval_t *rvp)
{
struct file *fd;
- register struct vcache *tvc;
- register int ioctlDone = 0, code = 0;
+ struct vcache *tvc;
+ int ioctlDone = 0, code = 0;
AFS_STATCNT(afs_xioctl);
-# if defined(AFS_SUN57_ENV)
fd = getf(uap->fd);
if (!fd)
return (EBADF);
-# elif defined(AFS_SUN54_ENV)
- fd = GETF(uap->fd);
- if (!fd)
- return (EBADF);
-# else
- if (code = getf(uap->fd, &fd)) {
- return (code);
- }
-# endif
if (fd->f_vnode->v_type == VREG || fd->f_vnode->v_type == VDIR) {
tvc = VTOAFS(fd->f_vnode); /* valid, given a vnode */
if (tvc && IsAfsVnode(AFSTOV(tvc))) {
/* This is an AFS vnode */
if (((uap->com >> 8) & 0xff) == 'V') {
- register struct afs_ioctl *datap;
+ struct afs_ioctl *datap;
AFS_GLOCK();
- datap =
- (struct afs_ioctl *)osi_AllocSmallSpace(AFS_SMALLOCSIZ);
+ datap = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
code=copyin_afs_ioctl((char *)uap->arg, datap);
if (code) {
osi_FreeSmallSpace(datap);
AFS_GUNLOCK();
-# if defined(AFS_SUN54_ENV)
releasef(uap->fd);
-# else
- releasef(fd);
-# endif
return (EFAULT);
}
code = HandleIoctl(tvc, uap->com, datap);
}
}
}
-# if defined(AFS_SUN57_ENV)
releasef(uap->fd);
-# elif defined(AFS_SUN54_ENV)
- RELEASEF(uap->fd);
-# else
- releasef(fd);
-# endif
if (!ioctlDone)
code = ioctl(uap, rvp);
unsigned long arg)
{
struct afs_ioctl_sys ua, *uap = &ua;
- register struct vcache *tvc;
- register int ioctlDone = 0, code = 0;
+ struct vcache *tvc;
+ int code = 0;
AFS_STATCNT(afs_xioctl);
ua.com = com;
if (tvc && IsAfsVnode(AFSTOV(tvc))) {
/* This is an AFS vnode */
if (((uap->com >> 8) & 0xff) == 'V') {
- register struct afs_ioctl *datap;
+ struct afs_ioctl *datap;
AFS_GLOCK();
datap = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
code = copyin_afs_ioctl((char *)uap->arg, datap);
code = HandleIoctl(tvc, uap->com, datap);
osi_FreeSmallSpace(datap);
AFS_GUNLOCK();
- ioctlDone = 1;
}
else
code = EINVAL;
};
int
-afs_xioctl(afs_proc_t *p, register struct ioctl_args *uap, register_t *retval)
+afs_xioctl(afs_proc_t *p, struct ioctl_args *uap, register_t *retval)
{
struct file *fd;
- register struct vcache *tvc;
- register int ioctlDone = 0, code = 0;
+ struct vcache *tvc;
+ int ioctlDone = 0, code = 0;
AFS_STATCNT(afs_xioctl);
if ((code = fdgetf(p, uap->fd, &fd)))
if (tvc && IsAfsVnode(AFSTOV(tvc))) {
/* This is an AFS vnode */
if (((uap->com >> 8) & 0xff) == 'V') {
- register struct afs_ioctl *datap;
+ struct afs_ioctl *datap;
AFS_GLOCK();
datap = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
code = copyin_afs_ioctl((char *)uap->arg, datap);
# if defined(AFS_FBSD_ENV)
# define arg data
int
-afs_xioctl(struct thread *td, register struct ioctl_args *uap,
+afs_xioctl(struct thread *td, struct ioctl_args *uap,
register_t *retval)
{
afs_proc_t *p = td->td_proc;
+# elif defined(AFS_NBSD_ENV)
+int
+afs_xioctl(afs_proc_t *p, const struct sys_ioctl_args *uap, register_t *retval)
+{
# else
struct ioctl_args {
int fd;
};
int
-afs_xioctl(afs_proc_t *p, register struct ioctl_args *uap, register_t *retval)
+afs_xioctl(afs_proc_t *p, const struct ioctl_args *uap, register_t *retval)
{
# endif
- register struct filedesc *fdp;
- register struct vcache *tvc;
- register int ioctlDone = 0, code = 0;
+ struct filedesc *fdp;
+ struct vcache *tvc;
+ int ioctlDone = 0, code = 0;
struct file *fd;
AFS_STATCNT(afs_xioctl);
-# if defined(AFS_NBSD40_ENV)
- fdp = p->l_proc->p_fd;
-# else
+#if defined(AFS_NBSD40_ENV)
+ fdp = p->l_proc->p_fd;
+#else
fdp = p->p_fd;
#endif
- if ((u_int) uap->fd >= fdp->fd_nfiles
- || (fd = fdp->fd_ofiles[uap->fd]) == NULL)
+#if defined(AFS_NBSD50_ENV)
+ if ((fd = fd_getfile(SCARG(uap, fd))) == NULL)
+ return (EBADF);
+#elif defined(AFS_FBSD100_ENV)
+ if ((uap->fd >= fdp->fd_nfiles)
+ || ((fd = fdp->fd_ofiles[uap->fd].fde_file) == NULL))
+ return EBADF;
+#else
+ if ((uap->fd >= fdp->fd_nfiles)
+ || ((fd = fdp->fd_ofiles[uap->fd]) == NULL))
return EBADF;
+#endif
if ((fd->f_flag & (FREAD | FWRITE)) == 0)
return EBADF;
/* first determine whether this is any sort of vnode */
# else
tvc = VTOAFS((struct vnode *)fd->f_data); /* valid, given a vnode */
# endif
- if (tvc && IsAfsVnode(AFSTOV(tvc))) {
+ if (tvc && IsAfsVnode((struct vnode *)fd->f_data)) {
/* This is an AFS vnode */
- if (((uap->com >> 8) & 0xff) == 'V') {
- register struct afs_ioctl *datap;
+#if defined(AFS_NBSD50_ENV)
+ if (((SCARG(uap, com) >> 8) & 0xff) == 'V') {
+#else
+ if (((uap->com >> 8) & 0xff) == 'V') {
+#endif
+ struct afs_ioctl *datap;
AFS_GLOCK();
datap = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
+#if defined(AFS_NBSD50_ENV)
+ code = copyin_afs_ioctl(SCARG(uap, data), datap);
+#else
code = copyin_afs_ioctl((char *)uap->arg, datap);
+#endif
if (code) {
osi_FreeSmallSpace(datap);
AFS_GUNLOCK();
return code;
}
+#if defined(AFS_NBSD50_ENV)
+ code = HandleIoctl(tvc, SCARG(uap, com), datap);
+#else
code = HandleIoctl(tvc, uap->com, datap);
+#endif
osi_FreeSmallSpace(datap);
AFS_GUNLOCK();
ioctlDone = 1;
}
}
+#if defined(AFS_NBSD50_ENV)
+ fd_putfile(SCARG(uap, fd));
+#endif
+
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)
- struct lwp *l = osi_curproc();
- code = sys_ioctl(l, uap, retval);
+ code = sys_ioctl(p, uap, retval);
# endif
}
int
afs_xioctl(void)
{
- register struct a {
+ struct a {
int fd;
int com;
caddr_t arg;
} *uap = (struct a *)get_user_struct()->u_ap;
- register struct file *fd;
- register struct vcache *tvc;
- register int ioctlDone = 0, code = 0;
+ struct file *fd;
+ struct vcache *tvc;
+ int ioctlDone = 0, code = 0;
AFS_STATCNT(afs_xioctl);
if (tvc && IsAfsVnode(AFSTOV(tvc))) {
/* This is an AFS vnode */
if (((uap->com >> 8) & 0xff) == 'V') {
- register struct afs_ioctl *datap;
+ struct afs_ioctl *datap;
AFS_GLOCK();
datap = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
code=copyin_afs_ioctl((char *)uap->arg, datap);
int
#ifdef AFS_SUN5_ENV
-afs_syscall_pioctl(char *path, unsigned int com, caddr_t cmarg, int follow,
+afs_syscall_pioctl(char *path, unsigned int com, caddr_t cmarg, int follow,
rval_t *vvp, afs_ucred_t *credp)
#else
#ifdef AFS_DARWIN100_ENV
afs_syscall64_pioctl(user_addr_t path, unsigned int com, user_addr_t cmarg,
int follow, afs_ucred_t *credp)
#elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
-afs_syscall_pioctl(char *path, unsigned int com, caddr_t cmarg, int follow,
+afs_syscall_pioctl(char *path, unsigned int com, caddr_t cmarg, int follow,
afs_ucred_t *credp)
#else
afs_syscall_pioctl(char *path, unsigned int com, caddr_t cmarg, int follow)
#if defined(AFS_NEED_CLIENTCONTEXT) || defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV) || defined(AFS_LINUX22_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
afs_ucred_t *foreigncreds = NULL;
#endif
- register afs_int32 code = 0;
+ afs_int32 code = 0;
struct vnode *vp = NULL;
#ifdef AFS_AIX41_ENV
struct ucred *credp = crref(); /* don't free until done! */
vp = (struct vnode *)dp->d_inode;
#else
code = gop_lookupname_user(path, AFS_UIOUSER, follow, &vp);
-#if defined(AFS_FBSD80_ENV) /* XXX check on 7x */
- if (vp != NULL)
- VN_HOLD(vp);
-#endif /* AFS_FBSD80_ENV */
#endif /* AFS_LINUX22_ENV */
#endif /* AFS_AIX41_ENV */
AFS_GLOCK();
struct vnode *realvp;
if
#ifdef AFS_SUN511_ENV
- (VOP_REALVP(vp, &realvp, NULL) == 0)
+ (VOP_REALVP(vp, &realvp, NULL) == 0)
#else
- (VOP_REALVP(vp, &realvp) == 0)
+ (VOP_REALVP(vp, &realvp) == 0)
#endif
{
struct vnode *oldvp = vp;
-
+
VN_HOLD(realvp);
vp = realvp;
AFS_RELE(oldvp);
#endif /* AFS_NEED_CLIENTCONTEXT */
if (vp) {
#ifdef AFS_LINUX22_ENV
+ /*
+ * Holding the global lock when calling dput can cause a deadlock
+ * when the kernel calls back into afs_dentry_iput
+ */
+ AFS_GUNLOCK();
dput(dp);
+ AFS_GLOCK();
#else
#if defined(AFS_FBSD80_ENV)
if (VOP_ISLOCKED(vp))
int
afs_HandlePioctl(struct vnode *avp, afs_int32 acom,
- register struct afs_ioctl *ablob, int afollow,
+ struct afs_ioctl *ablob, int afollow,
afs_ucred_t **acred)
{
struct vcache *avc;
- struct vrequest treq;
- register afs_int32 code;
- register afs_int32 function, device;
+ struct vrequest *treq = NULL;
+ afs_int32 code;
+ afs_int32 function, device;
struct afs_pdata input, output;
struct afs_pdata copyInput, copyOutput;
size_t outSize;
ICL_TYPE_POINTER, avc, ICL_TYPE_INT32, afollow);
AFS_STATCNT(HandlePioctl);
- code = afs_InitReq(&treq, *acred);
+ code = afs_CreateReq(&treq, *acred);
if (code)
return code;
afs_InitFakeStat(&fakestate);
if (avc) {
- code = afs_EvalFakeStat(&avc, &fakestate, &treq);
+ code = afs_EvalFakeStat(&avc, &fakestate, treq);
if (code)
goto out;
}
if (code)
goto out;
- if (function == 8 && device == 'V') { /* PGetTokens */
+ if ((function == 8 && device == 'V') ||
+ (function == 7 && device == 'C')) { /* PGetTokens */
code = afs_pd_alloc(&output, MAXPIOCTLTOKENLEN);
} else {
code = afs_pd_alloc(&output, AFS_LRALLOCSIZ);
copyOutput = output;
code =
- (*pioctlSw[function]) (avc, function, &treq, ©Input,
+ (*pioctlSw[function]) (avc, function, treq, ©Input,
©Output, acred);
outSize = copyOutput.ptr - output.ptr;
afs_pd_free(&output);
afs_PutFakeStat(&fakestate);
- return afs_CheckCode(code, &treq, 41);
+ code = afs_CheckCode(code, treq, 41);
+ afs_DestroyReq(treq);
+ return code;
}
/*!
DECL_PIOCTL(PSetAcl)
{
- register afs_int32 code;
+ afs_int32 code;
struct afs_conn *tconn;
struct AFSOpaque acl;
struct AFSVolSync tsync;
struct AFSFetchStatus OutStatus;
+ struct rx_connection *rxconn;
XSTATS_DECLS;
AFS_STATCNT(PSetAcl);
return EINVAL;
do {
- tconn = afs_Conn(&avc->f.fid, areq, SHARED_LOCK);
+ tconn = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn);
if (tconn) {
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_STOREACL);
RX_AFS_GUNLOCK();
code =
- RXAFS_StoreACL(tconn->id, (struct AFSFid *)&avc->f.fid.Fid,
+ RXAFS_StoreACL(rxconn, (struct AFSFid *)&avc->f.fid.Fid,
&acl, &OutStatus, &tsync);
RX_AFS_GLOCK();
XSTATS_END_TIME;
} else
code = -1;
} while (afs_Analyze
- (tconn, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_STOREACL,
+ (tconn, rxconn, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_STOREACL,
SHARED_LOCK, NULL));
/* now we've forgotten all of the access info */
afs_int32 code;
struct afs_conn *tconn;
struct AFSFid Fid;
+ struct rx_connection *rxconn;
XSTATS_DECLS;
AFS_STATCNT(PGetAcl);
}
acl.AFSOpaque_val = aout->ptr;
do {
- tconn = afs_Conn(&avc->f.fid, areq, SHARED_LOCK);
+ tconn = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn);
if (tconn) {
acl.AFSOpaque_val[0] = '\0';
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_FETCHACL);
RX_AFS_GUNLOCK();
- code = RXAFS_FetchACL(tconn->id, &Fid, &acl, &OutStatus, &tsync);
+ code = RXAFS_FetchACL(rxconn, &Fid, &acl, &OutStatus, &tsync);
RX_AFS_GLOCK();
XSTATS_END_TIME;
} else
code = -1;
} while (afs_Analyze
- (tconn, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_FETCHACL,
+ (tconn, rxconn, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_FETCHACL,
SHARED_LOCK, NULL));
if (code == 0) {
*/
DECL_PIOCTL(PGetFileCell)
{
- register struct cell *tcell;
+ struct cell *tcell;
AFS_STATCNT(PGetFileCell);
if (!avc)
*/
DECL_PIOCTL(PGetUserCell)
{
- register afs_int32 i;
- register struct unixuser *tu;
- register struct cell *tcell;
+ afs_int32 i;
+ struct unixuser *tu;
+ struct cell *tcell;
AFS_STATCNT(PGetUserCell);
if (!afs_resourceinit_flag) /* afs daemons haven't started yet */
if (tu->uid == areq->uid && (tu->states & UPrimary)) {
tu->refCount++;
ReleaseWriteLock(&afs_xuser);
+ afs_LockUser(tu, READ_LOCK, 0);
break;
}
}
if (tu) {
tcell = afs_GetCell(tu->cell, READ_LOCK);
- afs_PutUser(tu, WRITE_LOCK);
+ afs_PutUser(tu, READ_LOCK);
if (!tcell)
return ESRCH;
else {
return 0;
}
+/* Work out which cell we're changing tokens for */
+static_inline int
+_settok_tokenCell(char *cellName, int *cellNum, int *primary) {
+ int t1;
+ struct cell *cell;
+
+ if (primary) {
+ *primary = 0;
+ }
+
+ if (cellName && strlen(cellName) > 0) {
+ cell = afs_GetCellByName(cellName, READ_LOCK);
+ } else {
+ cell = afs_GetPrimaryCell(READ_LOCK);
+ if (primary)
+ *primary = 1;
+ }
+ if (!cell) {
+ t1 = afs_initState;
+ if (t1 < 101)
+ return EIO;
+ else
+ return ESRCH;
+ }
+ *cellNum = cell->cellNum;
+ afs_PutCell(cell, READ_LOCK);
+
+ return 0;
+}
+
+
+static_inline int
+_settok_setParentPag(afs_ucred_t **cred) {
+ afs_uint32 pag;
+#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+ char procname[256];
+ osi_procname(procname, 256);
+ afs_warnuser("Process %d (%s) tried to change pags in PSetTokens\n",
+ MyPidxx2Pid(MyPidxx), procname);
+ return setpag(osi_curproc(), cred, -1, &pag, 1);
+#else
+ return setpag(cred, -1, &pag, 1);
+#endif
+}
+
/*!
* VIOCSETTOK (3) - Set authentication tokens
*
*/
DECL_PIOCTL(PSetTokens)
{
- afs_int32 i;
- register struct unixuser *tu;
+ afs_int32 cellNum;
+ afs_int32 size;
+ afs_int32 code;
+ struct unixuser *tu;
struct ClearToken clear;
- register struct cell *tcell;
char *stp;
char *cellName;
int stLen;
- struct vrequest treq;
+ struct vrequest *treq = NULL;
afs_int32 flag, set_parent_pag = 0;
AFS_STATCNT(PSetTokens);
if (afs_pd_skip(ain, stLen) != 0)
return EINVAL;
- if (afs_pd_getInt(ain, &i) != 0)
+ if (afs_pd_getInt(ain, &size) != 0)
return EINVAL;
- if (i != sizeof(struct ClearToken))
+ if (size != sizeof(struct ClearToken))
return EINVAL;
if (afs_pd_getBytes(ain, &clear, sizeof(struct ClearToken)) !=0)
if (afs_pd_getStringPtr(ain, &cellName) != 0)
return EINVAL;
- /* rest is cell name, look it up */
- tcell = afs_GetCellByName(cellName, READ_LOCK);
- if (!tcell)
- goto nocell;
+ code = _settok_tokenCell(cellName, &cellNum, NULL);
+ if (code)
+ return code;
} else {
/* default to primary cell, primary id */
- flag = 1; /* primary id */
- tcell = afs_GetPrimaryCell(READ_LOCK);
- if (!tcell)
- goto nocell;
+ code = _settok_tokenCell(NULL, &cellNum, &flag);
+ if (code)
+ return code;
}
- i = tcell->cellNum;
- afs_PutCell(tcell, READ_LOCK);
+
if (set_parent_pag) {
- afs_uint32 pag;
-#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
- char procname[256];
- osi_procname(procname, 256);
- afs_warnuser("Process %d (%s) tried to change pags in PSetTokens\n",
- MyPidxx2Pid(MyPidxx), procname);
- if (!setpag(osi_curproc(), acred, -1, &pag, 1)) {
-#else
- if (!setpag(acred, -1, &pag, 1)) {
-#endif
- afs_InitReq(&treq, *acred);
- areq = &treq;
+ if (_settok_setParentPag(acred) == 0) {
+ code = afs_CreateReq(&treq, *acred);
+ if (code) {
+ return code;
+ }
+ areq = treq;
}
}
+
/* now we just set the tokens */
- tu = afs_GetUser(areq->uid, i, WRITE_LOCK); /* i has the cell # */
- tu->vid = clear.ViceId;
- if (tu->stp != NULL) {
- afs_osi_Free(tu->stp, tu->stLen);
- }
- tu->stp = (char *)afs_osi_Alloc(stLen);
- if (tu->stp == NULL) {
- return ENOMEM;
- }
- tu->stLen = stLen;
- memcpy(tu->stp, stp, stLen);
- tu->ct = clear;
+ tu = afs_GetUser(areq->uid, cellNum, WRITE_LOCK);
+ /* Set tokens destroys any that are already there */
+ afs_FreeTokens(&tu->tokens);
+ afs_AddRxkadToken(&tu->tokens, stp, stLen, &clear);
#ifndef AFS_NOSTATS
afs_stats_cmfullperf.authent.TicketUpdates++;
afs_ComputePAGStats();
afs_ResetUserConns(tu);
afs_NotifyUser(tu, UTokensObtained);
afs_PutUser(tu, WRITE_LOCK);
+ afs_DestroyReq(treq);
return 0;
-
- nocell:
- {
- int t1;
- t1 = afs_initState;
- if (t1 < 101)
- return EIO;
- else
- return ESRCH;
- }
}
/*!
char volName[32];
char *offLineMsg = afs_osi_Alloc(256);
char *motd = afs_osi_Alloc(256);
- register struct afs_conn *tc;
- register afs_int32 code = 0;
+ struct afs_conn *tc;
+ afs_int32 code = 0;
struct AFSFetchVolumeStatus volstat;
char *Name;
+ struct rx_connection *rxconn;
XSTATS_DECLS;
+ osi_Assert(offLineMsg != NULL);
+ osi_Assert(motd != NULL);
AFS_STATCNT(PGetVolumeStatus);
if (!avc) {
code = EINVAL;
}
Name = volName;
do {
- tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK);
+ tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn);
if (tc) {
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_GETVOLUMESTATUS);
RX_AFS_GUNLOCK();
code =
- RXAFS_GetVolumeStatus(tc->id, avc->f.fid.Fid.Volume, &volstat,
+ RXAFS_GetVolumeStatus(rxconn, avc->f.fid.Fid.Volume, &volstat,
&Name, &offLineMsg, &motd);
RX_AFS_GLOCK();
XSTATS_END_TIME;
} else
code = -1;
} while (afs_Analyze
- (tc, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_GETVOLUMESTATUS,
+ (tc, rxconn, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_GETVOLUMESTATUS,
SHARED_LOCK, NULL));
if (code)
char *volName;
char *offLineMsg;
char *motd;
- register struct afs_conn *tc;
- register afs_int32 code = 0;
+ struct afs_conn *tc;
+ afs_int32 code = 0;
struct AFSFetchVolumeStatus volstat;
struct AFSStoreVolumeStatus storeStat;
- register struct volume *tvp;
+ struct volume *tvp;
+ struct rx_connection *rxconn;
XSTATS_DECLS;
AFS_STATCNT(PSetVolumeStatus);
storeStat.Mask |= AFS_SETMAXQUOTA;
}
do {
- tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK);
+ tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn);
if (tc) {
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_SETVOLUMESTATUS);
RX_AFS_GUNLOCK();
code =
- RXAFS_SetVolumeStatus(tc->id, avc->f.fid.Fid.Volume, &storeStat,
+ RXAFS_SetVolumeStatus(rxconn, avc->f.fid.Fid.Volume, &storeStat,
volName, offLineMsg, motd);
RX_AFS_GLOCK();
XSTATS_END_TIME;
} else
code = -1;
} while (afs_Analyze
- (tc, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_SETVOLUMESTATUS,
+ (tc, rxconn, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_SETVOLUMESTATUS,
SHARED_LOCK, NULL));
if (code)
AFS_STATCNT(PFlush);
if (!avc)
return EINVAL;
-#ifdef AFS_BOZONLOCK_ENV
- afs_BozonLock(&avc->pvnLock, avc); /* Since afs_TryToSmush will do a pvn_vptrunc */
-#endif
ObtainWriteLock(&avc->lock, 225);
- afs_ResetVCache(avc, *acred);
+ afs_ResetVCache(avc, *acred, 0);
ReleaseWriteLock(&avc->lock);
-#ifdef AFS_BOZONLOCK_ENV
- afs_BozonUnlock(&avc->pvnLock, avc);
-#endif
return 0;
}
*/
DECL_PIOCTL(PNewStatMount)
{
- register afs_int32 code;
- register struct vcache *tvc;
- register struct dcache *tdc;
+ afs_int32 code;
+ struct vcache *tvc;
+ struct dcache *tdc;
struct VenusFid tfid;
char *bufp;
char *name;
}
tdc = afs_GetDCache(avc, (afs_size_t) 0, areq, &offset, &len, 1);
if (!tdc)
- return ENOENT;
+ return EIO;
Check_AtSys(avc, name, &sysState, areq);
ObtainReadLock(&tdc->lock);
do {
tvc = afs_GetVCache(&tfid, areq, NULL, NULL);
}
if (!tvc) {
- code = ENOENT;
+ code = EIO;
goto out;
}
- if (tvc->mvstat != 1) {
+ if (tvc->mvstat != AFS_MVSTAT_MTPT) {
afs_PutVCache(tvc);
code = EINVAL;
goto out;
}
/*!
+ * A helper function to get the n'th cell which a particular user has tokens
+ * for. This is racy. If new tokens are added whilst we're iterating, then
+ * we may return some cells twice. If tokens expire mid run, then we'll
+ * miss some cells from our output. So, could be better, but that would
+ * require an interface change.
+ */
+
+static struct unixuser *
+getNthCell(afs_int32 uid, afs_int32 iterator) {
+ int i;
+ struct unixuser *tu = NULL;
+
+ i = UHash(uid);
+ ObtainReadLock(&afs_xuser);
+ for (tu = afs_users[i]; tu; tu = tu->next) {
+ if (tu->uid == uid && (tu->states & UHasTokens)) {
+ if (iterator-- == 0)
+ break; /* are we done yet? */
+ }
+ }
+ if (tu) {
+ tu->refCount++;
+ }
+ ReleaseReadLock(&afs_xuser);
+ if (tu) {
+ afs_LockUser(tu, READ_LOCK, 0);
+ }
+
+
+ return tu;
+}
+/*!
* VIOCGETTOK (8) - Get authentication tokens
- *
+ *
* \ingroup pioctl
- *
+ *
* \param[in] ain cellid to return tokens for
* \param[out] aout token
- *
+ *
* \retval EIO
* Error if the afs daemon hasn't started yet
* \retval EDOM
* tokens
* \retval ENOTCONN
* Error if there aren't tokens for this cell
- *
+ *
* \post
* If the input paramater exists, get the token that corresponds to
* the parameter value, if there is no token at this value, get the
DECL_PIOCTL(PGetTokens)
{
- register struct cell *tcell;
- register afs_int32 i;
- register struct unixuser *tu;
+ struct cell *tcell;
+ struct unixuser *tu = NULL;
+ union tokenUnion *token;
afs_int32 iterator = 0;
int newStyle;
+ int cellNum;
int code = E2BIG;
AFS_STATCNT(PGetTokens);
if (afs_pd_getInt(ain, &iterator) != 0)
return EINVAL;
}
- i = UHash(areq->uid);
- ObtainReadLock(&afs_xuser);
- for (tu = afs_users[i]; tu; tu = tu->next) {
- if (newStyle) {
- if (tu->uid == areq->uid && (tu->states & UHasTokens)) {
- if (iterator-- == 0)
- break; /* are we done yet? */
- }
- } else {
- if (tu->uid == areq->uid && afs_IsPrimaryCellNum(tu->cell))
- break;
- }
- }
- if (tu) {
- /*
- * No need to hold a read lock on each user entry
- */
- tu->refCount++;
+ if (newStyle) {
+ tu = getNthCell(areq->uid, iterator);
+ } else {
+ cellNum = afs_GetPrimaryCellNum();
+ if (cellNum)
+ tu = afs_FindUser(areq->uid, cellNum, READ_LOCK);
}
- ReleaseReadLock(&afs_xuser);
-
if (!tu) {
return EDOM;
}
- if (((tu->states & UHasTokens) == 0)
- || (tu->ct.EndTimestamp < osi_Time())) {
+ if (!(tu->states & UHasTokens)
+ || !afs_HasUsableTokens(tu->tokens, osi_Time())) {
tu->states |= (UTokensBad | UNeedsReset);
afs_NotifyUser(tu, UTokensDropped);
afs_PutUser(tu, READ_LOCK);
return ENOTCONN;
}
- iterator = tu->stLen; /* for compat, we try to return 56 byte tix if they fit */
+ token = afs_FindToken(tu->tokens, RX_SECIDX_KAD);
+
+ /* If they don't have an RXKAD token, but do have other tokens,
+ * then sadly there's nothing this interface can do to help them. */
+ if (token == NULL)
+ return ENOTCONN;
+
+ /* for compat, we try to return 56 byte tix if they fit */
+ iterator = token->rxkad.ticketLen;
if (iterator < 56)
iterator = 56; /* # of bytes we're returning */
if (afs_pd_putInt(aout, iterator) != 0)
goto out;
- if (afs_pd_putBytes(aout, tu->stp, tu->stLen) != 0)
+ if (afs_pd_putBytes(aout, token->rxkad.ticket, token->rxkad.ticketLen) != 0)
goto out;
- if (tu->stLen < 56) {
+ if (token->rxkad.ticketLen < 56) {
/* Tokens are always 56 bytes or larger */
- if (afs_pd_skip(aout, iterator - tu->stLen) != 0) {
+ if (afs_pd_skip(aout, iterator - token->rxkad.ticketLen) != 0) {
goto out;
}
}
if (afs_pd_putInt(aout, sizeof(struct ClearToken)) != 0)
goto out;
- if (afs_pd_putBytes(aout, &tu->ct, sizeof(struct ClearToken)) != 0)
+ if (afs_pd_putBytes(aout, &token->rxkad.clearToken,
+ sizeof(struct ClearToken)) != 0)
goto out;
if (newStyle) {
*/
DECL_PIOCTL(PUnlog)
{
- register afs_int32 i;
- register struct unixuser *tu;
+ afs_int32 i;
+ struct unixuser *tu;
AFS_STATCNT(PUnlog);
if (!afs_resourceinit_flag) /* afs daemons haven't started yet */
ObtainWriteLock(&afs_xuser, 227);
for (tu = afs_users[i]; tu; tu = tu->next) {
if (tu->uid == areq->uid) {
- tu->vid = UNDEFVID;
- tu->states &= ~UHasTokens;
- /* security is not having to say you're sorry */
- memset(&tu->ct, 0, sizeof(struct ClearToken));
tu->refCount++;
ReleaseWriteLock(&afs_xuser);
+
+ afs_LockUser(tu, WRITE_LOCK, 366);
+
+ tu->states &= ~UHasTokens;
+ afs_FreeTokens(&tu->tokens);
afs_NotifyUser(tu, UTokensDropped);
/* We have to drop the lock over the call to afs_ResetUserConns,
* since it obtains the afs_xvcache lock. We could also keep
* every user conn that existed when we began this call.
*/
afs_ResetUserConns(tu);
- tu->refCount--;
+ afs_PutUser(tu, WRITE_LOCK);
ObtainWriteLock(&afs_xuser, 228);
#ifdef UKERNEL
/* set the expire times to 0, causes
* afs_GCUserData to remove this entry
*/
- tu->ct.EndTimestamp = 0;
tu->tokenTime = 0;
#endif /* UKERNEL */
}
*/
DECL_PIOCTL(PCheckServers)
{
- register int i;
- register struct server *ts;
+ int i;
+ struct server *ts;
afs_int32 temp;
char *cellName = NULL;
struct cell *cellp;
{
int i;
struct srvAddr *sa;
- struct afs_conn *tc;
+ struct sa_conn_vector *tcv;
struct unixuser *tu;
afs_int32 retValue;
/* all connections in cell 1 working? */
for (i = 0; i < NSERVERS; i++) {
for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) {
- for (tc = sa->conns; tc; tc = tc->next) {
- if (tc->user == tu && (tu->states & UTokensBad))
+ for (tcv = sa->conns; tcv; tcv = tcv->next) {
+ if (tcv->user == tu && (tu->states & UTokensBad))
retValue = EACCES;
}
}
Prefetch(uparmtype apath, struct afs_ioctl *adata, int afollow,
afs_ucred_t *acred)
{
- register char *tp;
- register afs_int32 code;
-#if defined(AFS_SGI61_ENV) || defined(AFS_SUN57_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+ char *tp;
+ afs_int32 code;
+#if defined(AFS_SGI61_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
size_t bufferSize;
#else
u_int bufferSize;
*/
DECL_PIOCTL(PFindVolume)
{
- register struct volume *tvp;
- register struct server *ts;
- register afs_int32 i;
+ struct volume *tvp;
+ struct server *ts;
+ afs_int32 i;
int code = 0;
AFS_STATCNT(PFindVolume);
*/
DECL_PIOCTL(PViceAccess)
{
- register afs_int32 code;
+ afs_int32 code;
afs_int32 temp;
AFS_STATCNT(PViceAccess);
{
afs_int32 results[MAXGCSTATS];
afs_int32 flags;
- register struct dcache * tdc;
+ struct dcache * tdc;
int i, size;
-
+
AFS_STATCNT(PGetCacheSize);
if (afs_pd_remaining(ain) == sizeof(afs_int32)) {
} else {
return EINVAL;
}
-
+
memset(results, 0, sizeof(results));
results[0] = afs_cacheBlocks;
results[1] = afs_blocksUsed;
results[2] = afs_cacheFiles;
-
+
if (1 == flags){
for (i = 0; i < afs_cacheFiles; i++) {
if (afs_indexFlags[i] & IFFree) results[3]++;
*/
DECL_PIOCTL(PRemoveCallBack)
{
- register struct afs_conn *tc;
- register afs_int32 code = 0;
+ struct afs_conn *tc;
+ afs_int32 code = 0;
struct AFSCallBack CallBacks_Array[1];
struct AFSCBFids theFids;
struct AFSCBs theCBs;
+ struct rx_connection *rxconn;
XSTATS_DECLS;
AFS_STATCNT(PRemoveCallBack);
CallBacks_Array[0].CallBackType = CB_DROPPED;
if (avc->callback) {
do {
- tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK);
+ tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn);
if (tc) {
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_GIVEUPCALLBACKS);
RX_AFS_GUNLOCK();
- code = RXAFS_GiveUpCallBacks(tc->id, &theFids, &theCBs);
+ code = RXAFS_GiveUpCallBacks(rxconn, &theFids, &theCBs);
RX_AFS_GLOCK();
XSTATS_END_TIME;
}
/* don't set code on failure since we wouldn't use it */
} while (afs_Analyze
- (tc, code, &avc->f.fid, areq,
+ (tc, rxconn, code, &avc->f.fid, areq,
AFS_STATS_FS_RPCIDX_GIVEUPCALLBACKS, SHARED_LOCK, NULL));
ObtainWriteLock(&afs_xcbhash, 457);
DECL_PIOCTL(PListCells)
{
afs_int32 whichCell;
- register struct cell *tcell = 0;
- register afs_int32 i;
+ struct cell *tcell = 0;
+ afs_int32 i;
int code;
AFS_STATCNT(PListCells);
DECL_PIOCTL(PListAliases)
{
afs_int32 whichAlias;
- register struct cell_alias *tcalias = 0;
+ struct cell_alias *tcalias = 0;
int code;
if (!afs_resourceinit_flag) /* afs daemons haven't started yet */
*/
DECL_PIOCTL(PRemoveMount)
{
- register afs_int32 code;
+ afs_int32 code;
char *bufp;
char *name;
struct sysname_info sysState;
afs_size_t offset, len;
- register struct afs_conn *tc;
- register struct dcache *tdc;
- register struct vcache *tvc;
+ struct afs_conn *tc;
+ struct dcache *tdc;
+ struct vcache *tvc;
struct AFSFetchStatus OutDirStatus;
struct VenusFid tfid;
struct AFSVolSync tsync;
+ struct rx_connection *rxconn;
XSTATS_DECLS;
/* "ain" is the name of the file in this dir to remove */
tdc = afs_GetDCache(avc, (afs_size_t) 0, areq, &offset, &len, 1); /* test for error below */
if (!tdc)
- return ENOENT;
+ return EIO;
Check_AtSys(avc, name, &sysState, areq);
ObtainReadLock(&tdc->lock);
do {
tvc = afs_GetVCache(&tfid, areq, NULL, NULL);
}
if (!tvc) {
- code = ENOENT;
+ code = EIO;
afs_PutDCache(tdc);
goto out;
}
- if (tvc->mvstat != 1) {
+ if (tvc->mvstat != AFS_MVSTAT_MTPT) {
afs_PutDCache(tdc);
afs_PutVCache(tvc);
code = EINVAL;
ObtainWriteLock(&avc->lock, 231);
osi_dnlc_remove(avc, bufp, tvc);
do {
- tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK);
+ tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn);
if (tc) {
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_REMOVEFILE);
RX_AFS_GUNLOCK();
code =
- RXAFS_RemoveFile(tc->id, (struct AFSFid *)&avc->f.fid.Fid, bufp,
+ RXAFS_RemoveFile(rxconn, (struct AFSFid *)&avc->f.fid.Fid, bufp,
&OutDirStatus, &tsync);
RX_AFS_GLOCK();
XSTATS_END_TIME;
} else
code = -1;
} while (afs_Analyze
- (tc, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_REMOVEFILE,
+ (tc, rxconn, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_REMOVEFILE,
SHARED_LOCK, NULL));
if (code) {
*/
DECL_PIOCTL(PGetCellStatus)
{
- register struct cell *tcell;
+ struct cell *tcell;
char *cellName;
afs_int32 temp;
*/
DECL_PIOCTL(PSetCellStatus)
{
- register struct cell *tcell;
+ struct cell *tcell;
char *cellName;
afs_int32 flags0, flags1;
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)
{
- register afs_int32 i;
- register struct dcache *tdc;
- register struct vcache *tvc;
- register struct volume *tv;
- afs_int32 cell, volume;
+ afs_int32 i;
+ struct dcache *tdc;
+ struct vcache *tvc;
+ struct volume *tv;
+ 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);
}
#ifdef AFS_DARWIN80_ENV
if (tvc->f.states & CDeadVnode) {
- if (!(tvc->f.states & CBulkFetching)) {
- ReleaseReadLock(&afs_xvcache);
- afs_osi_Sleep(&tvc->f.states);
- goto loop;
- }
+ ReleaseReadLock(&afs_xvcache);
+ afs_osi_Sleep(&tvc->f.states);
+ goto loop;
}
vp = AFSTOV(tvc);
if (vnode_get(vp))
AFS_GLOCK();
continue;
}
- if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
- AFS_GUNLOCK();
- vnode_recycle(AFSTOV(tvc));
- AFS_GLOCK();
- }
#else
AFS_FAST_HOLD(tvc);
#endif
ReleaseReadLock(&afs_xvcache);
-#ifdef AFS_BOZONLOCK_ENV
- afs_BozonLock(&tvc->pvnLock, tvc); /* Since afs_TryToSmush will do a pvn_vptrunc */
-#endif
ObtainWriteLock(&tvc->lock, 232);
-
- ObtainWriteLock(&afs_xcbhash, 458);
- afs_DequeueCallback(tvc);
- tvc->f.states &= ~(CStatd | CDirty);
- ReleaseWriteLock(&afs_xcbhash);
- if (tvc->f.fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))
- osi_dnlc_purgedp(tvc);
- afs_TryToSmush(tvc, *acred, 1);
+ afs_ResetVCache(tvc, acred, 1);
ReleaseWriteLock(&tvc->lock);
-#ifdef AFS_BOZONLOCK_ENV
- afs_BozonUnlock(&tvc->pvnLock, tvc);
-#endif
#ifdef AFS_DARWIN80_ENV
vnode_put(AFSTOV(tvc));
#endif
AFS_FAST_RELE(tvc);
}
}
+ }
ReleaseReadLock(&afs_xvcache);
for (i = 0; i < afs_cacheFiles; i++) {
if (!(afs_indexFlags[i] & IFEverUsed))
continue; /* never had any data */
- tdc = afs_GetDSlot(i, NULL);
+ tdc = afs_GetValidDSlot(i);
+ if (!tdc) {
+ continue;
+ }
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 (!(afs_indexFlags[i] & IFDataMod)) {
+ 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
* into it. Better to skip flushing such a file, it will be
* brought back immediately on the next write anyway.
- *
+ *
+ * Skip if already freed.
+ *
* If we *must* flush, then this code has to be rearranged
* to call afs_storeAllSegments() first */
afs_FlushDCache(tdc);
ReleaseWriteLock(&afs_xdcache);
ObtainReadLock(&afs_xvolume);
- for (i = 0; i < NVOLS; i++) {
+ for (i = all ? 0 : VHash(volume); 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;
+ if (!all)
+ goto last;
}
}
}
+ last:
ReleaseReadLock(&afs_xvolume);
/* 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
*/
DECL_PIOCTL(PGetVnodeXStatus)
{
- register afs_int32 code;
+ afs_int32 code;
struct vcxstat stat;
afs_int32 mode, i;
DECL_PIOCTL(PGetVnodeXStatus2)
{
- register afs_int32 code;
+ afs_int32 code;
struct vcxstat2 stat;
afs_int32 mode;
char outname[MAXSYSNAME];
afs_int32 setsysname;
int foundname = 0;
- register struct afs_exporter *exporter;
- register struct unixuser *au;
- register afs_int32 pag, error;
+ struct afs_exporter *exporter;
+ struct unixuser *au;
+ afs_int32 pag, error;
int t, count, num = 0, allpags = 0;
char **sysnamelist;
struct afs_pdata validate;
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;
}
{
int i;
struct volume *j;
- register int k;
+ int k;
if (vlonly) {
afs_int32 *p;
- p = (afs_int32 *) afs_osi_Alloc(sizeof(afs_int32) * (s + 1));
+ p = afs_osi_Alloc(sizeof(afs_int32) * (s + 1));
+ osi_Assert(p != NULL);
p[0] = s;
memcpy(p + 1, l, s * sizeof(afs_int32));
afs_TraverseCells(&ReSortCells_cb, p);
afs_uint32 temp = sp->host.s_addr;
srvr =
afs_GetServer(&temp, 1, 0, (vlonly ? AFS_VLPORT : AFS_FSPORT),
- WRITE_LOCK, (afsUUID *) 0, 0);
+ WRITE_LOCK, (afsUUID *) 0, 0, NULL);
srvr->addr->sa_iprank = sp->rank + afs_randomMod15();
afs_PutServer(srvr, WRITE_LOCK);
}
ssp = (struct setspref *)ainPtr;
if (ainSize < (sizeof(struct setspref)
- + sizeof(struct spref) * ssp->num_servers-1))
+ + sizeof(struct spref) * (ssp->num_servers-1)))
return EINVAL;
afs_setsprefs(&(ssp->servers[0]), ssp->num_servers,
return 0;
}
-/*
+/*
* VIOC_SETPREFS33 (42) - Set server ranks (deprecated)
*
* \param[in] ain the server preferences to be set
return 0;
}
-/*
+/*
* VIOC_GETSPREFS (43) - Get server ranks
*
* \ingroup pioctl
afs_int32 export, newint = 0;
afs_int32 type, changestate, handleValue, convmode, pwsync, smounts;
afs_int32 rempags = 0, pagcb = 0;
- register struct afs_exporter *exporter;
+ struct afs_exporter *exporter;
AFS_STATCNT(PExportAfs);
if (afs_pd_getInt(ain, &handleValue) != 0)
return afs_pd_putBytes(aout, &cm_initParams,
sizeof(struct cm_initparams));
- return 0;
}
#ifdef AFS_SGI65_ENV
} else if (!code) {
EXP_RELE(outexporter);
}
- if (!code)
+ if (!code)
*com = (*com) | comp;
return code;
}
#endif /* AFS_NEED_CLIENTCONTEXT */
-/*!
+/*!
* VIOC_GETCPREFS (50) - Get client interface
*
* \ingroup pioctl
*/
DECL_PIOCTL(PFlushMount)
{
- register afs_int32 code;
- register struct vcache *tvc;
- register struct dcache *tdc;
+ afs_int32 code;
+ struct vcache *tvc;
+ struct dcache *tdc;
struct VenusFid tfid;
char *bufp;
char *mount;
}
tdc = afs_GetDCache(avc, (afs_size_t) 0, areq, &offset, &len, 1);
if (!tdc)
- return ENOENT;
+ return EIO;
Check_AtSys(avc, mount, &sysState, areq);
ObtainReadLock(&tdc->lock);
do {
tvc = afs_GetVCache(&tfid, areq, NULL, NULL);
}
if (!tvc) {
- code = ENOENT;
+ code = EIO;
goto out;
}
- if (tvc->mvstat != 1) {
+ if (tvc->mvstat != AFS_MVSTAT_MTPT) {
afs_PutVCache(tvc);
code = EINVAL;
goto out;
}
-#ifdef AFS_BOZONLOCK_ENV
- afs_BozonLock(&tvc->pvnLock, tvc); /* Since afs_TryToSmush will do a pvn_vptrunc */
-#endif
ObtainWriteLock(&tvc->lock, 649);
ObtainWriteLock(&afs_xcbhash, 650);
afs_DequeueCallback(tvc);
tvc->linkData = NULL;
}
ReleaseWriteLock(&tvc->lock);
-#ifdef AFS_BOZONLOCK_ENV
- afs_BozonUnlock(&tvc->pvnLock, tvc);
-#endif
afs_PutVCache(tvc);
out:
if (sysState.allocked)
DECL_PIOCTL(PPrefetchFromTape)
{
- register afs_int32 code, code1;
- afs_int32 bytes, outval;
+ afs_int32 code;
+ afs_int32 outval;
struct afs_conn *tc;
struct rx_call *tcall;
struct AFSVolSync tsync;
struct VenusFid tfid;
struct AFSFid *Fid;
struct vcache *tvc;
+ struct rx_connection *rxconn;
- AFS_STATCNT(PSetAcl);
+ AFS_STATCNT(PPrefetchFromTape);
if (!avc)
return EINVAL;
ICL_TYPE_FID, &tfid, ICL_TYPE_FID, &tvc->f.fid);
do {
- tc = afs_Conn(&tvc->f.fid, areq, SHARED_LOCK);
+ tc = afs_Conn(&tvc->f.fid, areq, SHARED_LOCK, &rxconn);
if (tc) {
RX_AFS_GUNLOCK();
- tcall = rx_NewCall(tc->id);
+ tcall = rx_NewCall(rxconn);
code =
StartRXAFS_FetchData(tcall, (struct AFSFid *)&tvc->f.fid.Fid, 0,
0);
if (!code) {
- bytes = rx_Read(tcall, (char *)&outval, sizeof(afs_int32));
+ rx_Read(tcall, (char *)&outval, sizeof(afs_int32));
code =
EndRXAFS_FetchData(tcall, &OutStatus, &CallBack, &tsync);
}
- code1 = rx_EndCall(tcall, code);
+ code = rx_EndCall(tcall, code);
RX_AFS_GLOCK();
} else
code = -1;
} while (afs_Analyze
- (tc, code, &tvc->f.fid, areq, AFS_STATS_FS_RPCIDX_RESIDENCYRPCS,
+ (tc, rxconn, code, &tvc->f.fid, areq, AFS_STATS_FS_RPCIDX_RESIDENCYRPCS,
SHARED_LOCK, NULL));
/* This call is done only to have the callback things handled correctly */
afs_FetchStatus(tvc, &tfid, areq, &OutStatus);
DECL_PIOCTL(PFsCmd)
{
- register afs_int32 code;
+ afs_int32 code;
struct afs_conn *tc;
struct vcache *tvc;
struct FsCmdInputs *Inputs;
struct FsCmdOutputs *Outputs;
struct VenusFid tfid;
struct AFSFid *Fid;
+ struct rx_connection *rxconn;
if (!avc)
return EINVAL;
if (Inputs->command) {
do {
- tc = afs_Conn(&tvc->f.fid, areq, SHARED_LOCK);
+ tc = afs_Conn(&tvc->f.fid, areq, SHARED_LOCK, &rxconn);
if (tc) {
RX_AFS_GUNLOCK();
code =
- RXAFS_FsCmd(tc->id, Fid, Inputs,
- (struct FsCmdOutputs *)aout);
+ RXAFS_FsCmd(rxconn, Fid, Inputs, Outputs);
RX_AFS_GLOCK();
} else
code = -1;
} while (afs_Analyze
- (tc, code, &tvc->f.fid, areq,
+ (tc, rxconn, code, &tvc->f.fid, areq,
AFS_STATS_FS_RPCIDX_RESIDENCYRPCS, SHARED_LOCK, NULL));
/* This call is done to have the callback things handled correctly */
afs_FetchStatus(tvc, &tfid, areq, &Outputs->status);
return 0;
}
-#if defined(AFS_CACHE_BYPASS)
+#if defined(AFS_CACHE_BYPASS) && defined(AFS_LINUX24_ENV)
DECL_PIOCTL(PSetCachingThreshold)
{
if (setting == 0 && getting == 0)
return EINVAL;
-
- /*
+
+ /*
* If setting, set first, and return the value now in effect
*/
if (setting) {
if (!afs_osi_suser(*acred))
return EPERM;
cache_bypass_threshold = threshold;
- afs_warn("Cache Bypass Threshold set to: %d\n", 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 (getting)
return afs_pd_putInt(aout, cache_bypass_threshold);
afs_int32 i, j;
struct unixuser *tu;
struct srvAddr **addrs;
+ struct rx_connection *rxconn;
/*AFS_STATCNT(PCallBackAddr); */
if (!afs_resourceinit_flag) /* afs deamons havn't started yet */
}
addrs = afs_osi_Alloc(srvAddrCount * sizeof(*addrs));
+ osi_Assert(addrs != NULL);
j = 0;
for (i = 0; i < NSERVERS; i++) {
for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) {
/* get a connection, even if host is down; bumps conn ref count */
tu = afs_GetUser(areq->uid, ts->cell->cellNum, SHARED_LOCK);
tc = afs_ConnBySA(sa, ts->cell->fsport, ts->cell->cellNum, tu,
- 1 /*force */ , 1 /*create */ , SHARED_LOCK);
+ 1 /*force */ , 1 /*create */ , SHARED_LOCK, 0, &rxconn);
afs_PutUser(tu, SHARED_LOCK);
if (!tc)
continue;
if ((sa->sa_flags & SRVADDR_ISDOWN) || afs_HaveCallBacksFrom(ts)) {
if (sa->sa_flags & SRVADDR_ISDOWN) {
- rx_SetConnDeadTime(tc->id, 3);
+ rx_SetConnDeadTime(rxconn, 3);
}
#ifdef RX_ENABLE_LOCKS
AFS_GUNLOCK();
#endif /* RX_ENABLE_LOCKS */
- code = RXAFS_CallBackRxConnAddr(tc->id, &addr);
+ code = RXAFS_CallBackRxConnAddr(rxconn, &addr);
#ifdef RX_ENABLE_LOCKS
AFS_GLOCK();
#endif /* RX_ENABLE_LOCKS */
}
- afs_PutConn(tc, SHARED_LOCK); /* done with it now */
+ afs_PutConn(tc, rxconn, SHARED_LOCK); /* done with it now */
} /* Outer loop over addrs */
#endif /* UKERNEL */
return 0;
return afs_pd_putInt(aout, mode);
}
+#define MAX_PIOCTL_TOKENS 10
+
+DECL_PIOCTL(PSetTokens2)
+{
+ int code =0;
+ int i, cellNum, primaryFlag;
+ XDR xdrs;
+ struct unixuser *tu;
+ struct vrequest *treq = NULL;
+ struct ktc_setTokenData tokenSet;
+ struct ktc_tokenUnion decodedToken;
+
+ memset(&tokenSet, 0, sizeof(tokenSet));
+
+ AFS_STATCNT(PSetTokens2);
+ if (!afs_resourceinit_flag)
+ return EIO;
+
+ afs_pd_xdrStart(ain, &xdrs, XDR_DECODE);
+
+ if (!xdr_ktc_setTokenData(&xdrs, &tokenSet)) {
+ afs_pd_xdrEnd(ain, &xdrs);
+ return EINVAL;
+ }
+
+ afs_pd_xdrEnd(ain, &xdrs);
+
+ /* We limit each PAG to 10 tokens to prevent a malicous (or runaway)
+ * process from using up the whole of the kernel memory by allocating
+ * tokens.
+ */
+ if (tokenSet.tokens.tokens_len > MAX_PIOCTL_TOKENS) {
+ xdr_free((xdrproc_t) xdr_ktc_setTokenData, &tokenSet);
+ return E2BIG;
+ }
+
+ code = _settok_tokenCell(tokenSet.cell, &cellNum, &primaryFlag);
+ if (code) {
+ xdr_free((xdrproc_t) xdr_ktc_setTokenData, &tokenSet);
+ return code;
+ }
+
+ 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
+ code = afs_CreateReq(&treq, *acred);
+ if (code) {
+ xdr_free((xdrproc_t) xdr_ktc_setTokenData, &tokenSet);
+ return code;
+ }
+ areq = treq;
+ }
+ }
+
+ tu = afs_GetUser(areq->uid, cellNum, WRITE_LOCK);
+ /* Free any tokens that we've already got */
+ afs_FreeTokens(&tu->tokens);
+
+ /* Iterate across the set of tokens we've received, and stuff them
+ * into this user's tokenJar
+ */
+ for (i=0; i < tokenSet.tokens.tokens_len; i++) {
+ xdrmem_create(&xdrs,
+ tokenSet.tokens.tokens_val[i].token_opaque_val,
+ tokenSet.tokens.tokens_val[i].token_opaque_len,
+ XDR_DECODE);
+
+ memset(&decodedToken, 0, sizeof(decodedToken));
+ if (!xdr_ktc_tokenUnion(&xdrs, &decodedToken)) {
+ xdr_destroy(&xdrs);
+ code = EINVAL;
+ goto out;
+ }
+
+ xdr_destroy(&xdrs);
+
+ afs_AddTokenFromPioctl(&tu->tokens, &decodedToken);
+ /* This is untidy - the old token interface supported passing
+ * the primaryFlag as part of the token interface. Current
+ * OpenAFS userland never sets this, but it's specified as being
+ * part of the XG interface, so we should probably still support
+ * it. Rather than add it to our AddToken interface, just handle
+ * it here.
+ */
+ if (decodedToken.at_type == AFSTOKEN_UNION_KAD) {
+ if (decodedToken.ktc_tokenUnion_u.at_kad.rk_primary_flag)
+ primaryFlag = 1;
+ }
+
+ /* XXX - We should think more about destruction here. It's likely that
+ * there is key material in what we're about to throw away, which
+ * we really should zero out before giving back to the allocator */
+ xdr_free((xdrproc_t) xdr_ktc_tokenUnion, &decodedToken);
+ }
+
+ tu->states |= UHasTokens;
+ tu->states &= ~UTokensBad;
+ afs_SetPrimary(tu, primaryFlag);
+ tu->tokenTime = osi_Time();
+
+ xdr_free((xdrproc_t) xdr_ktc_setTokenData, &tokenSet);
+
+out:
+ afs_ResetUserConns(tu);
+ afs_PutUser(tu, WRITE_LOCK);
+ afs_DestroyReq(treq);
+
+ return code;
+}
+
+DECL_PIOCTL(PGetTokens2)
+{
+ struct cell *cell = NULL;
+ struct unixuser *tu = NULL;
+ afs_int32 iterator;
+ char *cellName = NULL;
+ afs_int32 cellNum;
+ int code = 0;
+ time_t now;
+ XDR xdrs;
+ struct ktc_setTokenData tokenSet;
+
+ AFS_STATCNT(PGetTokens);
+ if (!afs_resourceinit_flag)
+ return EIO;
+
+ memset(&tokenSet, 0, sizeof(tokenSet));
+
+ /* No input data - return tokens for primary cell */
+ /* 4 octets of data is 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 */
+ if (afs_pd_getInt(ain, &iterator) != 0)
+ return EINVAL;
+ tu = getNthCell(areq->uid, iterator);
+ } else {
+ if (afs_pd_remaining(ain) > 0) {
+ if (afs_pd_getStringPtr(ain, &cellName) != 0)
+ return EINVAL;
+ } else {
+ cellName = NULL;
+ }
+ code = _settok_tokenCell(cellName, &cellNum, NULL);
+ if (code)
+ return code;
+ tu = afs_FindUser(areq->uid, cellNum, READ_LOCK);
+ }
+ if (tu == NULL)
+ return EDOM;
+
+ now = osi_Time();
+
+ if (!(tu->states & UHasTokens)
+ || !afs_HasValidTokens(tu->tokens, now)) {
+ tu->states |= (UTokensBad | UNeedsReset);
+ afs_PutUser(tu, READ_LOCK);
+ return ENOTCONN;
+ }
+
+ code = afs_ExtractTokensForPioctl(tu->tokens, now, &tokenSet);
+ if (code)
+ goto out;
+
+ cell = afs_GetCell(tu->cell, READ_LOCK);
+ tokenSet.cell = cell->cellName;
+ afs_pd_xdrStart(aout, &xdrs, XDR_ENCODE);
+ if (!xdr_ktc_setTokenData(&xdrs, &tokenSet)) {
+ code = E2BIG;
+ goto out;
+ }
+ afs_pd_xdrEnd(aout, &xdrs);
+
+out:
+ tokenSet.cell = NULL;
+
+ if (tu)
+ afs_PutUser(tu, READ_LOCK);
+ if (cell)
+ afs_PutCell(cell, READ_LOCK);
+ xdr_free((xdrproc_t)xdr_ktc_setTokenData, &tokenSet);
+
+ return code;
+};
+
DECL_PIOCTL(PNFSNukeCreds)
{
afs_uint32 addr;
- register afs_int32 i;
- register struct unixuser *tu;
+ afs_int32 i;
+ struct unixuser *tu;
AFS_STATCNT(PUnlog);
if (!afs_resourceinit_flag) /* afs daemons haven't started yet */
for (i = 0; i < NUSERS; i++) {
for (tu = afs_users[i]; tu; tu = tu->next) {
if (tu->exporter && EXP_CHECKHOST(tu->exporter, addr)) {
- tu->vid = UNDEFVID;
- tu->states &= ~UHasTokens;
- /* security is not having to say you're sorry */
- memset(&tu->ct, 0, sizeof(struct ClearToken));
tu->refCount++;
ReleaseWriteLock(&afs_xuser);
+
+ afs_LockUser(tu, WRITE_LOCK, 367);
+
+ tu->states &= ~UHasTokens;
+ afs_FreeTokens(&tu->tokens);
afs_ResetUserConns(tu);
- tu->refCount--;
+ afs_PutUser(tu, WRITE_LOCK);
ObtainWriteLock(&afs_xuser, 228);
#ifdef UKERNEL
/* set the expire times to 0, causes
* afs_GCUserData to remove this entry
*/
- tu->ct.EndTimestamp = 0;
tu->tokenTime = 0;
#endif /* UKERNEL */
}