DECL_PIOCTL(PSetCellStatus);
DECL_PIOCTL(PFlushVolumeData);
DECL_PIOCTL(PGetVnodeXStatus);
+DECL_PIOCTL(PGetVnodeXStatus2);
DECL_PIOCTL(PSetSysName);
DECL_PIOCTL(PSetSPrefs);
DECL_PIOCTL(PSetSPrefs33);
PPrefetchFromTape, /* 66 -- MR-AFS: prefetch file from tape */
PResidencyCmd, /* 67 -- MR-AFS: generic commnd interface */
PBogus, /* 68 -- arla: fetch stats */
+ PGetVnodeXStatus2, /* 69 - get caller access and some vcache status */
};
static int (*(CpioctlSw[])) () = {
#define PSetClientContext 99 /* Special pioctl to setup caller's creds */
int afs_nobody = NFS_NOBODY;
+#if (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)) || defined(AFS_HPUX_64BIT_ENV) || defined(AFS_SUN57_64BIT_ENV) || (defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64)) || defined(NEED_IOCTL32)
static void
afs_ioctl32_to_afs_ioctl(const struct afs_ioctl32 *src, struct afs_ioctl *dst)
{
dst->in_size = src->in_size;
dst->out_size = src->out_size;
}
+#endif
/*
* If you need to change copyin_afs_ioctl(), you may also need to change
}
#endif /* defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64) */
-#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV) && !defined(AFS_AMD64_LINUX20_ENV)
+#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
struct afs_ioctl32 dst32;
-#ifdef AFS_SPARC64_LINUX24_ENV
+#ifdef AFS_SPARC64_LINUX26_ENV
+ if (test_thread_flag(TIF_32BIT))
+#elif AFS_SPARC64_LINUX24_ENV
if (current->thread.flags & SPARC_FLAG_32BIT)
#elif defined(AFS_SPARC64_LINUX20_ENV)
if (current->tss.flags & SPARC_FLAG_32BIT)
+
+#elif defined(AFS_AMD64_LINUX26_ENV)
+ if (test_thread_flag(TIF_IA32))
#elif defined(AFS_AMD64_LINUX20_ENV)
if (current->thread.flags & THREAD_IA32)
+
+#elif defined(AFS_PPC64_LINUX26_ENV)
+ if (current->thread_info->flags & _TIF_32BIT)
#elif defined(AFS_PPC64_LINUX20_ENV)
-#ifdef AFS_PPC64_LINUX26_ENV
- if (current->thread_info->flags & _TIF_32BIT)
-#else /*Linux 2.6*/
- if (current->thread.flags & PPC_FLAG_32BIT)
-#endif
+ if (current->thread.flags & PPC_FLAG_32BIT)
+
+#elif defined(AFS_S390X_LINUX26_ENV)
+ if (test_thread_flag(TIF_31BIT))
#elif defined(AFS_S390X_LINUX20_ENV)
if (current->thread.flags & S390_FLAG_31BIT)
+
#else
-#error Not done for this linux type
+#error pioctl32 not done for this linux
#endif
{
AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
register int ioctlDone = 0, code = 0;
AFS_STATCNT(afs_xioctl);
-#if defined(AFS_XBSD_ENV)
+#if defined(AFS_DARWIN_ENV)
+ if ((code = fdgetf(p, uap->fd, &fd)))
+ return code;
+#elif defined(AFS_XBSD_ENV)
fdp = p->p_fd;
if ((u_int) uap->fd >= fdp->fd_nfiles
|| (fd = fdp->fd_ofiles[uap->fd]) == NULL)
return EBADF;
if ((fd->f_flag & (FREAD | FWRITE)) == 0)
return EBADF;
-#elif defined(AFS_DARWIN_ENV)
- if ((code = fdgetf(p, uap->fd, &fd)))
- return code;
#elif defined(AFS_LINUX22_ENV)
ua.com = com;
ua.arg = arg;
#endif
#endif /* AFS_LINUX22_ENV */
if (tvc && IsAfsVnode(AFSTOV(tvc))) {
-#ifdef AFS_DEC_ENV
- tvc = VTOAFS(afs_gntovn((struct gnode *)tvc));
- if (!tvc) { /* shouldn't happen with held gnodes */
- u.u_error = ENOENT;
- return;
- }
-#endif
/* This is an AFS vnode */
if (((uap->com >> 8) & 0xff) == 'V') {
register struct afs_ioctl *datap;
AFS_GLOCK();
datap =
(struct afs_ioctl *)osi_AllocSmallSpace(AFS_SMALLOCSIZ);
- AFS_COPYIN((char *)uap->arg, (caddr_t) datap,
- sizeof(struct afs_ioctl), code);
+ code=copyin_afs_ioctl((char *)uap->arg, datap);
if (code) {
osi_FreeSmallSpace(datap);
AFS_GUNLOCK();
int follow;
{
struct afs_ioctl data;
- struct AFS_UCRED *tmpcred, *foreigncreds = NULL;
- register afs_int32 code = 0;
- struct vnode *vp;
-#ifdef AFS_DEC_ENV
- struct vnode *gp;
+#ifdef AFS_NEED_CLIENTCONTEXT
+ struct AFS_UCRED *tmpcred;
#endif
+ struct AFS_UCRED *foreigncreds = NULL;
+ register afs_int32 code = 0;
+ struct vnode *vp = NULL;
#ifdef AFS_AIX41_ENV
struct ucred *credp = crref(); /* don't free until done! */
#endif
foreigncreds ? foreigncreds : credp);
#else
#ifdef AFS_LINUX22_ENV
- code = gop_lookupname(path, AFS_UIOUSER, follow, NULL, &dp);
+ code = gop_lookupname(path, AFS_UIOUSER, follow, &dp);
if (!code)
vp = (struct vnode *)dp->d_inode;
#else
- code = gop_lookupname(path, AFS_UIOUSER, follow, NULL, &vp);
+ code = gop_lookupname(path, AFS_UIOUSER, follow, &vp);
#endif /* AFS_LINUX22_ENV */
#endif /* AFS_AIX41_ENV */
AFS_GLOCK();
/* now make the call if we were passed no file, or were passed an AFS file */
if (!vp || IsAfsVnode(vp)) {
-#if defined(AFS_DEC_ENV)
- /* Ultrix 4.0: can't get vcache entry unless we've got an AFS gnode.
- * So, we must test in this part of the code. Also, must arrange to
- * GRELE the original gnode pointer when we're done, since in Ultrix 4.0,
- * we hold gnodes, whose references hold our vcache entries.
- */
- if (vp) {
- gp = vp; /* remember for "put" */
- vp = (struct vnode *)afs_gntovn(vp); /* get vcache from gp */
- } else
- gp = NULL;
-#elif defined(AFS_SUN5_ENV)
+#if defined(AFS_SUN5_ENV)
code = afs_HandlePioctl(vp, com, &data, follow, &credp);
#elif defined(AFS_AIX41_ENV)
{
#else
code = EINVAL; /* not in /afs */
#endif
-#ifdef AFS_DEC_ENV
- if (vp) {
- GRELE(vp);
- vp = NULL;
- }
-#endif
}
rescred:
if (inSize > MAXPIOCTLTOKENLEN || inSize < 0 || ablob->out_size < 0)
return E2BIG;
+ /* Note that we use osi_Alloc for large allocs and osi_AllocLargeSpace for small ones */
if (inSize > AFS_LRALLOCSIZ) {
- inData = osi_AllocLargeSpace(inSize+1);
+ inData = osi_Alloc(inSize + 1);
} else {
- inData = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
+ inData = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
}
if (!inData)
- return ENOMEM;
+ return ENOMEM;
if (inSize > 0) {
AFS_COPYIN(ablob->in, inData, inSize, code);
inData[inSize] = '\0';
} else
code = 0;
if (code) {
- if (inSize > AFS_LRALLOCSIZ) {
- osi_Free(inData, inSize+1);
- } else {
- osi_FreeLargeSpace(inData);
- }
- afs_PutFakeStat(&fakestate);
- return code;
+ if (inSize > AFS_LRALLOCSIZ) {
+ osi_Free(inData, inSize + 1);
+ } else {
+ osi_FreeLargeSpace(inData);
+ }
+ afs_PutFakeStat(&fakestate);
+ return code;
}
- if (function == 8 && device == 'V') { /* PGetTokens */
- outSizeMax = MAXPIOCTLTOKENLEN;
- outData = osi_Alloc(outSizeMax);
+ if (function == 8 && device == 'V') { /* PGetTokens */
+ outSizeMax = MAXPIOCTLTOKENLEN;
+ outData = osi_Alloc(outSizeMax);
} else {
- outSizeMax = AFS_LRALLOCSIZ;
- outData = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
+ outSizeMax = AFS_LRALLOCSIZ;
+ outData = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
}
if (!outData) {
- if (inSize > AFS_LRALLOCSIZ) {
- osi_Free(inData, inSize+1);
- } else {
- osi_FreeLargeSpace(inData);
- }
- return ENOMEM;
+ if (inSize > AFS_LRALLOCSIZ) {
+ osi_Free(inData, inSize + 1);
+ } else {
+ osi_FreeLargeSpace(inData);
+ }
+ afs_PutFakeStat(&fakestate);
+ return ENOMEM;
}
outSize = 0;
code =
(*pioctlSw[function]) (avc, function, &treq, inData, outData, inSize,
&outSize, acred);
if (inSize > AFS_LRALLOCSIZ) {
- osi_Free(inData, inSize+1);
+ osi_Free(inData, inSize + 1);
} else {
- osi_FreeLargeSpace(inData);
+ osi_FreeLargeSpace(inData);
}
if (code == 0 && ablob->out_size > 0) {
- if (outSize > ablob->out_size) {
- code = E2BIG; /* data wont fit in user buffer */
- } else if (outSize) {
- AFS_COPYOUT(outData, ablob->out, outSize, code);
- }
+ if (outSize > ablob->out_size) {
+ code = E2BIG; /* data wont fit in user buffer */
+ } else if (outSize) {
+ AFS_COPYOUT(outData, ablob->out, outSize, code);
+ }
}
if (outSizeMax > AFS_LRALLOCSIZ) {
- osi_Free(outData, outSizeMax);
+ osi_Free(outData, outSizeMax);
} else {
- osi_FreeLargeSpace(outData);
+ osi_FreeLargeSpace(outData);
}
afs_PutFakeStat(&fakestate);
return afs_CheckCode(code, &treq, 41);
char *motd = afs_osi_Alloc(256);
register struct conn *tc;
register afs_int32 code = 0;
- struct VolumeStatus volstat;
+ struct AFSFetchVolumeStatus volstat;
register char *cp;
char *Name, *OfflineMsg, *MOTD;
XSTATS_DECLS;
AFS_STATCNT(PFlush);
if (!avc)
return EINVAL;
-#if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV)
+#ifdef AFS_BOZONLOCK_ENV
afs_BozonLock(&avc->pvnLock, avc); /* Since afs_TryToSmush will do a pvn_vptrunc */
#endif
ObtainWriteLock(&avc->lock, 225);
/* now find the disk cache entries */
afs_TryToSmush(avc, *acred, 1);
osi_dnlc_purgedp(avc);
- afs_symhint_inval(avc);
if (avc->linkData && !(avc->states & CCore)) {
afs_osi_Free(avc->linkData, strlen(avc->linkData) + 1);
avc->linkData = NULL;
}
ReleaseWriteLock(&avc->lock);
-#if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV)
+#ifdef AFS_BOZONLOCK_ENV
afs_BozonUnlock(&avc->pvnLock, avc);
#endif
return 0;
* the vcaches associated with the volume.
*/
ObtainReadLock(&afs_xvcache);
- for (i = 0; i < VCSIZE; i++) {
- for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
+ i = VCHashV(&avc->fid);
+ for (tvc = afs_vhashT[i]; tvc; tvc = tvc->vhnext) {
if (tvc->fid.Fid.Volume == volume && tvc->fid.Cell == cell) {
-#if defined(AFS_SGI_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
+#if defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
VN_HOLD(AFSTOV(tvc));
#else
#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
osi_vnhold(tvc, 0);
#else
- VREFCOUNT_INC(tvc);
+ VREFCOUNT_INC(tvc); /* AIX, apparently */
#endif
#endif
ReleaseReadLock(&afs_xvcache);
-#if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV)
+#ifdef AFS_BOZONLOCK_ENV
afs_BozonLock(&tvc->pvnLock, tvc); /* Since afs_TryToSmush will do a pvn_vptrunc */
#endif
ObtainWriteLock(&tvc->lock, 232);
osi_dnlc_purgedp(tvc);
afs_TryToSmush(tvc, *acred, 1);
ReleaseWriteLock(&tvc->lock);
-#if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV)
+#ifdef AFS_BOZONLOCK_ENV
afs_BozonUnlock(&tvc->pvnLock, tvc);
#endif
ObtainReadLock(&afs_xvcache);
AFS_FAST_RELE(tvc);
}
}
- }
ReleaseReadLock(&afs_xvcache);
mode = PRSFS_READ;
if (!afs_AccessOK(avc, mode, areq, CHECK_MODE_BITS))
return EACCES;
+
+ memset(&stat, 0, sizeof(struct vcxstat));
stat.fid = avc->fid;
hset32(stat.DataVersion, hgetlo(avc->m.DataVersion));
stat.lock = avc->lock;
}
+DECL_PIOCTL(PGetVnodeXStatus2)
+{
+ register afs_int32 code;
+ struct vcxstat2 stat;
+ afs_int32 mode;
+
+ if (!avc)
+ return EINVAL;
+ code = afs_VerifyVCache(avc, areq);
+ if (code)
+ return code;
+ if (vType(avc) == VDIR)
+ mode = PRSFS_LOOKUP;
+ else
+ mode = PRSFS_READ;
+ if (!afs_AccessOK(avc, mode, areq, CHECK_MODE_BITS))
+ return EACCES;
+
+ memset(&stat, 0, sizeof(struct vcxstat2));
+
+ stat.cbExpires = avc->cbExpires;
+ stat.anyAccess = avc->anyAccess;
+ stat.mvstat = avc->mvstat;
+ stat.callerAccess = afs_GetAccessBits(avc, ~0, areq);
+
+ memcpy(aout, (char *)&stat, sizeof(struct vcxstat2));
+ *aoutSize = sizeof(struct vcxstat2);
+ return 0;
+}
+
/* We require root for local sysname changes, but not for remote */
/* (since we don't really believe remote uids anyway) */
/* outname[] shouldn't really be needed- this is left as an excercise */
/* for the reader. */
DECL_PIOCTL(PSetSysName)
{
- char *cp, *cp2, inname[MAXSYSNAME], outname[MAXSYSNAME];
+ char *cp, *cp2 = NULL, inname[MAXSYSNAME], outname[MAXSYSNAME];
int setsysname, foundname = 0;
register struct afs_exporter *exporter;
register struct unixuser *au;
register afs_int32 pag, error;
int t, count, num = 0;
- char **sysnamelist[MAXSYSNAME];
+ char **sysnamelist[MAXNUMSYSNAMES];
AFS_STATCNT(PSetSysName);
if (!afs_globalVFS) {
return error;
}
} else {
- foundname = num;
- strcpy(outname, (*sysnamelist)[0]);
+ foundname = num;
+ strcpy(outname, (*sysnamelist)[0]);
}
afs_PutUser(au, READ_LOCK);
} else {
uid = afs_nobody; /* NFS_NOBODY == -2 */
}
newcred = crget();
+#if defined(AFS_LINUX26_ENV)
+ newcred->cr_group_info = groups_alloc(0);
+#endif
#ifdef AFS_AIX41_ENV
setuerror(0);
#endif
newcred->cr_groups[i] = NOGROUP;
#endif
#endif
-#if !defined(AFS_OSF_ENV) && !defined(AFS_DEC_ENV)
+#if !defined(AFS_OSF_ENV)
afs_nfsclient_init(); /* before looking for exporter, ensure one exists */
#endif
if (!(exporter = exporter_find(exporter_type))) {
code = EINVAL;
goto out;
}
-#if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV)
+#ifdef AFS_BOZONLOCK_ENV
afs_BozonLock(&tvc->pvnLock, tvc); /* Since afs_TryToSmush will do a pvn_vptrunc */
#endif
ObtainWriteLock(&tvc->lock, 649);
/* now find the disk cache entries */
afs_TryToSmush(tvc, *acred, 1);
osi_dnlc_purgedp(tvc);
- afs_symhint_inval(tvc);
if (tvc->linkData && !(tvc->states & CCore)) {
afs_osi_Free(tvc->linkData, strlen(tvc->linkData) + 1);
tvc->linkData = NULL;
}
ReleaseWriteLock(&tvc->lock);
-#if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV)
+#ifdef AFS_BOZONLOCK_ENV
afs_BozonUnlock(&tvc->pvnLock, tvc);
#endif
afs_PutVCache(tvc);
struct unixuser *tu;
struct srvAddr **addrs;
- /*AFS_STATCNT(PCallBackAddr);*/
- if ( !afs_resourceinit_flag ) /* afs deamons havn't started yet */
- return EIO; /* Inappropriate ioctl for device */
+ /*AFS_STATCNT(PCallBackAddr); */
+ if (!afs_resourceinit_flag) /* afs deamons havn't started yet */
+ return EIO; /* Inappropriate ioctl for device */
if (!afs_osi_suser(acred))
return EACCES;
- if ( ainSize < sizeof(afs_int32) )
+ if (ainSize < sizeof(afs_int32))
return EINVAL;
memcpy(&addr, ain, sizeof(afs_int32));
ObtainReadLock(&afs_xinterface);
- for ( i=0; (unsigned short)i < afs_cb_interface.numberOfInterfaces; i++) {
- if (afs_cb_interface.addr_in[i] == addr) break;
+ for (i = 0; (unsigned short)i < afs_cb_interface.numberOfInterfaces; i++) {
+ if (afs_cb_interface.addr_in[i] == addr)
+ break;
}
ReleaseWriteLock(&afs_xinterface);
if (afs_cb_interface.addr_in[i] != addr)
return EINVAL;
- ObtainReadLock(&afs_xserver); /* Necessary? */
+ ObtainReadLock(&afs_xserver); /* Necessary? */
ObtainReadLock(&afs_xsrvAddr);
srvAddrCount = 0;
- for (i=0;i<NSERVERS;i++) {
- for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) {
- srvAddrCount++;
- }
+ for (i = 0; i < NSERVERS; i++) {
+ for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) {
+ srvAddrCount++;
+ }
}
addrs = afs_osi_Alloc(srvAddrCount * sizeof(*addrs));
j = 0;
- for (i=0;i<NSERVERS;i++) {
- for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) {
- if (j >= srvAddrCount) break;
- addrs[j++] = sa;
- }
+ for (i = 0; i < NSERVERS; i++) {
+ for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) {
+ if (j >= srvAddrCount)
+ break;
+ addrs[j++] = sa;
+ }
}
ReleaseReadLock(&afs_xsrvAddr);
ReleaseReadLock(&afs_xserver);
- for (i=0; i<j; i++) {
- sa = addrs[i];
- ts = sa->server;
- if (!ts)
- continue;
-
- /* vlserver has no callback conn */
- if (sa->sa_portal == AFS_VLPORT) {
- continue;
- }
-
- if (!ts->cell) /* not really an active server, anyway, it must */
- continue; /* have just been added by setsprefs */
-
- /* 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);
- afs_PutUser(tu, SHARED_LOCK);
- if (!tc)
+ for (i = 0; i < j; i++) {
+ sa = addrs[i];
+ ts = sa->server;
+ if (!ts)
continue;
- if ((sa->sa_flags & SRVADDR_ISDOWN) || afs_HaveCallBacksFrom(ts)) {
- if (sa->sa_flags & SRVADDR_ISDOWN) {
- rx_SetConnDeadTime(tc->id, 3);
- }
+ /* vlserver has no callback conn */
+ if (sa->sa_portal == AFS_VLPORT) {
+ continue;
+ }
+
+ if (!ts->cell) /* not really an active server, anyway, it must */
+ continue; /* have just been added by setsprefs */
+ /* 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);
+ 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);
+ }
#ifdef RX_ENABLE_LOCKS
- AFS_GUNLOCK();
+ AFS_GUNLOCK();
#endif /* RX_ENABLE_LOCKS */
code = RXAFS_CallBackRxConnAddr(tc->id, &addr);
#ifdef RX_ENABLE_LOCKS
- AFS_GLOCK();
+ AFS_GLOCK();
#endif /* RX_ENABLE_LOCKS */
}
- afs_PutConn(tc, SHARED_LOCK); /* done with it now */
- } /* Outer loop over addrs */
+ afs_PutConn(tc, SHARED_LOCK); /* done with it now */
+ } /* Outer loop over addrs */
#endif /* UKERNEL */
return 0;
}